vike-react 0.3.1 → 0.3.3

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.
@@ -1,7 +1,7 @@
1
1
  import type { ConfigEffect } from 'vike/types';
2
2
  declare const _default: {
3
- onRenderHtml: "import:vike-react/renderer/onRenderHtml";
4
- onRenderClient: "import:vike-react/renderer/onRenderClient";
3
+ onRenderHtml: "import:vike-react/renderer/onRenderHtml:onRenderHtml";
4
+ onRenderClient: "import:vike-react/renderer/onRenderClient:onRenderClient";
5
5
  passToClient: string[];
6
6
  clientRouting: true;
7
7
  hydrationCanBeAborted: true;
@@ -19,8 +19,14 @@ const toggleSsrRelatedConfig = ({ configDefinedAt, configValue }) => {
19
19
  };
20
20
  };
21
21
  export default {
22
- onRenderHtml: 'import:vike-react/renderer/onRenderHtml',
23
- onRenderClient: 'import:vike-react/renderer/onRenderClient',
22
+ onRenderHtml: 'import:vike-react/renderer/onRenderHtml:onRenderHtml',
23
+ onRenderClient: 'import:vike-react/renderer/onRenderClient:onRenderClient',
24
+ // A page can define an onBeforeRender() hook to be run on the server, which
25
+ // can fetch data and return it as additional page context. Typically it will
26
+ // return the page's root React component's props and additional data that can
27
+ // be used by the renderers.
28
+ // It is a cumulative config option, so a web app using vike-react can extend
29
+ // this list.
24
30
  passToClient: ['pageProps', 'title'],
25
31
  clientRouting: true,
26
32
  hydrationCanBeAborted: true,
@@ -3,6 +3,9 @@ import React from 'react';
3
3
  import { PageContextProvider } from './PageContextProvider.js';
4
4
  function getPageElement(pageContext) {
5
5
  var _a;
6
+ if (!pageContext.Page) {
7
+ return React.createElement(React.Fragment, null);
8
+ }
6
9
  const Layout = (_a = pageContext.config.Layout) !== null && _a !== void 0 ? _a : PassThrough;
7
10
  const Wrapper =
8
11
  /* Should we implement this? Enabling users to defined a wrapper that is used across all layouts.
@@ -13,8 +16,7 @@ function getPageElement(pageContext) {
13
16
  const page = (React.createElement(React.StrictMode, null,
14
17
  React.createElement(PageContextProvider, { pageContext: pageContext },
15
18
  React.createElement(Wrapper, null,
16
- React.createElement(Layout, null,
17
- React.createElement(Page, { ...pageProps }))))));
19
+ React.createElement(Layout, null, Page ? React.createElement(Page, { ...pageProps }) : null)))));
18
20
  return page;
19
21
  }
20
22
  function PassThrough({ children }) {
@@ -1,6 +1,7 @@
1
1
  export { getTitle };
2
- import type { ConfigEntries } from 'vike/types';
3
- declare function getTitle(pageContext: {
4
- title?: unknown;
5
- configEntries: ConfigEntries;
6
- }): null | string;
2
+ import type { PageContext } from 'vike/types';
3
+ /**
4
+ * Get the page's title if defined, either from the additional data fetched by
5
+ * the page's onBeforeRender() hook or from the config.
6
+ */
7
+ declare function getTitle(pageContext: PageContext): null | string;
@@ -1,33 +1,32 @@
1
1
  export { getTitle };
2
2
  import { isCallable } from './utils/isCallable.js';
3
+ /**
4
+ * Get the page's title if defined, either from the additional data fetched by
5
+ * the page's onBeforeRender() hook or from the config.
6
+ */
3
7
  function getTitle(pageContext) {
4
8
  var _a;
5
- if (pageContext.title) {
6
- if (typeof pageContext.title !== 'string') {
7
- throw new Error('pageContext.title should be a string');
8
- }
9
+ if (pageContext.title !== undefined) {
9
10
  return pageContext.title;
10
11
  }
11
- else {
12
- const titleConfig = (_a = pageContext.configEntries.title) === null || _a === void 0 ? void 0 : _a[0];
13
- if (!titleConfig) {
14
- return null;
15
- }
16
- const title = titleConfig.configValue;
17
- if (typeof title === 'string') {
18
- return title;
19
- }
20
- if (!title) {
21
- return null;
22
- }
23
- const { configDefinedAt } = titleConfig;
24
- if (isCallable(title)) {
25
- const val = title(pageContext);
26
- if (typeof val !== 'string') {
27
- throw new Error(configDefinedAt + ' should return a string');
28
- }
29
- return val;
12
+ const titleConfig = (_a = pageContext.configEntries.title) === null || _a === void 0 ? void 0 : _a[0];
13
+ if (!titleConfig) {
14
+ return null;
15
+ }
16
+ const title = titleConfig.configValue;
17
+ if (typeof title === 'string') {
18
+ return title;
19
+ }
20
+ if (!title) {
21
+ return null;
22
+ }
23
+ const { configDefinedAt } = titleConfig;
24
+ if (isCallable(title)) {
25
+ const val = title(pageContext);
26
+ if (typeof val !== 'string') {
27
+ throw new Error(configDefinedAt + ' should return a string');
30
28
  }
31
- throw new Error(configDefinedAt + ' should be a string or a function returning a string');
29
+ return val;
32
30
  }
31
+ throw new Error(configDefinedAt + ' should be a string or a function returning a string');
33
32
  }
@@ -1,3 +1,3 @@
1
- export default onRenderClient;
2
- import type { PageContextClient } from 'vike/types';
3
- declare function onRenderClient(pageContext: PageContextClient): Promise<void>;
1
+ export { onRenderClient };
2
+ import type { OnRenderClientAsync } from 'vike/types';
3
+ declare const onRenderClient: OnRenderClientAsync;
@@ -1,22 +1,30 @@
1
- export default onRenderClient;
1
+ // https://vike.dev/onRenderClient
2
+ export { onRenderClient };
2
3
  import ReactDOM from 'react-dom/client';
3
4
  import { getTitle } from './getTitle.js';
4
5
  import { getPageElement } from './getPageElement.js';
5
6
  let root;
6
- async function onRenderClient(pageContext) {
7
+ const onRenderClient = async (pageContext) => {
7
8
  const page = getPageElement(pageContext);
8
9
  const container = document.getElementById('page-view');
9
10
  if (container.innerHTML !== '' && pageContext.isHydration) {
11
+ // Hydration
10
12
  root = ReactDOM.hydrateRoot(container, page);
11
13
  }
12
14
  else {
13
15
  if (!root) {
16
+ // First rendering
14
17
  root = ReactDOM.createRoot(container);
15
18
  }
19
+ else {
20
+ // Client routing
21
+ // See https://vike.dev/server-routing-vs-client-routing
22
+ // Get the page's `title` config value, which may be different from the
23
+ // previous page. It can even be null, in which case we should unset the
24
+ // document title.
25
+ const title = getTitle(pageContext);
26
+ document.title = title || '';
27
+ }
16
28
  root.render(page);
17
29
  }
18
- const title = getTitle(pageContext);
19
- if (title !== null) {
20
- document.title = title;
21
- }
22
- }
30
+ };
@@ -1,5 +1,3 @@
1
- export default onRenderHtml;
2
- import type { PageContext } from 'vike/types';
3
- declare function onRenderHtml(pageContext: PageContext): Promise<{
4
- documentHtml: import("vike/dist/esm/node/runtime/html/renderHtml.js").TemplateWrapped;
5
- }>;
1
+ export { onRenderHtml };
2
+ import type { OnRenderHtmlAsync } from 'vike/types';
3
+ declare const onRenderHtml: OnRenderHtmlAsync;
@@ -1,46 +1,41 @@
1
- export default onRenderHtml;
2
- import { renderToString } from 'react-dom/server';
3
- import { escapeInject, dangerouslySkipEscape, version } from 'vike/server';
1
+ // https://vike.dev/onRenderHtml
2
+ export { onRenderHtml };
3
+ import { renderToStream } from 'react-streaming/server';
4
+ import { escapeInject, version } from 'vike/server';
4
5
  import { getTitle } from './getTitle.js';
5
6
  import { getPageElement } from './getPageElement.js';
6
7
  import { PageContextProvider } from './PageContextProvider.js';
7
8
  import React from 'react';
8
9
  checkVikeVersion();
9
- async function onRenderHtml(pageContext) {
10
- let pageHtml = '';
11
- if (!!pageContext.Page) {
12
- const page = getPageElement(pageContext);
13
- pageHtml = renderToString(page);
14
- }
10
+ const onRenderHtml = async (pageContext) => {
11
+ const lang = pageContext.config.lang || 'en';
12
+ const { favicon } = pageContext.config;
13
+ const faviconTag = !favicon ? '' : React.createElement("link", { rel: "icon", href: favicon });
15
14
  const title = getTitle(pageContext);
16
- const titleTag = !title ? '' : escapeInject `<title>${title}</title>`;
15
+ const titleTag = !title ? '' : React.createElement("title", null, title);
17
16
  const { description } = pageContext.config;
18
- const descriptionTag = !description ? '' : escapeInject `<meta name="description" content="${description}" />`;
19
- const { favicon } = pageContext.config;
20
- const faviconTag = !favicon ? '' : escapeInject `<link rel="icon" href="${favicon}" />`;
17
+ const descriptionTag = !description ? '' : React.createElement("meta", { name: "description", content: description });
21
18
  const Head = pageContext.config.Head || (() => React.createElement(React.Fragment, null));
22
19
  const head = (React.createElement(React.StrictMode, null,
23
20
  React.createElement(PageContextProvider, { pageContext: pageContext },
24
21
  React.createElement(Head, null))));
25
- const headHtml = renderToString(head);
26
- const lang = pageContext.config.lang || 'en';
22
+ const page = getPageElement(pageContext);
23
+ const stream = await renderToStream(React.createElement(React.Fragment, null,
24
+ React.createElement("head", null,
25
+ React.createElement("meta", { charSet: "UTF-8" }),
26
+ faviconTag,
27
+ titleTag,
28
+ descriptionTag,
29
+ head),
30
+ React.createElement("body", null,
31
+ React.createElement("div", { id: "page-view" }, page))), { userAgent: pageContext.userAgent });
27
32
  const documentHtml = escapeInject `<!DOCTYPE html>
28
- <html lang='${lang}'>
29
- <head>
30
- <meta charset="UTF-8" />
31
- ${faviconTag}
32
- ${titleTag}
33
- ${descriptionTag}
34
- ${dangerouslySkipEscape(headHtml)}
35
- </head>
36
- <body>
37
- <div id="page-view">${dangerouslySkipEscape(pageHtml)}</div>
38
- </body>
39
- </html>`;
40
- return {
41
- documentHtml
42
- };
43
- }
33
+ <html lang='${lang}'>
34
+ ${stream}
35
+ <!-- built with https://github.com/vikejs/vike-react -->
36
+ </html>`;
37
+ return documentHtml;
38
+ };
44
39
  function checkVikeVersion() {
45
40
  if (version) {
46
41
  const versionParts = version.split('.').map((s) => parseInt(s, 10));
@@ -4,8 +4,12 @@ type Component = (props: any) => ReactElement;
4
4
  declare global {
5
5
  namespace Vike {
6
6
  interface PageContext {
7
- Page: Component;
8
- pageProps: Record<string, unknown>;
7
+ Page?: Component;
8
+ /** Properties of the page's root React component. */
9
+ pageProps?: Record<string, unknown>;
10
+ /** &lt;title>${title}&lt;/title> - has precedence over the config */
11
+ title?: string;
12
+ userAgent?: string;
9
13
  }
10
14
  }
11
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike-react",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "main": "./dist/renderer/+config.js",
6
6
  "types": "./dist/renderer/+config.d.ts",
@@ -23,7 +23,7 @@
23
23
  "vite": "^4.3.8"
24
24
  },
25
25
  "devDependencies": {
26
- "@brillout/release-me": "^0.1.7",
26
+ "@brillout/release-me": "^0.1.9",
27
27
  "@types/node": "^18.17.18",
28
28
  "@types/react": "^18.2.22",
29
29
  "@types/react-dom": "^18.2.7",
@@ -32,6 +32,9 @@
32
32
  "typescript": "^5.2.2",
33
33
  "vike": "^0.4.147"
34
34
  },
35
+ "dependencies": {
36
+ "react-streaming": "^0.3.16"
37
+ },
35
38
  "typesVersions": {
36
39
  "*": {
37
40
  ".": [