Skip to content

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:

OptionBest for
A Node.js process next to MagentoServers 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 WorkerHosting 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.

  1. Build the renderer together with the theme, from the Magento root folder:

    bash
    bin/magento lynx:static:deploy OOCS_LynxVue --ssr

    For the React edition, use OOCS_LynxReact.

  2. Start the renderer from the theme's folder:

    bash
    cd app/design/frontend/OOCS/LynxVue/lynx
    npm run ssr

    It listens on port 13714 by default. Set LYNX_SSR_PORT to use another port, and LYNX_SSR_CLUSTER=1 to run one worker per CPU core on busy stores.

  3. Keep it running with your usual process manager, such as systemd, PM2 or Supervisor, so it starts again after a restart or a crash.

  4. 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.

  1. Build the Worker from the theme's folder:

    bash
    cd app/design/frontend/OOCS/LynxVue/lynx
    npm run build:ssr:worker
  2. Sign in to Cloudflare once. This opens a browser window:

    bash
    npx wrangler login

    On 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:

    bash
    CLOUDFLARE_API_TOKEN=<token> CLOUDFLARE_ACCOUNT_ID=<account id> npm run deploy:ssr:worker
  3. Deploy:

    bash
    npm run deploy:ssr:worker

    The first time, Cloudflare asks you to pick a workers.dev subdomain. The command prints the Worker's address, such as https://lynx-ssr.<your-subdomain>.workers.dev. The React edition deploys as lynx-ssr-react.

  4. 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.log as Lynx 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:

SettingWhat to enter
EnabledYes
Renderer URLhttp://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.
RoutesThe 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 GroupsWhich 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.