Skip to content

fix: thread Vite base through SSR manifest and Nitro baseURL#2152

Open
bigmistqke wants to merge 3 commits into
solidjs:mainfrom
bigmistqke:fix/base-path-threading
Open

fix: thread Vite base through SSR manifest and Nitro baseURL#2152
bigmistqke wants to merge 3 commits into
solidjs:mainfrom
bigmistqke:fix/base-path-threading

Conversation

@bigmistqke
Copy link
Copy Markdown

@bigmistqke bigmistqke commented May 31, 2026

Hey all 👋

I wanted to deploy solidbase to gh-pages, but I needed to add basePath awareness to SolidStart so I vibecoded it with claude.

[after this line all is written by claude]

Fixes #2151.

Summary

Under a non-root Vite base, the prod SSR manifest emits root-absolute URLs for scripts, modulepreload, and stylesheets, and @solidjs/vite-plugin-nitro-2 ignores the same base for Nitro routing. Subpath deploys (GitHub Pages, reverse-proxied paths, embedded mounts) ship HTML that 404s every asset.

This restores the v1 behavior — base flows through the build manifest — without changing any public API or adding a new helper.

Changes

  • prod-ssr-manifest.ts — replace join("/", ...) with join(import.meta.env.BASE_URL, ...) in path, getAssets, and json. Matches the existing pattern in dev-ssr-manifest.ts.
  • dev-client-manifest.ts — same fix for the dev-mode dynamic import.
  • vite-plugin-nitro-2 — capture Vite's resolved config.base in configResolved and use it as the nitroConfig.baseURL default. A user-supplied nitroV2Plugin({ baseURL }) still wins because the spread comes after.

pathe.join collapses correctly when BASE_URL === "/", so the no-base case is unchanged (verified with a smoke build of apps/tests).

Tests

New packages/start/src/server/manifest/prod-ssr-manifest.spec.ts covers:

  • path(id) returns BASE_URL-prefixed paths.
  • getAssets(id) hrefs all sit under BASE_URL.
  • json() output paths are BASE_URL-prefixed.
  • BASE_URL "/" still emits single-slash URLs.

6/6 pass after the fix.

Manual verification

apps/tests built twice — once with base: "/sub/", once default. With base, every script/link tag is correctly prefixed and the Nitro server listens at /sub. Without base, output is byte-identical to main.

What this PR does NOT cover

This fixes framework-emitted URLs. User-authored root-absolute paths still need to be base-aware on the user's side — the framework can't safely rewrite arbitrary string literals in user code. Specifically:

  • entry-server.tsx static <head> references<link rel="icon" href="/favicon.ico" />, <link rel="manifest" href="/site.webmanifest" />, <meta property="og:image" content="/og.png" />, etc. These live in user JSX, not the build manifest, so they ship as-is. Authors should use ${import.meta.env.BASE_URL}favicon.ico (or a small helper).
  • User-authored <a href="/..."> — Solid Router's <A> prepends base; plain <a> does not unless the click is intercepted. Recommend <A> for in-app navigation.
  • CSS url(/foo) and <img src="/foo"> — same story. Vite handles asset imports (import logo from "./logo.png") and new URL("./asset", import.meta.url) correctly; raw string paths are the user's responsibility.
  • Sitemap / robots / canonical URLs generated by themes or user code — these typically depend on a separate siteUrl config, not Vite base.

A follow-up could ship a tiny withBase(path) helper from @solidjs/start to make the user-side calls less noisy, but that's a separate discussion.

Out of scope (also follow-up)

  • Auto-passing base to <Router> in app.tsx. Touches the router integration; happy to follow up if maintainers want it.
  • Any change to <Router base> semantics in @solidjs/router.

Commits

  1. 0147d17 test(start): fail when prod SSR manifest ignores deploy base
  2. e872ac8 fix(start): thread BASE_URL through SSR manifest paths
  3. 4bb7d84 fix(vite-plugin-nitro-2): inherit Vite config.base as the Nitro baseURL

Asserts getSsrProdManifest().path() / .getAssets() / .json() emit URLs
prefixed with import.meta.env.BASE_URL. Currently red: every emitted path
is rooted at '/', so subpath-deployed apps load script and CSS tags from
the wrong origin path.
The prod SSR manifest hard-coded '/' as the prefix for entry script src,
modulepreload/stylesheet hrefs, and the serialized window.manifest output
paths. Under a deploy base ('/repo/' on GitHub Pages, etc.) every emitted
URL pointed at the wrong origin path, so the prerendered HTML loaded
nothing and the app failed to hydrate.

Replace '/' with import.meta.env.BASE_URL via pathe.join, matching the
dev-ssr-manifest's existing base-aware joins. Apply the same fix to the
dev-client-manifest's dynamic import.
Today the plugin defaults Nitro's baseURL to '/' regardless of the
project's Vite base. On a subpath deploy ('base: "/repo/"' for GitHub
Pages, etc.) Nitro then prerenders, route-prefixes, and serves at the
wrong path, forcing users to pass the prefix to both Vite and the plugin.

Capture the resolved Vite base in configResolved and use it as the
nitroConfig.baseURL default. A user-supplied nitroV2Plugin({ baseURL }) is
still honored because the spread comes after the default.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 31, 2026

⚠️ No Changeset found

Latest commit: 4bb7d84

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@netlify
Copy link
Copy Markdown

netlify Bot commented May 31, 2026

Deploy Preview for solid-start-landing-page ready!

Name Link
🔨 Latest commit 4bb7d84
🔍 Latest deploy log https://app.netlify.com/projects/solid-start-landing-page/deploys/6a1be17730f3fe0008855750
😎 Deploy Preview https://deploy-preview-2152--solid-start-landing-page.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 31, 2026

Open in StackBlitz

npm i https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2152
npm i https://pkg.pr.new/solidjs/solid-start/@solidjs/vite-plugin-nitro-2@2152

commit: 4bb7d84

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SolidStart 2.0 (alpha) ignores Vite base for prerendered/SSR script and asset URLs

1 participant