question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`onBeforeRender` in `.page.ts` in SPA/Client Routing Mode causes server-side render

See original GitHub issue

I changed my default server rendering code, _default.page.server.tsx (see below) to return an empty HTML document, and for the client to simply call ReactDOM.render on load. This SPA mode helped me avoid a rabbit hole of bugs with Vite’s SSR system ssrModuleLoader with some particular packages that I was importing.

However, I wanted to add some pageContext on the frontend to change the layout of the PageShell that I’m using. This is my page:

import React from "react";
import { VisualizePage } from "../features/visualization/components/VisualizePage";

export { Page };

function Page() {
  return <VisualizePage />;
}

export function onBeforeRender() {
  return {
    pageContext: {
      pageProps: {
        noPadding: true,
      }
    }
  }
}

Unfortunately, this led to the Vite SSR errors listed below, and it seemed Vite was running its module analysis on frontend React dependencies on the server side. This was perplexing to me, because my default server renderer does not render any react components. I have a hunch that somehow vite-plugin-ssr is interpreting that because I have that function there, it should replace my default server code with some code that renders the components server side and passes data to the client. But I’m not sure; I really don’t know enough about the project internals so I’d really appreciate any guidance you can provide.

Expected behavior: do not do a server-side render and only call onBeforeRender on the client.

When I hit reload in my browser or access the page for the first time, it displays a 500 Internal Server Error message. But if I make any change to the visualize.page.tsx file, like adding or removing spaces/newlines, and then saving, that causes a hot module reload, which causes the components to render in the client without a problem. This was confusing for me for a bit as I though I had somehow fixed it by tweaking the file, but the issue remains.

Let me know if I can provide more information. Thanks for this great library!

Errors
import { isObject } from 'datalib/src/util';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at nodeRequire (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:183:15)
    at ssrImport (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:94:14)
    at eval (/models/shelf/spec/index.ts:1:37)
10:51:23 PM [vite] Error when evaluating SSR module /models/shelf/index.ts:
/home/alex/c2/loqu4/node_modules/.pnpm/compassql@0.21.2_vega@5.21.0/node_modules/compassql/build/src/query/encoding.js:1
import { isObject } from 'datalib/src/util';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at nodeRequire (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:183:15)
    at ssrImport (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:94:14)
    at eval (/models/shelf/spec/index.ts:1:37)
10:51:23 PM [vite] Error when evaluating SSR module /selectors/shelf.ts:
/home/alex/c2/loqu4/node_modules/.pnpm/compassql@0.21.2_vega@5.21.0/node_modules/compassql/build/src/query/encoding.js:1
import { isObject } from 'datalib/src/util';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at nodeRequire (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:183:15)
    at ssrImport (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:94:14)
    at eval (/models/shelf/spec/index.ts:1:37)
10:51:23 PM [vite] Error when evaluating SSR module /selectors/index.ts:
/home/alex/c2/loqu4/node_modules/.pnpm/compassql@0.21.2_vega@5.21.0/node_modules/compassql/build/src/query/encoding.js:1
import { isObject } from 'datalib/src/util';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at nodeRequire (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:183:15)
    at ssrImport (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:94:14)
    at eval (/models/shelf/spec/index.ts:1:37)
10:51:23 PM [vite] Error when evaluating SSR module /features/visualization/components/MainView.tsx:
/home/alex/c2/loqu4/node_modules/.pnpm/compassql@0.21.2_vega@5.21.0/node_modules/compassql/build/src/query/encoding.js:1
import { isObject } from 'datalib/src/util';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at nodeRequire (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:183:15)
    at ssrImport (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:94:14)
    at eval (/models/shelf/spec/index.ts:1:37)
10:51:23 PM [vite] Error when evaluating SSR module /features/visualization/components/VisualizePage.tsx:
/home/alex/c2/loqu4/node_modules/.pnpm/compassql@0.21.2_vega@5.21.0/node_modules/compassql/build/src/query/encoding.js:1
import { isObject } from 'datalib/src/util';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at nodeRequire (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:183:15)
    at ssrImport (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:94:14)
    at eval (/models/shelf/spec/index.ts:1:37)
10:51:23 PM [vite] Error when evaluating SSR module /pages/visualize.page.tsx:
/home/alex/c2/loqu4/node_modules/.pnpm/compassql@0.21.2_vega@5.21.0/node_modules/compassql/build/src/query/encoding.js:1
import { isObject } from 'datalib/src/util';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at nodeRequire (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:183:15)
    at ssrImport (/home/alex/c2/loqu4/node_modules/.pnpm/vite@2.6.7/node_modules/vite/src/node/ssr/ssrModuleLoader.ts:94:14)
    at eval (/models/shelf/spec/index.ts:1:37)

_default.page.server.tsx
import { escapeInject, dangerouslySkipEscape } from "vite-plugin-ssr";
import type { PageContext } from "./types";
import type { PageContextBuiltIn } from "vite-plugin-ssr";

export const passToClient = ["pageProps", "urlPathname"];
import { makeGoogleFontsURL } from "@/utils/fonts";

function render(pageContext: PageContextBuiltIn & PageContext) {
  const { documentProps } = pageContext;
  const title = (documentProps && documentProps.title) || "mytitle";
  const desc =
    (documentProps && documentProps.description) ||
    "mydesc";

  const documentHtml = escapeInject`<!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="preconnect" href="https://fonts.gstatic.com" />
        <link
          href="${makeGoogleFontsURL(["Inter"])}"
          rel="stylesheet"
        />
        <meta name="description" content="${desc}" />
        <title>${title}</title>
      </head>
      <body>
        <div id="page-view"></div>
      </body>
    </html>`;

  return {
    documentHtml,
    pageContext: {},
  };
}

export { render };

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:22 (14 by maintainers)

github_iconTop GitHub Comments

2reactions
brilloutcommented, Nov 14, 2021

You’re right, after some thoughts, I consider this a vite-plugin-ssr design flaw. I’ll fix this ASAP.

The solution I’ve in mind so far is to allow you to define Page and onBeforeRender() in .page.client.ts, which means that they will be only loaded in the browser and never in Node.js. (This introduces breaking changes so I’m going to thoroughly think it through.)

1reaction
brilloutcommented, Jan 4, 2022

👍 Let me know if you have questions.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Verify That the JS Storefront is Running in SSR Mode
You have enabled SSR mode in your build manifest and would like to confirm if a page is rendered on the server rather...
Read more >
Client-side Routing without hitting the server · Issue #95 - GitHub
Some people want to be able to navigate between pages without hitting the Node.js SSR server. I'm opening a ticket for dicussing this....
Read more >
onBeforeRender() hook (.page.server.js) - vite-plugin-ssr
The onBeforeRender() hook is usually used together with passToClient to fetch data, see Guides > Data Fetching. Since .page.server.js is only loaded in...
Read more >
Server-Side Rendering Optimization - Spartacus Documentation
Server -Side Rendering optimization allows you to fine tune your SSR setup, ... defaults to Client-Side Rendering (CSR); Pages are served in SSR...
Read more >
Server Rendering with React and React Router - ui.dev
This is the opposite of what happens with regular client-side rendering which just spits back a blank HTML document with a JavaScript bundle ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found