File tree Expand file tree Collapse file tree 4 files changed +36
-1
lines changed
Expand file tree Collapse file tree 4 files changed +36
-1
lines changed Original file line number Diff line number Diff line change @@ -70,7 +70,7 @@ export function manifest(start: SolidStartOptions): PluginOption {
7070 tag: "style",
7171 attrs: {
7272 type: "text/css",
73- "data-vite-dev-id": "${ key } ",
73+ "data-vite-dev-id": "${ wrapId ( key ) } ",
7474 "data-vite-ref": "0",
7575 },
7676 children: () => import("${ wrapId ( value ) } ?inline").then(mod => mod.default),
Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ import App from "solid-start:app";
55
66import { ErrorBoundary , TopErrorBoundary } from "../shared/ErrorBoundary.tsx" ;
77import { useAssets } from "./assets/index.ts" ;
8+ import PatchVirtualDevStyles from "./assets/PatchVirtualDevStyles.tsx" ;
89import { getSsrManifest } from "./manifest/ssr-manifest.ts" ;
910import type { DocumentComponentProps , PageEvent } from "./types.ts" ;
1011
@@ -29,6 +30,7 @@ export function StartServer(props: { document: Component<DocumentComponentProps>
2930 assets = { < HydrationScript /> }
3031 scripts = {
3132 < >
33+ < PatchVirtualDevStyles nonce = { nonce } />
3234 < script
3335 type = "module"
3436 nonce = { nonce }
Original file line number Diff line number Diff line change 1+ /**
2+ * Patches the data-vite-dev-id attribute for style tags of virtual modules
3+ *
4+ * Per Vite's convention, virtual module ids are prefixed with \0 (null byte):
5+ * https://vite.dev/guide/api-plugin#virtual-modules-convention
6+ *
7+ * However this null byte cannot be server rendered properly.
8+ * Vite client runtime then fails to find style's with wrong null bytes,
9+ * and instead inserts duplicate style's.
10+ *
11+ * This patch replaces the serializable /@id/__x00__ with the proper null byte,
12+ * and has to run before Vite's client runtime:
13+ * https://github.com/vitejs/vite/blob/130e7181a55c524383c63bbfb1749d0ff7185cad/packages/vite/src/client/client.ts#L529
14+ *
15+ * TODO: This should be solved in Vite directly!
16+ */
17+ const patch = function ( ) {
18+ document . querySelectorAll < HTMLElement > ( "style[data-vite-dev-id]" ) . forEach ( function ( el ) {
19+ el . setAttribute ( "data-vite-dev-id" , el . dataset . viteDevId ! . replace ( "/@id/__x00__" , "\0" ) ) ;
20+ } ) ;
21+ } ;
22+
23+ const serializedPatch = `(${ patch . toString ( ) } )();` ;
24+
25+ const PatchVirtualDevStyles = ( props : { nonce ?: string } ) => {
26+ if ( ! import . meta. env . PROD ) {
27+ return < script nonce = { props . nonce } innerHTML = { serializedPatch } /> ;
28+ }
29+ } ;
30+
31+ export default PatchVirtualDevStyles ;
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ import { getSsrManifest } from "../manifest/ssr-manifest.ts";
66
77import { TopErrorBoundary } from "../../shared/ErrorBoundary.tsx" ;
88import { useAssets } from "../assets/index.ts" ;
9+ import PatchVirtualDevStyles from "../assets/PatchVirtualDevStyles.tsx" ;
910import type { DocumentComponentProps , PageEvent } from "../types.ts" ;
1011
1112const docType = ssr ( "<!DOCTYPE html>" ) ;
@@ -27,6 +28,7 @@ export function StartServer(props: { document: Component<DocumentComponentProps>
2728 < props . document
2829 scripts = {
2930 < >
31+ < PatchVirtualDevStyles nonce = { nonce } />
3032 < script
3133 type = "module"
3234 src = { getSsrManifest ( "client" ) . path ( import . meta. env . START_CLIENT_ENTRY ) }
You can’t perform that action at this time.
0 commit comments