You have to enable SSR for an app before you can configure islands architecture.
Note
Opt-in to SSR
SSR is activated on a per-route basis. To enable SSR for a route, set bootstrap.ssr to true in lwr.config.json. Configure this property for every page that you want to render on the server-side.
When a route with bootstrap.ssr is requested, LWR uses the LWC renderComponent() function to SSR every root component on that page, regardless of whether the page is generated at runtime or pre-built using generateStaticSite.
LWR automatically passes root component attributes from a template as public properties during SSR. For example, the following code prompts LWR to pass the public property { limit: '10' } to my/root.
my-app/src/content/page.html
1<section>2<!-- "limit" is a template attribute -->3 <my-root limit="10"></my-root>4</section>
SSR Detection
To determine where component code is running, use a script to check the import.meta.env.SSR flag. If code runs on the server-side, the flag is true. If it runs on the client-side, the flag is falsy.
You can use this flag to control where your code runs. For example, this code uses an if-else statement that lets you pivot the runtime environment on the SSR flag.
1export default class App extends LightningElement{2 connectedCallback(){3 if(import.meta.env.SSR){4 // run code on the server5}else{6 // run code on the client7}8}9}
Load Data During SSR
To fetch server-side data for components that rely on external data and resources, use LWR’s getServerData hook. getServerData is only available for LWR on Node.js-only sites. During SSR, LWR calls getServerData() for every root component. Then, the props returned by the hook get passed to the root component as public properties during SSR and on the client.
Data in markup is serialized into the page document as HTML. LWR adds each markup.link returned by getServerData() to the <head> section of the page document.
1export default class BookDetails extends LightningElement{2 // These public properties are bound to the "props" returned by getServerData() below3 @api data?: Book;4 @api bookId?: string;5}67export async function getServerData(context: SsrRequestContext): Promise<SsrDataResponse>{8 // This is called to fetch data before the root component is SSRed9 const bookId = context.params.bookId; // The "bookId" path param is declared in lwr.config.json10 const response = await fetch(`https://www.googleapis.com/books/v1/volumes/${bookId}`);11 const data = await response.json();12 return{13 props:{data, bookId}, // Return public properties for the BookDetails component14 cache:{ttl: '60s'}, // Cache the page for 1 minute15 markup:{16 links:[17{18 // The thumbnail for the book is important, so the page will preload the image19 href: data.volumeInfo.imageLinks.thumbnail,20 as: 'image',21 rel: 'preload',22 fetchpriority: 'high',23},24],25},26};27}
Time-to-Live
getServerData() can return a time-to-live (TTL) for a page in PageDataResponse.cache.ttl. To prevent your data from becoming stale, LWR uses ttl to set the max-age of the Cache-control header on the page. LWR uses the shortest TTL from all sources to set max-age.
getServerData() Considerations
In LWR, the SSR process runs in a secure sandbox. The sandbox supports globalThis.fetch, which lets you use fetch in getServerData() hooks as if the module executes in a browser.
Even within getServerData() context, your code still has to be portable.
If getServerData() throws an error, the page fails to render and the server returns an HTTP 500 error for the page request. To prevent this, address any errors thrown while fetching data and return default values from getServerData.
The getServerData() hook can choose to merge the properties from SsrRequestContext.props into its return object, or it can ignore/discard them.
The author of getServerData() is responsible for validating the params and query from SsrRequestContext before using them.
The same props returned by getServerData() are passed to the component during server rendering and client hydration.
Next Steps
Want to implement SSR with more granular control over how specific components on a page get rendered? Take a look at Understanding Islands to learn more.
Developer Preview Feature
Feature is available as a developer preview. Feature is not generally available unless or until Salesforce announces its general availability in documentation or in press releases or public statements. All commands, parameters, and other features are subject to change or deprecation at any time, with or without notice. Do not implement functionality developed with these commands or tools.