Appearance
Server-side Rendering
Server-side rendering (SSR) builds each page on the server, so search engines and social networks receive a complete page instead of an empty one that is filled in by JavaScript. Shoppers also see the page sooner on their first visit. After that first page, the store continues as a single-page app.
With SSR on, the home page of a test store scores 93 for performance in Lighthouse's mobile mode. See Lighthouse scores.
SSR is optional. Without it, Lynx pages are drawn in the browser, which search engines such as Google can still index. Turn it on when search traffic matters most to you.
No headless browser needed
Many single-page storefronts rely on prerendering services such as Rendertron or Prerender.io, which run a headless Chrome to load each page and take a snapshot. They are slow, use a lot of memory and often fall behind the live store.
Lynx does not need any of that. Its pages are rendered directly by the same Vue or React code that runs in the browser, inside a small JavaScript process. You only need one of these:
| Option | Best for |
|---|---|
| A Node.js process next to Magento | Servers where you can run a long-running Node.js process, such as a VPS, a dedicated server or a container setup. This is the fastest option. |
| A Cloudflare Worker | Hosting that does not allow Node.js processes, such as many shared or managed Magento hosts. Nothing extra runs on your server. |
Magento does not care which one you use: it only needs the address of the renderer. You can switch later by changing one setting.
How it works with the cache
Rendering only happens when a page is not already in Magento's full page cache. Once a page has been rendered, the finished HTML is cached like any other page, so most visitors are served straight from the cache.
If the renderer is slow or unavailable, Lynx waits no longer than the Timeout you set and then lets the browser draw the page instead. Shoppers never see an error because of SSR.
Cart, checkout and account pages are never rendered on the server. They are personal and not cached, and search engines do not index them.
Option 1: a Node.js process
Requires Node.js 22 or newer on the same server as Magento, or in the same private network.
Build the renderer together with the theme, from the Magento root folder:
bashbin/magento lynx:static:deploy OOCS_LynxVue --ssrFor the React edition, use
OOCS_LynxReact.Start the renderer from the theme's folder:
bashcd app/design/frontend/OOCS/LynxVue/lynx npm run ssrIt listens on port
13714by default. SetLYNX_SSR_PORTto use another port, andLYNX_SSR_CLUSTER=1to run one worker per CPU core on busy stores.Keep it running with your usual process manager, such as systemd, PM2 or Supervisor, so it starts again after a restart or a crash.
In the admin, set Renderer URL to
http://127.0.0.1:13714. See Turning it on.
WARNING
The renderer has no login of its own. Keep its port closed to the internet, for example by listening on 127.0.0.1 with LYNX_SSR_HOST=127.0.0.1 or with a firewall rule.
Option 2: a Cloudflare Worker
Cloudflare Workers run your renderer on Cloudflare's network, so your hosting only needs to run Magento. This is the way to use SSR when your server cannot run Node.js.
Use a paid Workers plan
Rendering a page takes more processing time than the free Workers plan allows for each request. Subscribe to the Workers Paid plan on your Cloudflare account. It costs a few dollars a month and covers millions of requests.
The steps below run on any computer with Node.js 22 or newer, such as your developer's machine or your deployment pipeline, not necessarily on the Magento server.
Build the Worker from the theme's folder:
bashcd app/design/frontend/OOCS/LynxVue/lynx npm run build:ssr:workerSign in to Cloudflare once. This opens a browser window:
bashnpx wrangler loginOn a machine without a browser, create an API token in Cloudflare under My Profile › API Tokens with the Edit Cloudflare Workers template, and pass it with your account ID instead:
bashCLOUDFLARE_API_TOKEN=<token> CLOUDFLARE_ACCOUNT_ID=<account id> npm run deploy:ssr:workerDeploy:
bashnpm run deploy:ssr:workerThe first time, Cloudflare asks you to pick a
workers.devsubdomain. The command prints the Worker's address, such ashttps://lynx-ssr.<your-subdomain>.workers.dev. The React edition deploys aslynx-ssr-react.In the admin, set Renderer URL to that address.
Each render now travels from your server to Cloudflare and back, so it takes a little longer than with a Node.js process next to Magento. The default Timeout is usually enough. If pages often fall back to being drawn in the browser, raise it. Those fallbacks are logged in
var/log/system.logasLynx SSR: renderer did not answer.
Redeploy the Worker each time you update Lynx or rebuild the theme, so the renderer and the store stay on the same version. To restrict who can call the Worker, put Cloudflare Access or a WAF rule in front of it.
Turning it on
Go to Stores › Configuration › Lynx › SSR:
| Setting | What to enter |
|---|---|
| Enabled | Yes |
| Renderer URL | http://127.0.0.1:13714 for Node.js, or the Worker's address. Use Test Connection to check it. |
| Timeout (ms) | How long a render may take before the browser takes over. The default is 2000. It is only a ceiling: a page that renders sooner is returned at once. Raise it only if var/log/system.log often shows Lynx SSR: renderer did not answer. |
| Routes | The pages to render, one per line. The default list covers the home page (cms_index_index), categories (catalog_category_view) and products (catalog_product_view). Add cms_page_view for CMS pages. A * at the end matches by prefix, so catalog_* covers all catalog pages. |
| Customer Groups | Which visitors receive rendered pages. Keep NOT LOGGED IN selected, since search engines are never signed in. |
Save, then flush the cache so pages are rendered on their next visit.