Skip to main content

Server Side Rendering

What is SSR Rendering?

Server-Side Rendering (SSR) is a technique used to improve the load performance and SEO of modern web applications. Most web apps today are built as Single Page Applications (SPAs), where all frontend code—JavaScript, HTML, and CSS—is bundled together and served in a single payload. While SPAs offer fluid, app-like user experiences, they often suffer from longer initial load times and poor SEO performance due to the time it takes for the JavaScript to download, parse, and render content.

SSR addresses these limitations by rendering the application on the server first. Instead of sending a blank HTML shell and loading everything on the client, SSR sends pre-rendered HTML from the server to the browser. This allows users to see meaningful content faster and improves search engine crawlability. Once the page is loaded, the client-side JavaScript takes over (a process called “hydration”) to make the application interactive.

Helium and SSR

Helium supports Server-Side Rendering out of the box. While it’s not strictly required, we strongly recommend using SSR to optimize performance and improve user experience—especially for content-heavy pages or SEO-critical routes.

Here’s a simple example of how to implement SSR in your Helium app using the <FeaturedContent /> component:

import React from 'react';
import { useTranslation } from 'react-i18next';
import {
FeaturedContent,
ContentTileStandardLayout,
FeaturedContentContentItem
} from '@thoughtindustries/featured-content';
import {
hydrateContent,
useCatalogQuery,
useAddResourceToQueueMutation
} from '@thoughtindustries/content';

export { Page };

function Page() {
const { i18n } = useTranslation();
const [addResourceToQueue] = useAddResourceToQueueMutation();
const handleAddedToQueue = (item: FeaturedContentContentItem): Promise<boolean | void> =>
item.displayCourse
? addResourceToQueue({ variables: { resourceId: item.displayCourse } }).then()
: Promise.resolve(undefined);

const { data, loading, error } = useCatalogQuery();

let content;

if (data) {
content = data.CatalogQuery.contentItems.map((item, index) => {
const hydratedItem = hydrateContent(i18n, item);
const { authors, description, href, ...restItemProps } = hydratedItem;
const transformedItem = {
...restItemProps,
authors,
shortDescription: description && `${description.substring(0, 75)} ...`,
linkUrl: href
};
return <ContentTileStandardLayout.Item key={`item-${index}`} {...transformedItem} />;
});
}

return (
<div className="px-4">
<FeaturedContent>
<ContentTileStandardLayout
desktopColumnCount={4}
onAddedToQueue={handleAddedToQueue}
>
{content}
</ContentTileStandardLayout>
</FeaturedContent>
</div>
);
}