@expo/router-server 56.0.14 → 57.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/server/renderStreamingContent.d.ts +8 -0
- package/build/server/renderStreamingContent.d.ts.map +1 -1
- package/build/server/renderStreamingContent.js +35 -32
- package/build/server/renderStreamingContent.js.map +1 -1
- package/build/static/renderStaticContent.d.ts +2 -0
- package/build/static/renderStaticContent.d.ts.map +1 -1
- package/build/static/renderStaticContent.js +29 -26
- package/build/static/renderStaticContent.js.map +1 -1
- package/build/utils/html.d.ts +8 -0
- package/build/utils/html.d.ts.map +1 -1
- package/build/utils/html.js +11 -0
- package/build/utils/html.js.map +1 -1
- package/build/utils/react.d.ts +4 -0
- package/build/utils/react.d.ts.map +1 -1
- package/build/utils/react.js +6 -0
- package/build/utils/react.js.map +1 -1
- package/package.json +8 -8
|
@@ -18,6 +18,14 @@ export type GetStreamingContentOptions = {
|
|
|
18
18
|
/** Assets for hydration bundles and development-only inline CSS. */
|
|
19
19
|
assets?: {
|
|
20
20
|
css: string[];
|
|
21
|
+
/**
|
|
22
|
+
* External stylesheets (`@import url(https://…)`) extracted from the bundled CSS, rendered
|
|
23
|
+
* verbatim as `<link rel="stylesheet">` so attributes like `media` survive.
|
|
24
|
+
*/
|
|
25
|
+
externalCss?: {
|
|
26
|
+
href: string;
|
|
27
|
+
media?: string;
|
|
28
|
+
}[];
|
|
21
29
|
/** CSS source to inline into the document head, used by development SSR. */
|
|
22
30
|
inlineCss?: {
|
|
23
31
|
source: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderStreamingContent.d.ts","sourceRoot":"","sources":["../../src/server/renderStreamingContent.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"renderStreamingContent.d.ts","sourceRoot":"","sources":["../../src/server/renderStreamingContent.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA2BzC,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,oEAAoE;QACpE,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,SAAS,EAAE,SAAS,EAAE,CAAC;KACxB,GAAG,IAAI,CAAC;IACT,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,MAAM,CAAC,EAAE;QACP,GAAG,EAAE,MAAM,EAAE,CAAC;QACd;;;WAGG;QACH,WAAW,CAAC,EAAE;YACZ,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,EAAE,CAAC;QACJ,4EAA4E;QAC5E,SAAS,CAAC,EAAE;YACV,MAAM,EAAE,MAAM,CAAC;YACf,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,EAAE,CAAC;QACJ,EAAE,EAAE,MAAM,EAAE,CAAC;QACb,+EAA+E;QAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAgDF;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,GAAG,EACb,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAsDrC;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -81,9 +81,6 @@ function prepareRenderContext(location, options) {
|
|
|
81
81
|
context: _ctx_1.ctx,
|
|
82
82
|
wrapper: ({ children }) => ((0, jsx_runtime_1.jsx)(Root, { children: (0, jsx_runtime_1.jsx)("div", { id: "root", children: children }) })),
|
|
83
83
|
});
|
|
84
|
-
// Clear any existing static resources from the global scope to attempt to prevent leaking between pages.
|
|
85
|
-
// This could break if pages are rendered in parallel or if fonts are loaded outside of the React tree
|
|
86
|
-
Font.resetServerContext();
|
|
87
84
|
// This MUST be run before `ReactDOMServer.renderToString` to prevent
|
|
88
85
|
// "Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported."
|
|
89
86
|
resetReactNavigationContexts();
|
|
@@ -96,6 +93,8 @@ function prepareRenderContext(location, options) {
|
|
|
96
93
|
return { headContext, element, getStyleElement, loadedData };
|
|
97
94
|
}
|
|
98
95
|
function FontResources() {
|
|
96
|
+
// NOTE(@hassankhan): runs once during the shell pass; fonts loaded inside late-resolving
|
|
97
|
+
// Suspense boundaries register after this and won't be emitted.
|
|
99
98
|
const descriptors = Font.getServerResourceDescriptors();
|
|
100
99
|
debug(`Pushing fonts: (count: ${descriptors.length})`, descriptors);
|
|
101
100
|
return (0, react_1.createInjectedFontsAsNodes)(descriptors);
|
|
@@ -105,35 +104,39 @@ function FontResources() {
|
|
|
105
104
|
* that emits the full HTML document with head injections applied.
|
|
106
105
|
*/
|
|
107
106
|
async function getStreamingContent(location, options) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
107
|
+
return Font.withServerContext(() => {
|
|
108
|
+
const { headContext, element, getStyleElement, loadedData } = prepareRenderContext(location, options);
|
|
109
|
+
const { headNodes: headCssNodes } = (0, react_1.createInjectedCssAsNodes)(options?.assets?.css ?? []);
|
|
110
|
+
const { headNodes: externalCssNodes } = (0, react_1.createInjectedExternalCssAsNodes)(options?.assets?.externalCss);
|
|
111
|
+
const { headNodes: inlineCssNodes } = (0, react_1.createInjectedInlineCssAsNodes)(options?.assets?.inlineCss);
|
|
112
|
+
const faviconNode = options?.assets?.favicon
|
|
113
|
+
? (0, react_1.createFaviconAsNode)(options?.assets?.favicon)
|
|
114
|
+
: undefined;
|
|
115
|
+
const serverDocumentData = {
|
|
116
|
+
headNodes: [
|
|
117
|
+
...(options?.metadata?.headNodes ?? []),
|
|
118
|
+
faviconNode,
|
|
119
|
+
getStyleElement({ key: 'rnw-style-element' }),
|
|
120
|
+
...(headCssNodes ?? []),
|
|
121
|
+
...(externalCssNodes ?? []),
|
|
122
|
+
...(inlineCssNodes ?? []),
|
|
123
|
+
].filter(Boolean),
|
|
124
|
+
bodyNodes: [(0, jsx_runtime_1.jsx)(FontResources, {}, "font-resources")],
|
|
125
|
+
};
|
|
126
|
+
return server_2.default.renderToReadableStream((0, jsx_runtime_1.jsx)(server_1.ServerDocument, { data: serverDocumentData, children: (0, jsx_runtime_1.jsx)(head_1.default.Provider, { context: headContext, children: (0, jsx_runtime_1.jsx)(static_1.InnerRoot, { loadedData: loadedData, children: element }) }) }), {
|
|
127
|
+
// TODO(@hassankhan): Experiment and see if we can calculate a better default
|
|
128
|
+
// We're doubling the default here so non-JavaScript renders show some content
|
|
129
|
+
progressiveChunkSize: 12800 * 2,
|
|
130
|
+
bootstrapScriptContent: (0, react_1.getBootstrapContents)({ hydrate: true, loadedData }),
|
|
131
|
+
bootstrapScripts: options?.assets?.js,
|
|
132
|
+
signal: options?.request?.signal,
|
|
133
|
+
onError(error) {
|
|
134
|
+
if (options?.request?.signal.aborted) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
console.error('SSR streaming render error:', error);
|
|
138
|
+
},
|
|
139
|
+
});
|
|
137
140
|
});
|
|
138
141
|
}
|
|
139
142
|
var metadata_1 = require("./metadata");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderStreamingContent.js","sourceRoot":"","sources":["../../src/server/renderStreamingContent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"renderStreamingContent.js","sourceRoot":"","sources":["../../src/server/renderStreamingContent.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright © 2026 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n// NOTE(@hassankhan): disable when this file is its own entrypoint\n// import '@expo/metro-runtime';\n\nimport * as Font from 'expo-font/build/server';\nimport { ExpoRoot } from 'expo-router';\nimport { ctx } from 'expo-router/_ctx';\nimport Head from 'expo-router/head';\nimport { ServerDocument } from 'expo-router/internal/server';\nimport { InnerRoot, registerStaticRootComponent } from 'expo-router/internal/static';\nimport React, { ReactNode } from 'react';\nimport ReactDOMServer from 'react-dom/server';\n\nimport { getRootComponent } from '../static/getRootComponent';\nimport { createDebug } from '../utils/debug';\nimport {\n createFaviconAsNode,\n createInjectedCssAsNodes,\n createInjectedExternalCssAsNodes,\n createInjectedFontsAsNodes,\n createInjectedInlineCssAsNodes,\n getBootstrapContents,\n} from '../utils/react';\n\nconst debug = createDebug('expo:router:server:renderStreamingContent');\n\nfunction resetReactNavigationContexts() {\n // https://github.com/expo/router/discussions/588\n // https://github.com/react-navigation/react-navigation/blob/9fe34b445fcb86e5666f61e144007d7540f014fa/packages/elements/src/getNamedContext.tsx#LL3C1-L4C1\n\n // React Navigation is storing providers in a global, this is fine for the first static render\n // but subsequent static renders of Stack or Tabs will cause React to throw a warning. To prevent this warning, we'll reset the globals before rendering.\n const contexts = '__react_navigation__elements_contexts';\n (globalThis as any)[contexts] = new Map<string, React.Context<any>>();\n}\n\n// NOTE(@hassankhan): Keep in sync with `expo-server/src/manifest.ts`\nexport type GetStreamingContentOptions = {\n loader?: {\n data?: any;\n /** Unique key for the route. Derived from the route's contextKey */\n key: string;\n };\n metadata?: {\n headNodes: ReactNode[];\n } | null;\n request?: Request;\n /** Assets for hydration bundles and development-only inline CSS. */\n assets?: {\n css: string[];\n /**\n * External stylesheets (`@import url(https://…)`) extracted from the bundled CSS, rendered\n * verbatim as `<link rel=\"stylesheet\">` so attributes like `media` survive.\n */\n externalCss?: {\n href: string;\n media?: string;\n }[];\n /** CSS source to inline into the document head, used by development SSR. */\n inlineCss?: {\n source: string;\n hmrId?: string;\n }[];\n js: string[];\n /** Public href of a favicon generated from `web.favicon` in the app config. */\n favicon?: string;\n };\n};\n\n/**\n * Shared setup for both `getStaticContent()` and `getStreamingContent()`. Creates the React element\n * tree, resets server contexts, and computes loader data.\n */\nfunction prepareRenderContext(location: URL, options?: GetStreamingContentOptions) {\n const headContext: { helmet?: any } = {};\n const Root = getRootComponent();\n\n const {\n // NOTE: The `element` that's returned adds two extra Views and\n // the seemingly unused `RootTagContext.Provider`.\n element,\n getStyleElement,\n } = registerStaticRootComponent(ExpoRoot, {\n location,\n context: ctx,\n wrapper: ({ children }: React.ComponentProps<any>) => (\n <Root>\n <div id=\"root\">{children}</div>\n </Root>\n ),\n });\n\n // This MUST be run before `ReactDOMServer.renderToString` to prevent\n // \"Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.\"\n resetReactNavigationContexts();\n\n const loaderKey = options?.loader ? options.loader.key + location.search : null;\n\n const loadedData = loaderKey\n ? {\n [loaderKey]: options?.loader?.data ?? null,\n }\n : null;\n\n return { headContext, element, getStyleElement, loadedData };\n}\n\nfunction FontResources() {\n // NOTE(@hassankhan): runs once during the shell pass; fonts loaded inside late-resolving\n // Suspense boundaries register after this and won't be emitted.\n const descriptors = Font.getServerResourceDescriptors();\n debug(`Pushing fonts: (count: ${descriptors.length})`, descriptors);\n return createInjectedFontsAsNodes(descriptors);\n}\n\n/**\n * Streaming SSR renderer using `renderToReadableStream`. Returns a web `ReadableStream`\n * that emits the full HTML document with head injections applied.\n */\nexport async function getStreamingContent(\n location: URL,\n options?: GetStreamingContentOptions\n): Promise<ReadableStream<Uint8Array>> {\n return Font.withServerContext(() => {\n const { headContext, element, getStyleElement, loadedData } = prepareRenderContext(\n location,\n options\n );\n\n const { headNodes: headCssNodes } = createInjectedCssAsNodes(options?.assets?.css ?? []);\n const { headNodes: externalCssNodes } = createInjectedExternalCssAsNodes(\n options?.assets?.externalCss\n );\n const { headNodes: inlineCssNodes } = createInjectedInlineCssAsNodes(\n options?.assets?.inlineCss\n );\n const faviconNode = options?.assets?.favicon\n ? createFaviconAsNode(options?.assets?.favicon)\n : undefined;\n\n const serverDocumentData = {\n headNodes: [\n ...(options?.metadata?.headNodes ?? []),\n faviconNode,\n getStyleElement({ key: 'rnw-style-element' }),\n ...(headCssNodes ?? []),\n ...(externalCssNodes ?? []),\n ...(inlineCssNodes ?? []),\n ].filter(Boolean),\n bodyNodes: [<FontResources key=\"font-resources\" />],\n };\n\n return ReactDOMServer.renderToReadableStream(\n <ServerDocument data={serverDocumentData}>\n {/* TODO(@hassankhan): Remove `<Head.Provider>` when `unstable_useServerRendering` is stabilized */}\n <Head.Provider context={headContext}>\n <InnerRoot loadedData={loadedData}>{element}</InnerRoot>\n </Head.Provider>\n </ServerDocument>,\n {\n // TODO(@hassankhan): Experiment and see if we can calculate a better default\n // We're doubling the default here so non-JavaScript renders show some content\n progressiveChunkSize: 12800 * 2,\n bootstrapScriptContent: getBootstrapContents({ hydrate: true, loadedData }),\n bootstrapScripts: options?.assets?.js,\n signal: options?.request?.signal,\n onError(error) {\n if (options?.request?.signal.aborted) {\n return;\n }\n\n console.error('SSR streaming render error:', error);\n },\n }\n );\n });\n}\n\nexport { resolveMetadata } from './metadata';\n"]}
|
|
@@ -16,6 +16,8 @@ export type GetStaticContentOptions = {
|
|
|
16
16
|
assets?: {
|
|
17
17
|
css: string[];
|
|
18
18
|
js: string[];
|
|
19
|
+
/** Public href of a favicon generated from `web.favicon` in the app config. */
|
|
20
|
+
favicon?: string;
|
|
19
21
|
};
|
|
20
22
|
};
|
|
21
23
|
export declare function getStaticContent(location: URL, options?: GetStaticContentOptions): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderStaticContent.d.ts","sourceRoot":"","sources":["../../src/static/renderStaticContent.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"renderStaticContent.d.ts","sourceRoot":"","sources":["../../src/static/renderStaticContent.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,qBAAqB,CAAC;AAgC7B,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,oEAAoE;QACpE,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE;QACP,GAAG,EAAE,MAAM,EAAE,CAAC;QACd,EAAE,EAAE,MAAM,EAAE,CAAC;QACb,+EAA+E;QAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAwCF,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,GAAG,EACb,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,MAAM,CAAC,CAmDjB;AAiBD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxF,OAAO,EAAE,+BAA+B,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -79,9 +79,6 @@ function prepareRenderContext(location, options) {
|
|
|
79
79
|
context: _ctx_1.ctx,
|
|
80
80
|
wrapper: ({ children }) => ((0, jsx_runtime_1.jsx)(Root, { children: (0, jsx_runtime_1.jsx)("div", { id: "root", children: children }) })),
|
|
81
81
|
});
|
|
82
|
-
// Clear any existing static resources from the global scope to attempt to prevent leaking between pages.
|
|
83
|
-
// This could break if pages are rendered in parallel or if fonts are loaded outside of the React tree
|
|
84
|
-
Font.resetServerContext();
|
|
85
82
|
// This MUST be run before `ReactDOMServer.renderToString` to prevent
|
|
86
83
|
// "Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported."
|
|
87
84
|
resetReactNavigationContexts();
|
|
@@ -94,31 +91,37 @@ function prepareRenderContext(location, options) {
|
|
|
94
91
|
return { headContext, element, getStyleElement, loadedData };
|
|
95
92
|
}
|
|
96
93
|
async function getStaticContent(location, options) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// Inject hydration assets (JS/CSS bundles). Used in SSR mode
|
|
111
|
-
if (options?.assets) {
|
|
112
|
-
if (options.assets.css.length > 0) {
|
|
113
|
-
const injectedCSS = (0, html_1.createInjectedCssAsString)(options.assets.css);
|
|
114
|
-
output = output.replace('</head>', `${injectedCSS}\n</head>`);
|
|
94
|
+
return Font.withServerContext(() => {
|
|
95
|
+
const { headContext, element, getStyleElement, loadedData } = prepareRenderContext(location, options);
|
|
96
|
+
const html = server_1.default.renderToString((0, jsx_runtime_1.jsx)(head_1.default.Provider, { context: headContext, children: (0, jsx_runtime_1.jsx)(static_1.InnerRoot, { loadedData: loadedData, children: element }) }));
|
|
97
|
+
// Eval the CSS after the HTML is rendered so that the CSS is in the same order
|
|
98
|
+
const css = server_1.default.renderToStaticMarkup(getStyleElement());
|
|
99
|
+
let output = mixHeadComponentsWithStaticResults(headContext.helmet, html);
|
|
100
|
+
output = output.replace('</head>', `${css}</head>`);
|
|
101
|
+
const fonts = Font.getServerResources();
|
|
102
|
+
debug(`Pushing static fonts: (count: ${fonts.length})`, fonts);
|
|
103
|
+
// Inject static fonts loaded with expo-font
|
|
104
|
+
output = output.replace('</head>', `${fonts.join('')}</head>`);
|
|
105
|
+
if (loadedData) {
|
|
106
|
+
output = output.replace('</head>', `${(0, html_1.createLoaderDataScriptAsString)(loadedData)}</head>`);
|
|
115
107
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
output = output.replace('</
|
|
108
|
+
// Inject favicon link tag. Mirrors `assets.favicon` handling in `getStreamingContent`.
|
|
109
|
+
if (options?.assets?.favicon) {
|
|
110
|
+
output = output.replace('</head>', `${(0, html_1.createFaviconAsString)(options.assets.favicon)}</head>`);
|
|
119
111
|
}
|
|
120
|
-
|
|
121
|
-
|
|
112
|
+
// Inject hydration assets (JS/CSS bundles). Used in SSR mode
|
|
113
|
+
if (options?.assets) {
|
|
114
|
+
if (options.assets.css.length > 0) {
|
|
115
|
+
const injectedCSS = (0, html_1.createInjectedCssAsString)(options.assets.css);
|
|
116
|
+
output = output.replace('</head>', `${injectedCSS}\n</head>`);
|
|
117
|
+
}
|
|
118
|
+
if (options.assets.js.length > 0) {
|
|
119
|
+
// In non-streaming mode, use deferred scripts in the body
|
|
120
|
+
output = output.replace('</body>', `${(0, html_1.createInjectedScriptsAsString)(options.assets.js)}\n</body>`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return '<!DOCTYPE html>' + output;
|
|
124
|
+
});
|
|
122
125
|
}
|
|
123
126
|
function mixHeadComponentsWithStaticResults(helmet, html) {
|
|
124
127
|
const { headTags, htmlAttributes, bodyAttributes } = (0, html_1.serializeHelmetToHtml)(helmet);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderStaticContent.js","sourceRoot":"","sources":["../../src/static/renderStaticContent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"renderStaticContent.js","sourceRoot":"","sources":["../../src/static/renderStaticContent.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright © 2026 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport '@expo/metro-runtime';\n\nimport * as Font from 'expo-font/build/server';\nimport { ExpoRoot } from 'expo-router';\nimport { ctx } from 'expo-router/_ctx';\nimport Head from 'expo-router/head';\nimport { InnerRoot, registerStaticRootComponent } from 'expo-router/internal/static';\nimport React from 'react';\nimport ReactDOMServer from 'react-dom/server';\n\nimport { getRootComponent } from './getRootComponent';\nimport { createDebug } from '../utils/debug';\nimport {\n createFaviconAsString,\n createInjectedCssAsString,\n createInjectedScriptsAsString,\n createLoaderDataScriptAsString,\n serializeHelmetToHtml,\n} from '../utils/html';\n\nconst debug = createDebug('expo:router:server:renderStaticContent');\n\nfunction resetReactNavigationContexts() {\n // https://github.com/expo/router/discussions/588\n // https://github.com/react-navigation/react-navigation/blob/9fe34b445fcb86e5666f61e144007d7540f014fa/packages/elements/src/getNamedContext.tsx#LL3C1-L4C1\n\n // React Navigation is storing providers in a global, this is fine for the first static render\n // but subsequent static renders of Stack or Tabs will cause React to throw a warning. To prevent this warning, we'll reset the globals before rendering.\n const contexts = '__react_navigation__elements_contexts';\n (globalThis as any)[contexts] = new Map<string, React.Context<any>>();\n}\n\nexport type GetStaticContentOptions = {\n loader?: {\n data?: any;\n /** Unique key for the route. Derived from the route's contextKey */\n key: string;\n };\n request?: Request;\n /** Asset manifest for hydration bundles (JS/CSS). Used in SSR. */\n assets?: {\n css: string[];\n js: string[];\n /** Public href of a favicon generated from `web.favicon` in the app config. */\n favicon?: string;\n };\n};\n\n/**\n * Shared setup for both `getStaticContent()` and `getStreamingContent()`. Creates the React element\n * tree, resets server contexts, and computes loader data.\n */\nfunction prepareRenderContext(location: URL, options?: GetStaticContentOptions) {\n const headContext: { helmet?: any } = {};\n const Root = getRootComponent();\n\n const {\n // NOTE: The `element` that's returned adds two extra Views and\n // the seemingly unused `RootTagContext.Provider`.\n element,\n getStyleElement,\n } = registerStaticRootComponent(ExpoRoot, {\n location,\n context: ctx,\n wrapper: ({ children }: React.ComponentProps<any>) => (\n <Root>\n <div id=\"root\">{children}</div>\n </Root>\n ),\n });\n\n // This MUST be run before `ReactDOMServer.renderToString` to prevent\n // \"Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.\"\n resetReactNavigationContexts();\n\n const loaderKey = options?.loader ? options.loader.key + location.search : null;\n\n const loadedData = loaderKey\n ? {\n [loaderKey]: options?.loader?.data ?? null,\n }\n : null;\n\n return { headContext, element, getStyleElement, loadedData };\n}\n\nexport async function getStaticContent(\n location: URL,\n options?: GetStaticContentOptions\n): Promise<string> {\n return Font.withServerContext(() => {\n const { headContext, element, getStyleElement, loadedData } = prepareRenderContext(\n location,\n options\n );\n\n const html = ReactDOMServer.renderToString(\n <Head.Provider context={headContext}>\n <InnerRoot loadedData={loadedData}>{element}</InnerRoot>\n </Head.Provider>\n );\n\n // Eval the CSS after the HTML is rendered so that the CSS is in the same order\n const css = ReactDOMServer.renderToStaticMarkup(getStyleElement());\n\n let output = mixHeadComponentsWithStaticResults(headContext.helmet, html);\n\n output = output.replace('</head>', `${css}</head>`);\n\n const fonts = Font.getServerResources();\n debug(`Pushing static fonts: (count: ${fonts.length})`, fonts);\n // Inject static fonts loaded with expo-font\n output = output.replace('</head>', `${fonts.join('')}</head>`);\n if (loadedData) {\n output = output.replace('</head>', `${createLoaderDataScriptAsString(loadedData)}</head>`);\n }\n\n // Inject favicon link tag. Mirrors `assets.favicon` handling in `getStreamingContent`.\n if (options?.assets?.favicon) {\n output = output.replace('</head>', `${createFaviconAsString(options.assets.favicon)}</head>`);\n }\n\n // Inject hydration assets (JS/CSS bundles). Used in SSR mode\n if (options?.assets) {\n if (options.assets.css.length > 0) {\n const injectedCSS = createInjectedCssAsString(options.assets.css);\n output = output.replace('</head>', `${injectedCSS}\\n</head>`);\n }\n\n if (options.assets.js.length > 0) {\n // In non-streaming mode, use deferred scripts in the body\n output = output.replace(\n '</body>',\n `${createInjectedScriptsAsString(options.assets.js)}\\n</body>`\n );\n }\n }\n\n return '<!DOCTYPE html>' + output;\n });\n}\n\nfunction mixHeadComponentsWithStaticResults(helmet: any, html: string) {\n const { headTags, htmlAttributes, bodyAttributes } = serializeHelmetToHtml(helmet);\n\n if (headTags) {\n html = html.replace('<head>', `<head>${headTags}`);\n }\n\n // attributes\n html = html.replace('<html ', `<html ${htmlAttributes} `);\n html = html.replace('<body ', `<body ${bodyAttributes} `);\n\n return html;\n}\n\n// Re-export for use in server\nexport { getStreamingContent, resolveMetadata } from '../server/renderStreamingContent';\nexport { getBuildTimeServerManifestAsync, getManifest } from './getServerManifest';\n"]}
|
package/build/utils/html.d.ts
CHANGED
|
@@ -24,6 +24,14 @@ export declare function createInjectedCssAsString(hrefs: string[]): string;
|
|
|
24
24
|
* HTML document's `<body>` element.
|
|
25
25
|
*/
|
|
26
26
|
export declare function createInjectedScriptsAsString(srcs: string[]): string;
|
|
27
|
+
/**
|
|
28
|
+
* Returns a `<link rel="icon" />` HTML string for the given favicon href.
|
|
29
|
+
*
|
|
30
|
+
* Used by the SPA export path, which splices into a pre-rendered template instead of a React
|
|
31
|
+
* tree. Output must stay byte-equivalent to `createFaviconAsNode` (rendered to static markup)
|
|
32
|
+
* so both rendering paths agree on the tag shape.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createFaviconAsString(href: string): string;
|
|
27
35
|
/**
|
|
28
36
|
* Returns the string content of the hydration flag script, which sets the
|
|
29
37
|
* `__EXPO_ROUTER_HYDRATE__` global flag to `true`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAMD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAUjE;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAGjF;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpF;AAID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,GAAG;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,CAkBA"}
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAMD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAUjE;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAGjF;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpF;AAID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,GAAG;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,CAkBA"}
|
package/build/utils/html.js
CHANGED
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.escapeUnsafeCharacters = escapeUnsafeCharacters;
|
|
10
10
|
exports.createInjectedCssAsString = createInjectedCssAsString;
|
|
11
11
|
exports.createInjectedScriptsAsString = createInjectedScriptsAsString;
|
|
12
|
+
exports.createFaviconAsString = createFaviconAsString;
|
|
12
13
|
exports.getHydrationFlagScriptContents = getHydrationFlagScriptContents;
|
|
13
14
|
exports.getHydrationFlagScriptAsString = getHydrationFlagScriptAsString;
|
|
14
15
|
exports.getLoaderDataScriptContents = getLoaderDataScriptContents;
|
|
@@ -63,6 +64,16 @@ function createInjectedCssAsString(hrefs) {
|
|
|
63
64
|
function createInjectedScriptsAsString(srcs) {
|
|
64
65
|
return srcs.map((src) => `<script src="${escapeHtmlAttribute(src)}" defer></script>`).join('\n');
|
|
65
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Returns a `<link rel="icon" />` HTML string for the given favicon href.
|
|
69
|
+
*
|
|
70
|
+
* Used by the SPA export path, which splices into a pre-rendered template instead of a React
|
|
71
|
+
* tree. Output must stay byte-equivalent to `createFaviconAsNode` (rendered to static markup)
|
|
72
|
+
* so both rendering paths agree on the tag shape.
|
|
73
|
+
*/
|
|
74
|
+
function createFaviconAsString(href) {
|
|
75
|
+
return `<link rel="icon" href="${escapeHtmlAttribute(href)}"/>`;
|
|
76
|
+
}
|
|
66
77
|
/**
|
|
67
78
|
* Returns the string content of the hydration flag script, which sets the
|
|
68
79
|
* `__EXPO_ROUTER_HYDRATE__` global flag to `true`.
|
package/build/utils/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAqBH,wDAEC;AAaD,8DAUC;AAQD,sEAEC;AAQD,wEAEC;AASD,wEAEC;AAQD,kEAGC;AASD,wEAEC;AAUD,sDAsBC;
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n// See: https://github.com/urql-graphql/urql/blob/ad0276ae616b2b2f2cd01a527b4217ae35c3fa2d/packages/next-urql/src/htmlescape.ts#L10\n// License: https://github.com/urql-graphql/urql/blob/ad0276ae616b2b2f2cd01a527b4217ae35c3fa2d/LICENSE\n\n// This utility is based on https://github.com/zertosh/htmlescape\n// License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE\n\nconst UNSAFE_CHARACTERS_REGEX = /[&><\\u2028\\u2029]/g;\nconst ESCAPED_CHARACTERS: { [match: string]: string } = {\n '&': '\\\\u0026',\n '>': '\\\\u003e',\n '<': '\\\\u003c',\n '\\u2028': '\\\\u2028',\n '\\u2029': '\\\\u2029',\n};\n\n/**\n * Replaces unsafe characters in a string with their escaped equivalents. This is to safely\n * embed data in an HTML context to prevent XSS.\n */\nexport function escapeUnsafeCharacters(str: string): string {\n return str.replace(UNSAFE_CHARACTERS_REGEX, (match) => ESCAPED_CHARACTERS[match] ?? match);\n}\n\nfunction escapeHtmlAttribute(value: string): string {\n return value.replace(/&/g, '&').replace(/\"/g, '"');\n}\n\n/**\n * Returns a newline-separated `<link rel=\"preload\">` and `<link rel=\"stylesheet\">` pair for each\n * CSS href.\n *\n * Used by both `renderStaticContent()` and `serializeHtml()` to inject CSS bundles into the HTML\n * document's `<body>` element.\n */\nexport function createInjectedCssAsString(hrefs: string[]): string {\n return hrefs\n .flatMap((href) => {\n const safeHref = escapeHtmlAttribute(href);\n return [\n `<link rel=\"preload\" href=\"${safeHref}\" as=\"style\">`,\n `<link rel=\"stylesheet\" href=\"${safeHref}\">`,\n ];\n })\n .join('\\n');\n}\n\n/**\n * Returns newline-separated `<script defer>` HTML strings for each JavaScript source URL.\n *\n * Used by both `renderStaticContent()` and `serializeHtml()` to inject JavaScript bundles into the\n * HTML document's `<body>` element.\n */\nexport function createInjectedScriptsAsString(srcs: string[]): string {\n return srcs.map((src) => `<script src=\"${escapeHtmlAttribute(src)}\" defer></script>`).join('\\n');\n}\n\n/**\n * Returns a `<link rel=\"icon\" />` HTML string for the given favicon href.\n *\n * Used by the SPA export path, which splices into a pre-rendered template instead of a React\n * tree. Output must stay byte-equivalent to `createFaviconAsNode` (rendered to static markup)\n * so both rendering paths agree on the tag shape.\n */\nexport function createFaviconAsString(href: string): string {\n return `<link rel=\"icon\" href=\"${escapeHtmlAttribute(href)}\"/>`;\n}\n\n/**\n * Returns the string content of the hydration flag script, which sets the\n * `__EXPO_ROUTER_HYDRATE__` global flag to `true`.\n *\n * @see {@link getHydrationFlagScriptAsString} for the full `<script>` tag wrapper.\n */\nexport function getHydrationFlagScriptContents(): string {\n return `globalThis.__EXPO_ROUTER_HYDRATE__=true;`;\n}\n\n/**\n * Returns a module script that sets the `__EXPO_ROUTER_HYDRATE__` global flag, which tells the\n * client-side Expo Router entrypoint to hydrate the server-rendered markup instead of performing\n * a full client render.\n *\n * @see packages/expo/src/launch/registerRootComponent.tsx\n */\nexport function getHydrationFlagScriptAsString(): string {\n return `<script type=\"module\">${getHydrationFlagScriptContents()}</script>`;\n}\n\n/**\n * Returns the string content of the loader data script, which sets\n * `globalThis.__EXPO_ROUTER_LOADER_DATA__` to the given data using double-serialized JSON.\n *\n * @see {@link createLoaderDataScriptAsString} for the full `<script>` tag wrapper.\n */\nexport function getLoaderDataScriptContents(data: Record<string, unknown>): string {\n const safeJson = escapeUnsafeCharacters(JSON.stringify(data));\n return `globalThis.__EXPO_ROUTER_LOADER_DATA__ = JSON.parse(${JSON.stringify(safeJson)});`;\n}\n\n/**\n * Returns a synchronous inline `<script>` that sets `globalThis.__EXPO_ROUTER_LOADER_DATA__`\n * with the given data, safely embedded as JSON.\n *\n * Uses double-serialization so the client can fast-parse via native `JSON.parse()`.\n * @see https://v8.dev/blog/cost-of-javascript-2019#json\n */\nexport function createLoaderDataScriptAsString(data: Record<string, unknown>): string {\n return `<script id=\"expo-router-data\">${getLoaderDataScriptContents(data)}</script>`;\n}\n\nconst HELMET_HEAD_KEYS = ['title', 'priority', 'meta', 'link', 'script', 'style'] as const;\n\n/**\n * Extracts head tags and document attributes from a `react-helmet-async` helmet instance.\n *\n * `<head>` keys are serialized in document order: title, priority, meta, link, script, style.\n * Returns empty strings when `helmet` is `null`/`undefined`.\n */\nexport function serializeHelmetToHtml(helmet: any): {\n headTags: string;\n htmlAttributes: string;\n bodyAttributes: string;\n} {\n if (!helmet) {\n return { headTags: '', htmlAttributes: '', bodyAttributes: '' };\n }\n\n const headParts: string[] = [];\n for (const key of HELMET_HEAD_KEYS) {\n const result = helmet[key]?.toString();\n if (result) {\n headParts.push(result);\n }\n }\n\n return {\n headTags: headParts.join(''),\n htmlAttributes: helmet.htmlAttributes?.toString() ?? '',\n bodyAttributes: helmet.bodyAttributes?.toString() ?? '',\n };\n}\n"]}
|
package/build/utils/react.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ type CreateNodeResult = {
|
|
|
5
5
|
bodyNodes?: ReactNode[];
|
|
6
6
|
};
|
|
7
7
|
export declare function createInjectedCssAsNodes(hrefs: string[]): CreateNodeResult;
|
|
8
|
+
export declare function createInjectedExternalCssAsNodes(externalCss?: {
|
|
9
|
+
href: string;
|
|
10
|
+
media?: string;
|
|
11
|
+
}[]): CreateNodeResult;
|
|
8
12
|
export declare function createInjectedInlineCssAsNodes(inlineCss?: {
|
|
9
13
|
source: string;
|
|
10
14
|
hmrId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/utils/react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,KAAK,gBAAgB,GAAG;IACtB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAO1E;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAO,GACnD,gBAAgB,CAUlB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAO5E;AAED,wBAAgB,oBAAoB,CAAC,EACnC,OAAc,EACd,UAAU,GACX,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5C,GAAG,MAAM,CAYT;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAE3D;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,4BAA4B,EAAE,GAC1C,SAAS,EAAE,CAyBb"}
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/utils/react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,KAAK,gBAAgB,GAAG;IACtB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAO1E;AAED,wBAAgB,gCAAgC,CAC9C,WAAW,GAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAO,GACnD,gBAAgB,CAWlB;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,GAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAO,GACnD,gBAAgB,CAUlB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAO5E;AAED,wBAAgB,oBAAoB,CAAC,EACnC,OAAc,EACd,UAAU,GACX,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5C,GAAG,MAAM,CAYT;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAE3D;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,4BAA4B,EAAE,GAC1C,SAAS,EAAE,CAyBb"}
|
package/build/utils/react.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createInjectedCssAsNodes = createInjectedCssAsNodes;
|
|
4
|
+
exports.createInjectedExternalCssAsNodes = createInjectedExternalCssAsNodes;
|
|
4
5
|
exports.createInjectedInlineCssAsNodes = createInjectedInlineCssAsNodes;
|
|
5
6
|
exports.createInjectedScriptAsNodes = createInjectedScriptAsNodes;
|
|
6
7
|
exports.getBootstrapContents = getBootstrapContents;
|
|
@@ -16,6 +17,11 @@ function createInjectedCssAsNodes(hrefs) {
|
|
|
16
17
|
]),
|
|
17
18
|
};
|
|
18
19
|
}
|
|
20
|
+
function createInjectedExternalCssAsNodes(externalCss = []) {
|
|
21
|
+
return {
|
|
22
|
+
headNodes: externalCss.map(({ href, media }) => ((0, jsx_runtime_1.jsx)("link", { rel: "stylesheet", href: href, media: media }, `css-external-${href}-${media ?? ''}`))),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
19
25
|
function createInjectedInlineCssAsNodes(inlineCss = []) {
|
|
20
26
|
return {
|
|
21
27
|
headNodes: inlineCss.map(({ source, hmrId }, index) => ((0, jsx_runtime_1.jsx)("style", { "data-expo-css-hmr": hmrId, dangerouslySetInnerHTML: { __html: source } }, hmrId ? `inline-css-${hmrId}` : `inline-css-${index}`))),
|
package/build/utils/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/utils/react.tsx"],"names":[],"mappings":";;AAUA,4DAOC;AAED,wEAYC;AAED,kEAOC;AAED,oDAkBC;AAED,kDAEC;AAED,gEA2BC;;
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/utils/react.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ServerFontResourceDescriptor } from 'expo-font';\nimport { type ReactNode } from 'react';\n\nimport { getHydrationFlagScriptContents, getLoaderDataScriptContents } from './html';\n\ntype CreateNodeResult = {\n headNodes?: ReactNode[];\n bodyNodes?: ReactNode[];\n};\n\nexport function createInjectedCssAsNodes(hrefs: string[]): CreateNodeResult {\n return {\n headNodes: hrefs.flatMap((href) => [\n <link key={`css-preload-${href}`} rel=\"preload\" href={href} as=\"style\" />,\n <link key={`css-stylesheet-${href}`} rel=\"stylesheet\" href={href} />,\n ]),\n };\n}\n\nexport function createInjectedExternalCssAsNodes(\n externalCss: { href: string; media?: string }[] = []\n): CreateNodeResult {\n return {\n headNodes: externalCss.map(({ href, media }) => (\n <link\n key={`css-external-${href}-${media ?? ''}`}\n rel=\"stylesheet\"\n href={href}\n media={media}\n />\n )),\n };\n}\n\nexport function createInjectedInlineCssAsNodes(\n inlineCss: { source: string; hmrId?: string }[] = []\n): CreateNodeResult {\n return {\n headNodes: inlineCss.map(({ source, hmrId }, index) => (\n <style\n key={hmrId ? `inline-css-${hmrId}` : `inline-css-${index}`}\n data-expo-css-hmr={hmrId}\n dangerouslySetInnerHTML={{ __html: source }}\n />\n )),\n };\n}\n\nexport function createInjectedScriptAsNodes(srcs: string[]): CreateNodeResult {\n return {\n headNodes: srcs.map((src) => (\n <link key={`script-preload-${src}`} rel=\"preload\" href={src} as=\"script\" />\n )),\n bodyNodes: srcs.map((src) => <script key={`script-src-${src}`} defer src={src} />),\n };\n}\n\nexport function getBootstrapContents({\n hydrate = true,\n loadedData,\n}: {\n hydrate: boolean;\n loadedData: Record<string, unknown> | null;\n}): string {\n const parts = [];\n\n if (hydrate) {\n parts.push(getHydrationFlagScriptContents());\n }\n\n if (loadedData) {\n parts.push(getLoaderDataScriptContents(loadedData));\n }\n\n return parts.join('\\n');\n}\n\nexport function createFaviconAsNode(href: string): ReactNode {\n return <link key=\"favicon\" rel=\"icon\" href={href} />;\n}\n\nexport function createInjectedFontsAsNodes(\n descriptors: ServerFontResourceDescriptor[]\n): ReactNode[] {\n return descriptors.map((descriptor) => {\n switch (descriptor.type) {\n case 'style':\n return (\n <style\n key={`font-style-${descriptor.id}`}\n id={descriptor.id}\n dangerouslySetInnerHTML={{ __html: descriptor.css }}\n />\n );\n case 'link':\n return (\n <link\n key={`font-link-${descriptor.href}`}\n rel={descriptor.rel}\n href={descriptor.href}\n as={descriptor.as}\n crossOrigin={descriptor.crossOrigin}\n />\n );\n default:\n return null;\n }\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/router-server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "57.0.0",
|
|
4
4
|
"description": "Expo Router is a file-based router for React Native and web applications.",
|
|
5
5
|
"author": "650 Industries, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
"expo"
|
|
25
25
|
],
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@expo/metro-runtime": "^
|
|
27
|
+
"@expo/metro-runtime": "^57.0.0",
|
|
28
28
|
"expo": "*",
|
|
29
|
-
"expo-constants": "^
|
|
30
|
-
"expo-font": "^
|
|
29
|
+
"expo-constants": "^57.0.0",
|
|
30
|
+
"expo-font": "^57.0.0",
|
|
31
31
|
"expo-router": "*",
|
|
32
|
-
"expo-server": "^
|
|
32
|
+
"expo-server": "^57.0.0",
|
|
33
33
|
"react": "*",
|
|
34
34
|
"react-dom": "*",
|
|
35
35
|
"react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1"
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"react-server-dom-webpack": "~19.0.6",
|
|
60
60
|
"tsd": "^0.33.0",
|
|
61
61
|
"tsd-lite": "^0.9.0",
|
|
62
|
-
"expo": "
|
|
63
|
-
"expo-router": "
|
|
62
|
+
"expo": "57.0.0-preview.0",
|
|
63
|
+
"expo-router": "57.0.0"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"debug": "^4.3.4"
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"publishConfig": {
|
|
69
69
|
"access": "public"
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "e3eb896c5fdcd89e0cded98ff4e35c9db12cc9c0",
|
|
72
72
|
"scripts": {
|
|
73
73
|
"build": "expo-module build",
|
|
74
74
|
"clean": "expo-module clean",
|