Skip to main content

CSR or SSR

A template route in your app has to fetch a template, render it, style it and fill in the page head. Where those jobs run, in the browser or on your server, decides what search engines and link previews see. The example on this page is the Blog post template, rendering the post AI 101 at /blog/ai-101.

What a template route has to do​

For /blog/ai-101, your route does four jobs:

  1. Fetch. It gets the composition for that URL, the Blog post template with AI 101's content bound in.
  2. Render. It turns the composition into your components.
  3. Style. It gets the template's styles into the first paint. The styles authors set in the Design panel aren't in your stylesheet. The SDK generates them from the composition.
  4. Describe. It puts the template's title and meta tags in the page head. The SDK doesn't write to the head. Your route does, from the seo values the fetch returns.

The two fetch functions and the one renderer​

The Studio SDK gives you two ways to fetch and one component to render with.

APIWhere it runsReturns
useCompositionData(query, options?)In the browser only. It's a React hook, so it runs inside a client component.{ specOptions, isLoading, error, refetchSpec, refetchData }
sdk.fetchCompositionData(query, options?)On the server, or anywhere outside React. It's a method on the object studioSdk.init returns.The spec options object itself

Both give you the same object, StudioComponentSpecOptions. The hook wraps it as specOptions, and fetchCompositionData returns it directly.

ComponentWhere it runsWhat it does
<StudioComponent specOptions={specOptions} />In the browser, and on the server. It's a client component that still renders to HTML on the server.Renders either fetch result the same way. It reads the mode from the URL and picks editing, the Open in Studio button or a plain render.

Who does each job on the client and on the server​

JobOn the clientOn the server
FetchuseCompositionData reads the query string from the browser's address itself.You call fetchCompositionData and pass the request's query string as searchQuery.
Render<StudioComponent /> renders in the browser.<StudioComponent /> renders to HTML on the server, and the browser hydrates it.
StyleYou don't add anything. The style helper is only for HTML built on the server.The HTML is built before any browser script runs, so you add the styles to the head with getSSRStyleTags.
DescribeThe seo values arrive with the fetch, after the page loads. They aren't in the HTML that crawlers and social previews read.You write the seo values into the head with getCompositionMetadata and renderMetadataToHtml.

Two lanes for the Blog post template at /blog/ai-101, labelled with the four jobs. In the client lane, the browser loads the app, useCompositionData fetches, StudioComponent renders in the browser, the styles apply with nothing added, and the head is set after the page loads. In the server lane, fetchCompositionData fetches on the server, StudioComponent renders to HTML, the style tag and the meta tags are added to the head, and the browser hydrates the HTML.

When you need server rendering​

Render on the server when any of these is true for a template:

  • Search engines must index its content from the first HTML response. On the client, that HTML has no template content yet.
  • Social previews must show its title, description and Open Graph image. Social networks and many crawlers don't run JavaScript, so they never see tags set in the browser.
  • The first paint must show the template. On the client, the first paint is your loading state, because useCompositionData starts in its loading state.

A client-rendered template can still set its title and meta tags after it loads, from specOptions.seo. Server rendering is what puts them in the first HTML.

What doesn't change between the two​

<StudioCanvas /> renders only in the browser. It renders nothing on the server and on the first client render, so it needs no special handling on either path.

Your section preview route and its Canvas URL, /canvas, stay the same whichever path your template routes use. See Mount the section preview route.

Choose a render path​

Both pages build on the catch-all route from Wire template preview routes.

Report a problem with this page