Skip to content

Components

Core components are the foundational building blocks of our web pages, developed to render flawless, performant HTML. These components ensure structural integrity and compliance with best practices without incorporating visual styling. They are modifiable and reusable, designed to nest within one another, enabling the creation of more complex and functional components when needed.

In web development, there are many ways to render elements. However, within Terra, we aim to standardize our approach, ensuring all team members follow a consistent structure and methodology. This consistency enhances maintainability, readability, and overall quality across all our projects.

Images

Typically, when adding images, we might use a simple <img src="asset.jpg" /> tag, which works well for many cases. However, to achieve the perfect image rendering, additional attributes are essential for performance and visual stability.

1 - Firstly, we always include the image’s width and height directly in the HTML. This enhances performance and prevents layout shifts during lazy loading. To further stabilize the layout, we set a dynamic aspect-ratio, unless the image meets one of the following conditions:

  • The aspect ratio is already defined in CSS.
  • The image has a fixed height in CSS.
  • The image is positioned absolutely, so it doesn’t impact the surrounding layout.

2 - We also use the srcset attribute to avoid loading images that are too large on mobile devices. For this, both WordPress and Sanity have functions that help manage responsive images.

When adding an image, the only thing we need to keep in mind is its expected width and specify it in the sizes attribute. For example, if the image spans the full width of the screen, its size would be 100vw.

The sizes attribute can include media queries, and its values can be specified in any unit, as long as it’s clear which unit is being used. For example:

  • If an image takes up 50% of the screen but shifts to 100% on screens 580px wide or smaller, sizes would be something like sizes="(max-width: 580px) 100vw, 50vw".
  • If it’s an icon that always measures 100px, it can be written as sizes="100px".

This ensures that images are appropriately sized for each device, optimizing performance and layout consistency.

Preferred Image Formats

To maximize web performance, we prioritize image file types in the following order:

  • WebP for the smallest file sizes and better compression.
  • JPG if WebP is not supported or available.
  • PNG only if other formats are not suitable.

Examples

Below are examples for WordPress, Astro & Sanity, and Vue. Each example follows the Terra standard and is adaptable to various projects, promoting modularity and reusability across the team.

Wordpress:

<?php
$image_tag_args = array(
'image' => $image,
'sizes' => '(max-width: 580px) 95vw, (max-width: 1024px) 50vw, 33vw',
'class' => 'c--media-a',
'isLazy' => false,
'showAspectRatio' => true,
'decodingAsync' => true,
'fetchPriority' => false,
'addFigcaption' => false,
);
generate_image_tag($image_tag_args)
?>

Astro For further reference, check @terrahq/astro-core - Image documentation.

<Asset
payload={{
type: "Image",
url: "https://example.com/image.jpg",
sizes: "(max-width: 600px) 480px, 800px",
alt: "Example image",
customClass: "image-class",
}}
/>

Vue For further reference, check @terrahq/vue-core - Image documentation.

<template>
<Asset :payload="imagePayload" />
</template>
<script setup>
const imagePayload = {
type: 'Image',
url: 'https://example.com/image.png',
alt: 'Example Image',
customClass: 'image-class',
attributes: {
width: 800,
height: 600,
},
};
</script>

Resulting HTML Output

<img alt="Image alt" src="imageSrc.webp" srcset="imageSrc.webp 2000w, imageSrc.webp?w=1300 1300w, imageSrc.webp?w=1024 1024w, imageSrc.webp?w=810 810w, imageSrc.webp?w=580 580w" width="2000" height="500" sizes="(max-width: 580px) 95vw, (max-width: 1024px) 50vw, 33vw" class="c--media-a g--lazy-01" style="aspect-ratio: 2000 / 500;" decoding="async" fetchpriority="auto">

Video

For videos, we typically use Boostify to ensure they don’t load immediately when the page loads. This way, videos only load if the user scrolls to them (for autoplay videos) or clicks the play button (for videos without autoplay). This approach optimizes performance by reducing initial page load times and conserving resources, as videos are only loaded when actually needed.

But we can’t always use Boostify. Sometimes we need to embed the video using the HTML <video> tag, either because it’s the background of a hero section or for other reasons.

Boostify

A Boostify video setup only requires a <div> element; when the video needs to load, the <video> element is dynamically created within that div. The setup looks like this:

<div class="c--video-a js--boostify-player" data-video-src="video.mp4"></div>

In this setup, data-video-src holds the video file source, and the video will only load when necessary, contributing to improved page performance.

To use Boostify, you’ll need to import the Boostify package and include some JavaScript code, like this:

document.querySelectorAll('.js--boostify-player').forEach(element => {
bstf.videoPlayer({
url: {
mp4: getAttribute('data-video-src'),
},
attributes: {
class: "c--video-a__media",
loop: false,
muted: false,
controls: true,
autoplay: true,
},
appendTo: element,
});
})

This code renders as:

<div class="c--video-a js--boostify-player" data-video-src="video.mp4">
<video class="c--video-a__media" controls autoplay playsinline="true">
<source src="video.mp4" type="video/mp4">
</video>
</div>

Astro For further reference, check @terrahq/astro-core - Video documentation.

<Asset
payload={{
type: "Video",
video_type: 'file', //file example
video_file: '/asset/video/placeholder.mp4',
hasPosterImg: true,
poster_url: 'https://example.com/image.jpg'
customClass: 'video-class',
isBoostify: true,
}}
/>

Vue For further reference, check @terrahq/vue-core - Video documentation.

<template>
<Asset :payload="videoPayload" />
</template>
<script setup>
const videoPayload = {
type: 'Video',
video_type: 'url', //embed example
video_url: 'https://www.youtube.com/watch?v=example',
customClass: 'video-class',
isBoostify: true, //boostify enabled
};
</script>

Video tag

When we embed a video using the <video> tag, we usually want it to autoplay. To ensure this works properly across all browsers, we need to make sure to add the muted and playsinline attributes.

Here’s an example of a video with autoplay enabled:

<div class="c--video-a">
<video class="c--video-a" autoplay loop playsinline muted>
<source src="video.mp4" type="video/mp4">
</video>
</div>