vike-react 0.6.5 → 0.6.7
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/dist/components/ClientOnly.js +1 -1
- package/dist/config.js +1 -1
- package/dist/hooks/usePageContext.d.ts +2 -2
- package/dist/hooks/usePageContext.js +3 -3
- package/dist/index.js +1 -1
- package/dist/integration/Loading.d.ts +2 -2
- package/dist/integration/Loading.js +23 -17
- package/dist/integration/getPageElement.d.ts +1 -0
- package/dist/integration/getPageElement.js +10 -6
- package/dist/integration/onRenderClient.d.ts +3 -3
- package/dist/integration/onRenderClient.js +71 -15
- package/dist/integration/onRenderHtml.d.ts +4 -2
- package/dist/integration/onRenderHtml.js +6 -6
- package/dist/utils/getGlobalObject.d.ts +1 -1
- package/package.json +10 -11
- package/dist/integration/Loading.css +0 -10
@@ -1,7 +1,7 @@
|
|
1
1
|
export { ClientOnly };
|
2
2
|
import React, { lazy, useEffect, useState, startTransition } from 'react';
|
3
3
|
function ClientOnly({ load, children, fallback, deps = [], }) {
|
4
|
-
//
|
4
|
+
// TO-DO/next-major: remove this file/export
|
5
5
|
console.warn('[vike-react][warning] <ClientOnly> is deprecated: use clientOnly() instead https://vike.dev/clientOnly');
|
6
6
|
const [Component, setComponent] = useState(null);
|
7
7
|
useEffect(() => {
|
package/dist/config.js
CHANGED
@@ -101,7 +101,7 @@ const config = {
|
|
101
101
|
cumulative: true,
|
102
102
|
env: { client: true, server: true },
|
103
103
|
},
|
104
|
-
//
|
104
|
+
// TO-DO/next-major: move to +react.js > strictMode ?
|
105
105
|
reactStrictMode: {
|
106
106
|
env: { client: true, server: true },
|
107
107
|
},
|
@@ -1,8 +1,8 @@
|
|
1
1
|
export { usePageContext };
|
2
|
-
export {
|
2
|
+
export { VikeReactProviderPageContext };
|
3
3
|
import React from 'react';
|
4
4
|
import type { PageContext } from 'vike/types';
|
5
|
-
declare function
|
5
|
+
declare function VikeReactProviderPageContext({ pageContext, children, }: {
|
6
6
|
pageContext: PageContext;
|
7
7
|
children: React.ReactNode;
|
8
8
|
}): React.JSX.Element;
|
@@ -1,11 +1,11 @@
|
|
1
1
|
export { usePageContext };
|
2
|
-
export {
|
2
|
+
export { VikeReactProviderPageContext };
|
3
3
|
import React, { useContext } from 'react';
|
4
4
|
import { getGlobalObject } from '../utils/getGlobalObject.js';
|
5
|
-
const globalObject = getGlobalObject('
|
5
|
+
const globalObject = getGlobalObject('usePageContext.tsx', {
|
6
6
|
reactContext: React.createContext(undefined),
|
7
7
|
});
|
8
|
-
function
|
8
|
+
function VikeReactProviderPageContext({ pageContext, children, }) {
|
9
9
|
const { reactContext } = globalObject;
|
10
10
|
return React.createElement(reactContext.Provider, { value: pageContext }, children);
|
11
11
|
}
|
package/dist/index.js
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
//
|
1
|
+
// TO-DO/next-major: remove this file/export
|
2
2
|
console.warn("[vike-react][warning][deprecation] Replace `import vikeReact from 'vike-react'` with `import vikeReact from 'vike-react/config'` (typically in your /pages/+config.js)");
|
3
3
|
export { default } from './config.js';
|
@@ -1,6 +1,6 @@
|
|
1
1
|
declare const _default: {
|
2
|
-
component: typeof
|
2
|
+
component: typeof VikeReactLoadingComponent;
|
3
3
|
};
|
4
4
|
export default _default;
|
5
5
|
import React from 'react';
|
6
|
-
declare function
|
6
|
+
declare function VikeReactLoadingComponent(): React.JSX.Element;
|
@@ -1,21 +1,27 @@
|
|
1
1
|
export default {
|
2
|
-
component:
|
2
|
+
component: VikeReactLoadingComponent,
|
3
3
|
};
|
4
4
|
import React from 'react';
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
5
|
+
function VikeReactLoadingComponent() {
|
6
|
+
return (React.createElement(React.Fragment, null,
|
7
|
+
React.createElement("div", { style: {
|
8
|
+
width: '100%',
|
9
|
+
height: '100%',
|
10
|
+
maxHeight: '100%',
|
11
|
+
background: 'linear-gradient(110deg, #ececec 8%, #f5f5f5 18%, #ececec 33%)',
|
12
|
+
borderRadius: '5px',
|
13
|
+
backgroundSize: '200% 100%',
|
14
|
+
animation: '1.3s vike-react-loading linear infinite',
|
15
|
+
aspectRatio: '2.5/1',
|
16
|
+
} }),
|
17
|
+
React.createElement("style", { href: "vike-react-loading",
|
18
|
+
// https://react.dev/reference/react-dom/components/style#special-rendering-behavior
|
19
|
+
// https://github.com/vikejs/vike-react/pull/184#discussion_r2348075206
|
20
|
+
precedence: "default" }, `
|
21
|
+
@keyframes vike-react-loading {
|
22
|
+
to {
|
23
|
+
background-position-x: -200%;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
`)));
|
21
27
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
export { getPageElement };
|
2
2
|
import React, { Suspense, useEffect } from 'react';
|
3
|
-
import {
|
3
|
+
import { VikeReactProviderPageContext } from '../hooks/usePageContext.js';
|
4
4
|
function getPageElement(pageContext) {
|
5
5
|
const { Page, config: { Loading }, } = pageContext;
|
6
6
|
let page = Page ? React.createElement(Page, null) : null;
|
@@ -20,16 +20,20 @@ function getPageElement(pageContext) {
|
|
20
20
|
page = React.createElement(Wrap, null, page);
|
21
21
|
page = addSuspense(page);
|
22
22
|
});
|
23
|
-
page = React.createElement(
|
23
|
+
page = React.createElement(VikeReactProviderPageContext, { pageContext: pageContext }, page);
|
24
24
|
let renderPromiseResolve;
|
25
|
-
let
|
26
|
-
|
25
|
+
let renderPromiseReject;
|
26
|
+
let renderPromise = new Promise((resolve, reject) => {
|
27
|
+
renderPromiseResolve = resolve;
|
28
|
+
renderPromiseReject = reject;
|
29
|
+
});
|
30
|
+
page = (React.createElement(VikeReactProviderRenderPromise, { renderPromiseResolve: renderPromiseResolve }, page));
|
27
31
|
if (pageContext.config.reactStrictMode !== false) {
|
28
32
|
page = React.createElement(React.StrictMode, null, page);
|
29
33
|
}
|
30
|
-
return { page, renderPromise };
|
34
|
+
return { page, renderPromise, renderPromiseReject };
|
31
35
|
}
|
32
|
-
function
|
36
|
+
function VikeReactProviderRenderPromise({ children, renderPromiseResolve, }) {
|
33
37
|
useEffect(renderPromiseResolve);
|
34
38
|
return children;
|
35
39
|
}
|
@@ -1,4 +1,4 @@
|
|
1
1
|
export { onRenderClient };
|
2
|
-
import type {
|
3
|
-
import '
|
4
|
-
declare
|
2
|
+
import type { PageContextClient } from 'vike/types';
|
3
|
+
import type { PageContextInternal } from '../types/PageContext.js';
|
4
|
+
declare function onRenderClient(pageContext: PageContextClient & PageContextInternal): Promise<void>;
|
@@ -6,36 +6,53 @@ import { getPageElement } from './getPageElement.js';
|
|
6
6
|
import { callCumulativeHooks } from '../utils/callCumulativeHooks.js';
|
7
7
|
import { applyHeadSettings } from './applyHeadSettings.js';
|
8
8
|
import { resolveReactOptions } from './resolveReactOptions.js';
|
9
|
-
import
|
10
|
-
|
11
|
-
const
|
9
|
+
import { getGlobalObject } from '../utils/getGlobalObject.js';
|
10
|
+
import { isObject } from '../utils/isObject.js';
|
11
|
+
const globalObject = getGlobalObject('onRenderClient.tsx', {});
|
12
|
+
async function onRenderClient(pageContext) {
|
12
13
|
pageContext._headAlreadySet = pageContext.isHydration;
|
13
14
|
// Use case:
|
14
15
|
// - Store hydration https://github.com/vikejs/vike-react/issues/110
|
15
16
|
await callCumulativeHooks(pageContext.config.onBeforeRenderClient, pageContext);
|
16
|
-
const { page, renderPromise } = getPageElement(pageContext);
|
17
|
+
const { page, renderPromise, renderPromiseReject } = getPageElement(pageContext);
|
17
18
|
pageContext.page = page;
|
18
|
-
//
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
// Local callback for current page
|
20
|
+
globalObject.onUncaughtErrorLocal = (err) => {
|
21
|
+
renderPromiseReject(err);
|
22
|
+
};
|
22
23
|
const container = document.getElementById('root');
|
23
24
|
const { hydrateRootOptions, createRootOptions } = resolveReactOptions(pageContext);
|
24
25
|
if (pageContext.isHydration &&
|
25
26
|
// Whether the page was [Server-Side Rendered](https://vike.dev/ssr).
|
26
27
|
container.innerHTML !== '') {
|
27
28
|
// First render while using SSR, i.e. [hydration](https://vike.dev/hydration)
|
28
|
-
root = ReactDOM.hydrateRoot(container, page,
|
29
|
+
globalObject.root = ReactDOM.hydrateRoot(container, page, {
|
30
|
+
...hydrateRootOptions,
|
31
|
+
// onUncaughtError is the right callback: https://gist.github.com/brillout/b9516e83a7a4517f4dbd0ef50e9dd716
|
32
|
+
onUncaughtError(...args) {
|
33
|
+
onUncaughtErrorGlobal.call(this, args, hydrateRootOptions);
|
34
|
+
},
|
35
|
+
});
|
29
36
|
}
|
30
37
|
else {
|
31
|
-
if (!root) {
|
38
|
+
if (!globalObject.root) {
|
32
39
|
// First render without SSR
|
33
|
-
root = ReactDOM.createRoot(container,
|
40
|
+
globalObject.root = ReactDOM.createRoot(container, {
|
41
|
+
...createRootOptions,
|
42
|
+
onUncaughtError(...args) {
|
43
|
+
onUncaughtErrorGlobal.call(this, args, createRootOptions);
|
44
|
+
},
|
45
|
+
});
|
34
46
|
}
|
35
|
-
root.render(page);
|
47
|
+
globalObject.root.render(page);
|
48
|
+
}
|
49
|
+
pageContext.root = globalObject.root;
|
50
|
+
try {
|
51
|
+
await renderPromise;
|
52
|
+
}
|
53
|
+
finally {
|
54
|
+
delete globalObject.onUncaughtErrorLocal;
|
36
55
|
}
|
37
|
-
pageContext.root = root;
|
38
|
-
await renderPromise;
|
39
56
|
if (!pageContext.isHydration) {
|
40
57
|
pageContext._headAlreadySet = true;
|
41
58
|
applyHead(pageContext);
|
@@ -44,9 +61,48 @@ const onRenderClient = async (pageContext) => {
|
|
44
61
|
// - Custom user settings: https://vike.dev/head-tags#custom-settings
|
45
62
|
// - Testing tools: https://github.com/vikejs/vike-react/issues/95
|
46
63
|
await callCumulativeHooks(pageContext.config.onAfterRenderClient, pageContext);
|
47
|
-
}
|
64
|
+
}
|
48
65
|
function applyHead(pageContext) {
|
49
66
|
const title = getHeadSetting('title', pageContext);
|
50
67
|
const lang = getHeadSetting('lang', pageContext);
|
51
68
|
applyHeadSettings(title, lang);
|
52
69
|
}
|
70
|
+
// Global callback, attached once upon hydration.
|
71
|
+
function onUncaughtErrorGlobal(args, userOptions) {
|
72
|
+
const [errorOriginal, errorInfo] = args;
|
73
|
+
const errorEnhanced = getErrorEnhanced(errorOriginal, errorInfo);
|
74
|
+
console.error(errorEnhanced);
|
75
|
+
// Used by Vike:
|
76
|
+
// https://github.com/vikejs/vike/blob/8ce2cbda756892f0ff083256291515b5a45fe319/packages/vike/client/runtime-client-routing/renderPageClientSide.ts#L838-L844
|
77
|
+
if (isObject(errorEnhanced))
|
78
|
+
errorEnhanced.isAlreadyLogged = true;
|
79
|
+
globalObject.onUncaughtErrorLocal?.(errorEnhanced);
|
80
|
+
userOptions?.onUncaughtError?.call(this, errorEnhanced, errorInfo);
|
81
|
+
}
|
82
|
+
function getErrorEnhanced(errorOriginal, errorInfo) {
|
83
|
+
if (!errorInfo?.componentStack || !isObject(errorOriginal))
|
84
|
+
return errorOriginal;
|
85
|
+
const errorOiginalStackLines = String(errorOriginal.stack).split('\n');
|
86
|
+
const cutoff = errorOiginalStackLines.findIndex((l) => l.includes('node_modules') && l.includes('react'));
|
87
|
+
if (cutoff === -1)
|
88
|
+
return errorOriginal;
|
89
|
+
const stackEnhanced = [
|
90
|
+
...errorOiginalStackLines.slice(0, cutoff),
|
91
|
+
...errorInfo.componentStack.split('\n').filter(Boolean),
|
92
|
+
...errorOiginalStackLines.slice(cutoff),
|
93
|
+
].join('\n');
|
94
|
+
const errorEnhanced = structuredClone(errorOriginal);
|
95
|
+
errorEnhanced.stack = stackEnhanced;
|
96
|
+
// https://gist.github.com/brillout/066293a687ab7cf695e62ad867bc6a9c
|
97
|
+
Object.defineProperty(errorEnhanced, 'getOriginalError', {
|
98
|
+
value: () => errorOriginal,
|
99
|
+
enumerable: true,
|
100
|
+
});
|
101
|
+
/* Not needed. Let's skip this to save client-side KBs.
|
102
|
+
Object.defineProperty(errorOriginal, 'getEnhancedError', {
|
103
|
+
value: () => errorEnhanced,
|
104
|
+
enumerable: true,
|
105
|
+
})
|
106
|
+
//*/
|
107
|
+
return errorEnhanced;
|
108
|
+
}
|
@@ -1,6 +1,8 @@
|
|
1
1
|
export { onRenderHtml };
|
2
2
|
import { renderToStream } from 'react-streaming/server';
|
3
|
-
import
|
4
|
-
|
3
|
+
import { escapeInject } from 'vike/server';
|
4
|
+
import type { PageContextServer } from 'vike/types';
|
5
|
+
import type { PageContextInternal } from '../types/PageContext.js';
|
6
|
+
declare function onRenderHtml(pageContext: PageContextServer & PageContextInternal): Promise<ReturnType<typeof escapeInject>>;
|
5
7
|
export type PageHtmlStream = Awaited<ReturnType<typeof renderToStream>>;
|
6
8
|
export type Viewport = 'responsive' | number | null;
|
@@ -4,7 +4,7 @@ import React from 'react';
|
|
4
4
|
import { renderToString, renderToStaticMarkup } from 'react-dom/server';
|
5
5
|
import { renderToStream } from 'react-streaming/server';
|
6
6
|
import { dangerouslySkipEscape, escapeInject } from 'vike/server';
|
7
|
-
import {
|
7
|
+
import { VikeReactProviderPageContext } from '../hooks/usePageContext.js';
|
8
8
|
import { getHeadSetting } from './getHeadSetting.js';
|
9
9
|
import { getPageElement } from './getPageElement.js';
|
10
10
|
import { isReactElement } from '../utils/isReactElement.js';
|
@@ -16,7 +16,7 @@ import { isNotNullish } from '../utils/isNotNullish.js';
|
|
16
16
|
import { isObject } from '../utils/isObject.js';
|
17
17
|
import { isType } from '../utils/isType.js';
|
18
18
|
addEcosystemStamp();
|
19
|
-
|
19
|
+
async function onRenderHtml(pageContext) {
|
20
20
|
await renderPageToHtml(pageContext);
|
21
21
|
const headHtml = getHeadHtml(pageContext);
|
22
22
|
const { bodyHtmlBegin, bodyHtmlEnd } = await getBodyHtmlBoundary(pageContext);
|
@@ -47,7 +47,7 @@ const onRenderHtml = async (pageContext) => {
|
|
47
47
|
${bodyHtmlEnd}
|
48
48
|
</body>
|
49
49
|
</html>`;
|
50
|
-
}
|
50
|
+
}
|
51
51
|
async function renderPageToHtml(pageContext) {
|
52
52
|
if (pageContext.Page)
|
53
53
|
pageContext.page = getPageElement(pageContext).page;
|
@@ -69,7 +69,7 @@ async function renderPageToHtml(pageContext) {
|
|
69
69
|
undefined
|
70
70
|
: streamSetting.type === 'web',
|
71
71
|
userAgent: pageContext.headers?.['user-agent'] ||
|
72
|
-
//
|
72
|
+
// TO-DO/eventually: remove old way of acccessing the User Agent header.
|
73
73
|
// @ts-ignore
|
74
74
|
pageContext.userAgent,
|
75
75
|
disable:
|
@@ -128,7 +128,7 @@ function getHeadElementHtml(Head, pageContext) {
|
|
128
128
|
headElement = Head;
|
129
129
|
}
|
130
130
|
else {
|
131
|
-
headElement = (React.createElement(
|
131
|
+
headElement = (React.createElement(VikeReactProviderPageContext, { pageContext: pageContext },
|
132
132
|
React.createElement(Head, null)));
|
133
133
|
}
|
134
134
|
if (pageContext.config.reactStrictMode !== false) {
|
@@ -182,7 +182,7 @@ async function getBodyHtmlBoundary(pageContext) {
|
|
182
182
|
}
|
183
183
|
function resolveStreamSetting(pageContext) {
|
184
184
|
const { stream,
|
185
|
-
//
|
185
|
+
// TO-DO/eventually: remove +streamIsRequired
|
186
186
|
// - Let's remove it once following last vike-react-{query,apollo} releases using +streamIsRequired can be considered old versions.
|
187
187
|
// - Last vike-react-query version that uses +streamIsRequired was 0.1.3
|
188
188
|
// - Last vike-react-apollo version that uses +streamIsRequired was 0.1.1
|
@@ -1 +1 @@
|
|
1
|
-
export declare function getGlobalObject<T extends Record<string, unknown> = never>(key: `${string}.ts`, defaultValue: T): T;
|
1
|
+
export declare function getGlobalObject<T extends Record<string, unknown> = never>(key: `${string}.ts` | `${string}.tsx`, defaultValue: T): T;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "vike-react",
|
3
|
-
"version": "0.6.
|
3
|
+
"version": "0.6.7",
|
4
4
|
"repository": "https://github.com/vikejs/vike-react",
|
5
5
|
"type": "module",
|
6
6
|
"exports": {
|
@@ -27,7 +27,7 @@
|
|
27
27
|
"./__internal/integration/Loading": "./dist/integration/Loading.js"
|
28
28
|
},
|
29
29
|
"dependencies": {
|
30
|
-
"react-streaming": "^0.4.
|
30
|
+
"react-streaming": "^0.4.5"
|
31
31
|
},
|
32
32
|
"peerDependencies": {
|
33
33
|
"react": ">=19",
|
@@ -38,14 +38,14 @@
|
|
38
38
|
"@biomejs/biome": "^1.9.4",
|
39
39
|
"@brillout/release-me": "^0.4.8",
|
40
40
|
"@types/node": "^24.0.8",
|
41
|
-
"@types/react": "^19.
|
42
|
-
"@types/react-dom": "^19.
|
43
|
-
"react": "^19.
|
44
|
-
"react-dom": "^19.
|
41
|
+
"@types/react": "^19.1.13",
|
42
|
+
"@types/react-dom": "^19.1.9",
|
43
|
+
"react": "^19.1.1",
|
44
|
+
"react-dom": "^19.1.1",
|
45
45
|
"rimraf": "^5.0.5",
|
46
|
-
"typescript": "^5.
|
47
|
-
"vike": "^0.4.
|
48
|
-
"vite": "^
|
46
|
+
"typescript": "^5.9.2",
|
47
|
+
"vike": "^0.4.241",
|
48
|
+
"vite": "^7.1.7"
|
49
49
|
},
|
50
50
|
"typesVersions": {
|
51
51
|
"*": {
|
@@ -95,8 +95,7 @@
|
|
95
95
|
],
|
96
96
|
"scripts": {
|
97
97
|
"dev": "tsc --watch",
|
98
|
-
"build": "rimraf dist/ && tsc
|
99
|
-
"build:css": "cp src/integration/Loading.css dist/integration/Loading.css",
|
98
|
+
"build": "rimraf dist/ && tsc",
|
100
99
|
"release": "release-me patch",
|
101
100
|
"release:minor": "release-me minor",
|
102
101
|
"release:commit": "release-me commit"
|
@@ -1,10 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
This CSS is loaded for all vike-react users, even if they don't use the <Loading> component because it's imported not directly but over depednency injection, see:
|
3
|
-
https://github.com/vikejs/vike/discussions/2340
|
4
|
-
*/
|
5
|
-
|
6
|
-
@keyframes vike-react-shine {
|
7
|
-
to {
|
8
|
-
background-position-x: -200%;
|
9
|
-
}
|
10
|
-
}
|