Skip to content

Tanstack Start prerender error #5939

@hehehai

Description

@hehehai

Which project does this relate to?

Start

Describe the bug

repo: https://github.com/hehehai/tiny-svg
site: https://tiny-svg.actnow.dev/

locale dev: success
locale build: error message (prerender)

vite config

import contentCollections from "@content-collections/vite";
import tailwindcss from "@tailwindcss/vite";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import viteReact from "@vitejs/plugin-react";
import { Locales } from "intlayer";
import { nitro } from "nitro/vite";
import { defineConfig } from "vite";
import { intlayer, intlayerMiddleware } from "vite-intlayer";
import { VitePWA } from "vite-plugin-pwa";
import tsconfigPaths from "vite-tsconfig-paths";

// PWA runtime caching patterns
const GOOGLE_FONTS_PATTERN = /^https:\/\/fonts\.googleapis\.com\/.*/i;
const GSTATIC_FONTS_PATTERN = /^https:\/\/fonts\.gstatic\.com\/.*/i;

export default defineConfig(({ mode }) => ({
  plugins: [
    contentCollections(),
    intlayer(),
    intlayerMiddleware(),
    tsconfigPaths(),
    tanstackStart({
      sitemap: {
        host: process.env.VERCEL_URL
          ? `https://${process.env.VERCEL_URL}`
          : "http://localhost:3001",
      },
      prerender: {
        // Only enable static pre-rendering in production builds
        enabled: mode === "production",

        // Extract and prerender links found in HTML
        crawlLinks: true,

        // Filter which routes to prerender
        // Only prerender about and blog pages in production
        filter: ({ path }) => {
          // Prerender about page for all locales
          if (path.includes("/about")) {
            return true;
          }

          // Prerender blog list and detail pages for all locales
          if (path.includes("/blog")) {
            return true;
          }

          // Don't prerender other pages (like /optimize which has dynamic functionality)
          return false;
        },
        failOnError: false,
      },
      pages: [
        ...[
          Locales.ENGLISH,
          Locales.CHINESE,
          Locales.KOREAN,
          Locales.GERMAN,
        ].map((locale) => ({
          path: `/${locale}/blog`,
          prerender: { enabled: true },
        })),
      ],
    }),
    nitro(),
    viteReact({
      babel: {
        plugins: ["babel-plugin-react-compiler"],
      },
    }),
    tailwindcss(),
    ...VitePWA({
      registerType: "prompt", // User-controlled updates
      includeAssets: ["*.png", "*.svg", "robots.txt", "sitemap.xml"],
      manifest: false, // Use existing site.webmanifest
      workbox: {
        globPatterns: ["**/*.{js,css,html,png,svg,ico,woff2}"],
        runtimeCaching: [
          {
            urlPattern: GOOGLE_FONTS_PATTERN,
            handler: "CacheFirst",
            options: {
              cacheName: "google-fonts-cache",
              expiration: {
                maxEntries: 10,
                maxAgeSeconds: 60 * 60 * 24 * 365, // 1 year
              },
              cacheableResponse: {
                statuses: [0, 200],
              },
            },
          },
          {
            urlPattern: GSTATIC_FONTS_PATTERN,
            handler: "CacheFirst",
            options: {
              cacheName: "gstatic-fonts-cache",
              expiration: {
                maxEntries: 10,
                maxAgeSeconds: 60 * 60 * 24 * 365, // 1 year
              },
              cacheableResponse: {
                statuses: [0, 200],
              },
            },
          },
        ],
        navigateFallback: null, // TanStack Start handles routing
        skipWaiting: false, // User-controlled updates
        clientsClaim: false,
      },
      devOptions: {
        enabled: false, // Disable in dev for faster iteration
      },
    }),
  ],
  ssr: {
    external: ["@takumi-rs/image-response"],
  },
  optimizeDeps: {
    exclude: ["@takumi-rs/image-response"],
  },
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          // Shiki - syntax highlighting (~300KB)
          if (id.includes("shiki")) {
            return "shiki";
          }
          // Prettier - large dependency (~1.2MB with parsers)
          if (
            id.includes("prettier/standalone") ||
            id.includes("prettier/plugins")
          ) {
            return "prettier";
          }
          // SVGO - only in workers, exclude from main bundle
          if (id.includes("svgo") && !id.includes(".worker")) {
            return "svgo";
          }
          // Radix UI components
          if (id.includes("@radix-ui")) {
            return "ui";
          }
        },
      },
    },
  },
}));

build error console

> vite build

Starting content-collections with config content-collections.ts
vite v7.2.4 building client environment for production...
Start initial build
build started ...
[intlayer]  Preparing Intlayer (v6.1.6)
[intlayer]  ✓ Local content: 8/8
... finished build of 1 collection and 36 documents in 162ms
[intlayer]  Dictionaries built (160ms)
transforming (1810) src/lib/svgo-plugins.ts[BABEL] Note: The code generator has deoptimised the styling of /Users/guanwei/x/doit/tiny-svg/apps/web/.content-collections/generated/allPosts.js as it exceeds the max of 500KB.
[plugin vite:resolve] Module "os" has been externalized for browser compatibility, imported by "/Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/svgo@4.0.0/node_modules/svgo/lib/svgo-node.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
[plugin vite:resolve] Module "fs/promises" has been externalized for browser compatibility, imported by "/Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/svgo@4.0.0/node_modules/svgo/lib/svgo-node.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
[plugin vite:resolve] Module "path" has been externalized for browser compatibility, imported by "/Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/svgo@4.0.0/node_modules/svgo/lib/svgo-node.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
[plugin vite:resolve] Module "url" has been externalized for browser compatibility, imported by "/Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/svgo@4.0.0/node_modules/svgo/lib/svgo-node.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
[plugin vite:resolve] Module "stream" has been externalized for browser compatibility, imported by "/Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/sax@1.4.3/node_modules/sax/lib/sax.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
[plugin vite:resolve] Module "string_decoder" has been externalized for browser compatibility, imported by "/Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/sax@1.4.3/node_modules/sax/lib/sax.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
✓ 2968 modules transformed.
....

(!) Some chunks are larger than 500 kB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
✓ built in 4.87s

PWA v1.1.0
mode      generateSW
precache  9 entries (0.00 KiB)
files generated
  dist/sw.js
  dist/workbox-21de4c82.js
warnings
  One of the glob patterns doesn't match any files. Please remove or fix the following: {
  "globDirectory": "/Users/guanwei/x/doit/tiny-svg/apps/web/dist",
  "globPattern": "**/*.{js,css,html,png,svg,ico,woff2}",
  "globIgnores": [
    "**/node_modules/**/*",
    "sw.js",
    "workbox-*.js"
  ]
}

vite v7.2.4 building ssr environment for production...
Start initial build
build started ...
[intlayer]  Intlayer prepared
... finished build of 1 collection and 36 documents in 129ms
✓ 3083 modules transformed.

✓ built in 2.85s

PWA v1.1.0
mode      generateSW
precache  9 entries (0.00 KiB)
files generated
  dist/sw.js
  dist/workbox-21de4c82.js
warnings
  One of the glob patterns doesn't match any files. Please remove or fix the following: {
  "globDirectory": "/Users/guanwei/x/doit/tiny-svg/apps/web/dist",
  "globPattern": "**/*.{js,css,html,png,svg,ico,woff2}",
  "globIgnores": [
    "**/node_modules/**/*",
    "sw.js",
    "workbox-*.js"
  ]
}

[prerender] Prerendering pages...
Starting content-collections with config content-collections.ts
[nitro] No build found. Please build your project before previewing.
[prerender] Concurrency: 10
[prerender] Crawling: /en/blog
[prerender] Crawling: /zh/blog
[prerender] Crawling: /ko/blog
[prerender] Crawling: /de/blog
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/guanwei/x/doit/tiny-svg/apps/web/dist/server/server.js' imported from /Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/@tanstack+start-plugin-core@1.139.0_@tanstack+react-router@1.139.0_react-dom@19.1.0_rea_655f57886a17e7b61fe86aa1b0a9e988/node_modules/@tanstack/start-plugin-core/dist/esm/preview-server-plugin/plugin.js
    at finalizeResolution (node:internal/modules/esm/resolve:274:11)
    at moduleResolve (node:internal/modules/esm/resolve:864:10)
    at defaultResolve (node:internal/modules/esm/resolve:990:11)
    at nextResolve (node:internal/modules/esm/hooks:748:28)
    at o (file:///Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/@tailwindcss+node@4.1.17/node_modules/@tailwindcss/node/dist/esm-cache.loader.mjs:1:69)
    at nextResolve (node:internal/modules/esm/hooks:748:28)
    at Hooks.resolve (node:internal/modules/esm/hooks:240:30)
    at MessagePort.handleMessage (node:internal/modules/esm/worker:201:24)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:827:20)
    at MessagePort.<anonymous> (node:internal/per_context/messageport:23:28)
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/guanwei/x/doit/tiny-svg/apps/web/dist/server/server.js' imported from /Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/@tanstack+start-plugin-core@1.139.0_@tanstack+react-router@1.139.0_react-dom@19.1.0_rea_655f57886a17e7b61fe86aa1b0a9e988/node_modules/@tanstack/start-plugin-core/dist/esm/preview-server-plugin/plugin.js
    at finalizeResolution (node:internal/modules/esm/resolve:274:11)
    at moduleResolve (node:internal/modules/esm/resolve:864:10)
    at defaultResolve (node:internal/modules/esm/resolve:990:11)
    at nextResolve (node:internal/modules/esm/hooks:748:28)
    at o (file:///Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/@tailwindcss+node@4.1.17/node_modules/@tailwindcss/node/dist/esm-cache.loader.mjs:1:69)
    at nextResolve (node:internal/modules/esm/hooks:748:28)
    at Hooks.resolve (node:internal/modules/esm/hooks:240:30)
    at handleMessage (node:internal/modules/esm/worker:201:24)
    at Immediate.checkForMessages (node:internal/modules/esm/worker:143:28)
    at process.processImmediate (node:internal/timers:505:21)
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/guanwei/x/doit/tiny-svg/apps/web/dist/server/server.js' imported from /Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/@tanstack+start-plugin-core@1.139.0_@tanstack+react-router@1.139.0_react-dom@19.1.0_rea_655f57886a17e7b61fe86aa1b0a9e988/node_modules/@tanstack/start-plugin-core/dist/esm/preview-server-plugin/plugin.js
    at finalizeResolution (node:internal/modules/esm/resolve:274:11)
    at moduleResolve (node:internal/modules/esm/resolve:864:10)
    at defaultResolve (node:internal/modules/esm/resolve:990:11)
    at nextResolve (node:internal/modules/esm/hooks:748:28)
    at o (file:///Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/@tailwindcss+node@4.1.17/node_modules/@tailwindcss/node/dist/esm-cache.loader.mjs:1:69)
    at nextResolve (node:internal/modules/esm/hooks:748:28)
    at Hooks.resolve (node:internal/modules/esm/hooks:240:30)
    at handleMessage (node:internal/modules/esm/worker:201:24)
    at checkForMessages (node:internal/modules/esm/worker:143:28)
    at process.<anonymous> (node:internal/modules/esm/worker:162:5)
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/guanwei/x/doit/tiny-svg/apps/web/dist/server/server.js' imported from /Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/@tanstack+start-plugin-core@1.139.0_@tanstack+react-router@1.139.0_react-dom@19.1.0_rea_655f57886a17e7b61fe86aa1b0a9e988/node_modules/@tanstack/start-plugin-core/dist/esm/preview-server-plugin/plugin.js
    at finalizeResolution (node:internal/modules/esm/resolve:274:11)
    at moduleResolve (node:internal/modules/esm/resolve:864:10)
    at defaultResolve (node:internal/modules/esm/resolve:990:11)
    at nextResolve (node:internal/modules/esm/hooks:748:28)
    at o (file:///Users/guanwei/x/doit/tiny-svg/node_modules/.pnpm/@tailwindcss+node@4.1.17/node_modules/@tailwindcss/node/dist/esm-cache.loader.mjs:1:69)
    at nextResolve (node:internal/modules/esm/hooks:748:28)
    at Hooks.resolve (node:internal/modules/esm/hooks:240:30)
    at handleMessage (node:internal/modules/esm/worker:201:24)
    at Immediate.checkForMessages (node:internal/modules/esm/worker:143:28)
    at process.processImmediate (node:internal/timers:505:21)
[prerender] Prerendered 0 pages:
[sitemap] Building Sitemap...
[sitemap] Writing sitemap XML at /Users/guanwei/x/doit/tiny-svg/apps/web/.output/public/sitemap.xml
[sitemap] Writing pages data at /Users/guanwei/x/doit/tiny-svg/apps/web/.output/public/pages.json

◐ Building [Nitro] (preset: node-server, compatibility: 2025-11-22)            nitro 10:19:49 AM
✔ Generated public .output/public                                             nitro 10:19:49 AM
vite v7.2.4 building nitro environment for production...
Start initial build
build started ...
[intlayer]  Intlayer prepared
... finished build of 1 collection and 36 documents in 135ms
✓ 102 modules transformed.
....
✓ built in 4.48s

PWA v1.1.0
mode      generateSW
precache  9 entries (0.00 KiB)
files generated
  dist/sw.js
  dist/workbox-21de4c82.js
warnings
  One of the glob patterns doesn't match any files. Please remove or fix the following: {
  "globDirectory": "/Users/guanwei/x/doit/tiny-svg/apps/web/dist",
  "globPattern": "**/*.{js,css,html,png,svg,ico,woff2}",
  "globIgnores": [
    "**/node_modules/**/*",
    "sw.js",
    "workbox-*.js"
  ]
}

ℹ Generated .output/nitro.json                                                      10:19:54 AM

✔ You can preview this build using node .output/server/index.mjs              nitro 10:19:54 AM

Your Example Website or App

https://tiny-svg.actnow.dev/

Steps to Reproduce the Bug or Issue

  1. pnpm install
  2. pnpm run build

Because failOnError is false, the build process will not be interrupted by an error.

Expected behavior

prerender success, build no error

Screenshots or Videos

No response

Platform

  • "@tanstack/react-start": "^1.132.31"
  • "@tanstack/react-router": "^1.132.31"
  • OS: macOS (deploy vercel same error)
  • Bundler: vite
  • "vite": "^7.0.2"

Additional context

I used PWA, and I'm not sure if this is the cause.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions