vike-react 0.6.2 → 0.6.4

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/README.md CHANGED
@@ -1 +1,5 @@
1
+ <!-- WARNING: keep links absolute in this file so they work on NPM too -->
2
+
3
+ [![npm version](https://img.shields.io/npm/v/vike-react)](https://www.npmjs.com/package/vike-react)
4
+
1
5
  See [Vike Docs > vike-react](https://vike.dev/vike-react).
package/dist/config.d.ts CHANGED
@@ -96,6 +96,7 @@ declare const config: {
96
96
  env: {
97
97
  server: true;
98
98
  };
99
+ cumulative: true;
99
100
  };
100
101
  streamIsRequired: {
101
102
  env: {
package/dist/config.js CHANGED
@@ -76,6 +76,7 @@ const config = {
76
76
  },
77
77
  stream: {
78
78
  env: { server: true },
79
+ cumulative: true,
79
80
  },
80
81
  streamIsRequired: {
81
82
  env: { server: true },
@@ -3,5 +3,4 @@ declare const _default: {
3
3
  };
4
4
  export default _default;
5
5
  import React from 'react';
6
- import './Loading.css';
7
6
  declare function LoadingComponent(): React.JSX.Element;
@@ -2,7 +2,11 @@ export default {
2
2
  component: LoadingComponent,
3
3
  };
4
4
  import React from 'react';
5
- import './Loading.css';
5
+ /* We can't import it here: https://github.com/vikejs/vike/issues/2460
6
+ * - We import it inside onRenderClient.js instead.
7
+ * - We'll be able to do it if Vite + Rolldown always transpiles the server-side.
8
+ import './Loading.css'
9
+ */
6
10
  function LoadingComponent() {
7
11
  return (React.createElement("div", { style: {
8
12
  width: '100%',
@@ -1,3 +1,4 @@
1
1
  export { onRenderClient };
2
2
  import type { OnRenderClientAsync } from 'vike/types';
3
+ import './Loading.css';
3
4
  declare const onRenderClient: OnRenderClientAsync;
@@ -6,6 +6,7 @@ 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 './Loading.css'; // See comment inside Loading.tsx
9
10
  let root;
10
11
  const onRenderClient = async (pageContext) => {
11
12
  pageContext._headAlreadySet = pageContext.isHydration;
@@ -12,6 +12,9 @@ import { getTagAttributesString } from '../utils/getTagAttributesString.js';
12
12
  import { assert } from '../utils/assert.js';
13
13
  import { callCumulativeHooks } from '../utils/callCumulativeHooks.js';
14
14
  import { resolveReactOptions } from './resolveReactOptions.js';
15
+ import { isNotNullish } from '../utils/isNotNullish.js';
16
+ import { isObject } from '../utils/isObject.js';
17
+ import { isType } from '../utils/isType.js';
15
18
  addEcosystemStamp();
16
19
  const onRenderHtml = async (pageContext) => {
17
20
  await renderPageToHtml(pageContext);
@@ -52,19 +55,32 @@ async function renderPageToHtml(pageContext) {
52
55
  await callCumulativeHooks(pageContext.config.onBeforeRenderHtml, pageContext);
53
56
  const { renderToStringOptions } = resolveReactOptions(pageContext);
54
57
  if (pageContext.page) {
55
- const { stream, streamIsRequired } = pageContext.config;
56
- if (!stream && !streamIsRequired) {
58
+ const streamSetting = resolveStreamSetting(pageContext);
59
+ if (!streamSetting.enable && !streamSetting.require) {
57
60
  const pageHtmlString = renderToString(pageContext.page, renderToStringOptions);
58
61
  pageContext.pageHtmlString = pageHtmlString;
59
62
  }
60
63
  else {
61
64
  const pageHtmlStream = await renderToStream(pageContext.page, {
62
- webStream: typeof stream === 'string' ? stream === 'web' : undefined,
65
+ webStream: !streamSetting.type
66
+ ? /* Let react-streaming decide which stream type to use.
67
+ false
68
+ */
69
+ undefined
70
+ : streamSetting.type === 'web',
63
71
  userAgent: pageContext.headers?.['user-agent'] ||
64
72
  // TODO/eventually: remove old way of acccessing the User Agent header.
65
73
  // @ts-ignore
66
74
  pageContext.userAgent,
67
- disable: stream === false ? true : undefined,
75
+ disable:
76
+ // +stream.require is true => default +stream.enable is true
77
+ // +stream.require is false => default +stream.enable is false
78
+ streamSetting.enable === false
79
+ ? true
80
+ : /* Don't override disabling when bot is detected.
81
+ false,
82
+ */
83
+ undefined,
68
84
  });
69
85
  pageContext.pageHtmlStream = pageHtmlStream;
70
86
  }
@@ -164,3 +180,45 @@ async function getBodyHtmlBoundary(pageContext) {
164
180
  const bodyHtmlEnd = dangerouslySkipEscape((await callCumulativeHooks(pageContext.config.bodyHtmlEnd, pageContext)).join(''));
165
181
  return { bodyHtmlBegin, bodyHtmlEnd };
166
182
  }
183
+ function resolveStreamSetting(pageContext) {
184
+ const { stream,
185
+ // TODO/eventually: remove +streamIsRequired
186
+ // - Let's remove it once following last vike-react-{query,apollo} releases using +streamIsRequired can be considered old versions.
187
+ // - Last vike-react-query version that uses +streamIsRequired was 0.1.3
188
+ // - Last vike-react-apollo version that uses +streamIsRequired was 0.1.1
189
+ // - New vike-react-{query,apollo} versions using +stream.require instead +streamIsRequired were released on May 29th 2025
190
+ // - Remove it in a minor release (AFAICT it's only used by vike-react-{query,apollo})
191
+ // - Add a `Negligible Breaking Change`
192
+ streamIsRequired, } = pageContext.config;
193
+ const streamSetting = {
194
+ type: null,
195
+ enable: null,
196
+ require: streamIsRequired ?? false,
197
+ };
198
+ stream
199
+ ?.reverse()
200
+ .filter(isNotNullish)
201
+ .forEach((setting) => {
202
+ if (typeof setting === 'boolean') {
203
+ streamSetting.enable = setting;
204
+ return;
205
+ }
206
+ if (typeof setting === 'string') {
207
+ streamSetting.type = setting;
208
+ streamSetting.enable = true;
209
+ return;
210
+ }
211
+ if (isObject(setting)) {
212
+ if (setting.enable !== null)
213
+ streamSetting.enable = setting.enable ?? true;
214
+ if (setting.require !== undefined)
215
+ streamSetting.require = setting.require;
216
+ if (setting.type !== undefined)
217
+ streamSetting.type = setting.type;
218
+ return;
219
+ }
220
+ isType(setting);
221
+ throw new Error(`Unexpected +stream value ${setting}`);
222
+ });
223
+ return streamSetting;
224
+ }
@@ -13,7 +13,7 @@ function ssrEffect({ configDefinedAt, configValue }) {
13
13
  return {
14
14
  meta: {
15
15
  Page: { env },
16
- /* We don't do this to enable wraping <Head> with <Wrapper>
16
+ /* We don't do this to enable wrapping <Head> with <Wrapper>
17
17
  Wrapper: { env }, */
18
18
  Layout: { env },
19
19
  Loading: { env },
@@ -1,4 +1,4 @@
1
- import type { ImportString, PageContextServer, PageContext, PageContextClient } from 'vike/types';
1
+ import type { ImportString, PageContext } from 'vike/types';
2
2
  import type { TagAttributes } from '../utils/getTagAttributesString.js';
3
3
  import type { Viewport } from '../integration/onRenderHtml.js';
4
4
  import type { ConfigsCumulative } from '../hooks/useConfig/configsCumulative.js';
@@ -140,16 +140,35 @@ declare global {
140
140
  */
141
141
  ssr?: boolean;
142
142
  /**
143
- * Enable or disable HTML Streaming.
143
+ * Settings for HTML Streaming.
144
144
  *
145
145
  * https://vike.dev/stream
146
146
  */
147
- stream?: boolean | 'node' | 'web';
148
- /**
149
- * Whether the existence of the React SSR stream is required (some integrations require it).
150
- *
151
- * HTML Streaming can still be disabled: the SSR stream is awaited and converted to a string.
152
- */
147
+ stream?: boolean | 'node' | 'web' | {
148
+ /**
149
+ * Whether the HTML stream should be a Web Stream or a Node.js Stream.
150
+ *
151
+ * https://vike.dev/stream
152
+ */
153
+ type?: 'node' | 'web';
154
+ /**
155
+ * Whether Server-Side Rendering (SSR) must use a stream. (Some tool integrations require it.)
156
+ *
157
+ * Setting +stream to `{ require: true, disable: true }` means that SSR is done using a stream but, from the user's perspective, HTML Streaming is disabled: the stream is awaited, converted to a string, and the full HTML is sent at once.
158
+ *
159
+ * https://vike.dev/stream
160
+ */
161
+ require?: boolean;
162
+ /**
163
+ * Setting +stream to `{ enable: null }` is the same as not setting +stream at all.
164
+ *
165
+ * Useful for changing stream settings without enabling streaming. For example, Vike extensions can set +stream to `{ enable: null, type: 'web' }` to change the default stream type without enabling streaming.
166
+ *
167
+ * https://vike.dev/stream
168
+ */
169
+ enable?: boolean | null;
170
+ };
171
+ /** @deprecated Set +stream.require instead */
153
172
  streamIsRequired?: boolean;
154
173
  /**
155
174
  * Whether to use `<StrictMode>`.
@@ -176,13 +195,13 @@ declare global {
176
195
  *
177
196
  * https://vike.dev/onBeforeRenderClient
178
197
  */
179
- onBeforeRenderClient?: (pageContext: PageContextClient) => void;
198
+ onBeforeRenderClient?: ((pageContext: PageContextClient) => void) | ImportString;
180
199
  /**
181
200
  * Client-side hook called after the page is rendered.
182
201
  *
183
202
  * https://vike.dev/onAfterRenderClient
184
203
  */
185
- onAfterRenderClient?: (pageContext: PageContextClient) => void;
204
+ onAfterRenderClient?: ((pageContext: PageContextClient) => void) | ImportString;
186
205
  /**
187
206
  * Define loading animations.
188
207
  *
@@ -209,6 +228,7 @@ declare global {
209
228
  onBeforeRenderClient?: Function[];
210
229
  onAfterRenderClient?: Function[];
211
230
  react?: Exclude<Config['react'], ImportString>[];
231
+ stream?: Exclude<Config['stream'], ImportString>[];
212
232
  }
213
233
  }
214
234
  }
@@ -0,0 +1,2 @@
1
+ export declare function isNullish(val: unknown): val is null | undefined;
2
+ export declare function isNotNullish<T>(p: T | null | undefined): p is T;
@@ -0,0 +1,7 @@
1
+ export function isNullish(val) {
2
+ return val === null || val === undefined;
3
+ }
4
+ // someArray.filter(isNotNullish)
5
+ export function isNotNullish(p) {
6
+ return !isNullish(p);
7
+ }
@@ -0,0 +1 @@
1
+ export declare function isObject(value: unknown): value is Record<string, unknown>;
@@ -0,0 +1,3 @@
1
+ export function isObject(value) {
2
+ return typeof value === 'object' && value !== null;
3
+ }
@@ -0,0 +1 @@
1
+ export declare function isType<Type>(_: Type): void;
@@ -0,0 +1 @@
1
+ export function isType(_) { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike-react",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "repository": "https://github.com/vikejs/vike-react",
5
5
  "type": "module",
6
6
  "exports": {
@@ -44,7 +44,7 @@
44
44
  "react-dom": "^19.0.0",
45
45
  "rimraf": "^5.0.5",
46
46
  "typescript": "^5.7.3",
47
- "vike": "^0.4.223",
47
+ "vike": "^0.4.230",
48
48
  "vite": "^6.2.5"
49
49
  },
50
50
  "typesVersions": {