vike-react 0.5.2 → 0.5.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,8 +1,3 @@
1
1
  export { Config };
2
2
  import type { ConfigFromHook } from '../../types/Config.js';
3
- /**
4
- * Set configurations inside React components.
5
- *
6
- * https://vike.dev/useConfig
7
- */
8
3
  declare function Config(props: ConfigFromHook): null;
@@ -1,11 +1,5 @@
1
1
  export { Config };
2
- // Same as ./Config-server.ts but importing useConfig-client.js
3
2
  import { useConfig } from '../../hooks/useConfig/useConfig-client.js';
4
- /**
5
- * Set configurations inside React components.
6
- *
7
- * https://vike.dev/useConfig
8
- */
9
3
  function Config(props) {
10
4
  const config = useConfig();
11
5
  config(props);
@@ -1,5 +1,4 @@
1
1
  export { Config };
2
- // Same as ./Config-client.ts but importing useConfig-server.js
3
2
  import { useConfig } from '../../hooks/useConfig/useConfig-server.js';
4
3
  /**
5
4
  * Set configurations inside React components.
@@ -0,0 +1,2 @@
1
+ export declare const configsCumulative: readonly ["Head", "bodyAttributes", "htmlAttributes"];
2
+ export type ConfigsCumulative = (typeof configsCumulative)[number];
@@ -0,0 +1 @@
1
+ export const configsCumulative = ['Head', 'bodyAttributes', 'htmlAttributes'];
@@ -1,8 +1,3 @@
1
1
  export { useConfig };
2
2
  import type { ConfigFromHook } from '../../types/Config.js';
3
- /**
4
- * Set configurations inside React components and Vike hooks.
5
- *
6
- * https://vike.dev/useConfig
7
- */
8
3
  declare function useConfig(): (config: ConfigFromHook) => void;
@@ -1,24 +1,20 @@
1
1
  export { useConfig };
2
2
  import { usePageContext } from '../usePageContext.js';
3
3
  import { getPageContext } from 'vike/getPageContext';
4
- /**
5
- * Set configurations inside React components and Vike hooks.
6
- *
7
- * https://vike.dev/useConfig
8
- */
4
+ import { applyHeadSettings } from '../../renderer/applyHeadSettings.js';
9
5
  function useConfig() {
10
6
  // Vike hook
11
7
  let pageContext = getPageContext();
12
8
  if (pageContext)
13
9
  return (config) => setPageContextConfigFromHook(config, pageContext);
14
- // React component
10
+ // Component
15
11
  pageContext = usePageContext();
16
12
  return (config) => {
17
13
  if (!('_headAlreadySet' in pageContext)) {
18
14
  setPageContextConfigFromHook(config, pageContext);
19
15
  }
20
16
  else {
21
- apply(config);
17
+ applyHead(config);
22
18
  }
23
19
  };
24
20
  }
@@ -26,8 +22,7 @@ function setPageContextConfigFromHook(config, pageContext) {
26
22
  pageContext._configFromHook ?? (pageContext._configFromHook = {});
27
23
  Object.assign(pageContext._configFromHook, config);
28
24
  }
29
- function apply(config) {
30
- const { title } = config;
31
- if (title)
32
- window.document.title = title;
25
+ function applyHead(config) {
26
+ const { title, lang } = config;
27
+ applyHeadSettings(title, lang);
33
28
  }
@@ -1,10 +1,8 @@
1
1
  export { useConfig };
2
- export type ConfigFromHookCumulative = (typeof configsCumulative)[number];
3
2
  import type { ConfigFromHook } from '../../types/Config.js';
4
3
  /**
5
- * Set configurations inside React components and Vike hooks.
4
+ * Set configurations inside components and Vike hooks.
6
5
  *
7
6
  * https://vike.dev/useConfig
8
7
  */
9
8
  declare function useConfig(): (config: ConfigFromHook) => void;
10
- declare const configsCumulative: readonly ["Head", "bodyAttributes", "htmlAttributes"];
@@ -4,8 +4,9 @@ import { getPageContext } from 'vike/getPageContext';
4
4
  import { useStream } from 'react-streaming';
5
5
  import { objectKeys } from '../../utils/objectKeys.js';
6
6
  import { includes } from '../../utils/includes.js';
7
+ import { configsCumulative } from './configsCumulative.js';
7
8
  /**
8
- * Set configurations inside React components and Vike hooks.
9
+ * Set configurations inside components and Vike hooks.
9
10
  *
10
11
  * https://vike.dev/useConfig
11
12
  */
@@ -14,7 +15,7 @@ function useConfig() {
14
15
  let pageContext = getPageContext();
15
16
  if (pageContext)
16
17
  return (config) => setPageContextConfigFromHook(config, pageContext);
17
- // React component
18
+ // Component
18
19
  pageContext = usePageContext();
19
20
  const stream = useStream();
20
21
  return (config) => {
@@ -28,7 +29,6 @@ function useConfig() {
28
29
  };
29
30
  }
30
31
  const configsClientSide = ['title'];
31
- const configsCumulative = ['Head', 'bodyAttributes', 'htmlAttributes'];
32
32
  function setPageContextConfigFromHook(config, pageContext) {
33
33
  pageContext._configFromHook ?? (pageContext._configFromHook = {});
34
34
  objectKeys(config).forEach((configName) => {
@@ -0,0 +1,3 @@
1
+ export { applyHeadSettings };
2
+ type Value = string | null | undefined;
3
+ declare function applyHeadSettings(title: Value, lang: Value): void;
@@ -0,0 +1,11 @@
1
+ export { applyHeadSettings };
2
+ // - We skip if `undefined` as we shouldn't remove values set by the Head setting.
3
+ // - Setting a default prevents the previous value to be leaked: upon client-side navigation, the value set by the previous page won't be removed if the next page doesn't override it.
4
+ // - Most of the time, the user sets a default himself (i.e. a value defined at /pages/+config.js)
5
+ // - If he doesn't have a default then he can use `null` to opt into Vike's defaults
6
+ function applyHeadSettings(title, lang) {
7
+ if (title !== undefined)
8
+ document.title = title || '';
9
+ if (lang !== undefined)
10
+ document.documentElement.lang = lang || 'en';
11
+ }
@@ -2,5 +2,4 @@ export { getHeadSetting };
2
2
  import type { PageContext } from 'vike/types';
3
3
  import type { PageContextInternal } from '../types/PageContext.js';
4
4
  import type { ConfigFromHookResolved } from '../types/Config.js';
5
- type HeadSetting = Exclude<keyof ConfigFromHookResolved, 'Head'>;
6
- declare function getHeadSetting<T>(headSetting: HeadSetting, pageContext: PageContext & PageContextInternal): undefined | T;
5
+ declare function getHeadSetting<T>(configName: keyof ConfigFromHookResolved, pageContext: PageContext & PageContextInternal): undefined | T;
@@ -1,18 +1,24 @@
1
1
  export { getHeadSetting };
2
2
  import { isCallable } from '../utils/isCallable.js';
3
- function getHeadSetting(headSetting, pageContext) {
3
+ import { configsCumulative } from '../hooks/useConfig/configsCumulative.js';
4
+ import { includes } from '../utils/includes.js';
5
+ // We use `any` instead of doing proper validation in order to save KBs sent to the client-side.
6
+ function getHeadSetting(configName, pageContext) {
4
7
  // Set by useConfig()
5
- {
6
- const val = pageContext._configFromHook?.[headSetting];
7
- if (val !== undefined)
8
- return val;
9
- }
8
+ const valFromUseConfig = pageContext._configFromHook?.[configName];
10
9
  // Set by +configName.js
11
- const val = pageContext.config[headSetting];
12
- if (isCallable(val)) {
13
- return val(pageContext);
10
+ const valFromConfig = pageContext.config[configName];
11
+ const getCallable = (val) => (isCallable(val) ? val(pageContext) : val);
12
+ if (!includes(configsCumulative, configName)) {
13
+ if (valFromUseConfig !== undefined)
14
+ return valFromUseConfig;
15
+ return getCallable(valFromConfig);
14
16
  }
15
17
  else {
16
- return val;
18
+ return [
19
+ //
20
+ ...(valFromConfig ?? []).map(getCallable),
21
+ ...(valFromUseConfig ?? [])
22
+ ];
17
23
  }
18
24
  }
@@ -5,8 +5,10 @@ import { getHeadSetting } from './getHeadSetting.js';
5
5
  import { getPageElement } from './getPageElement.js';
6
6
  import './styles.css';
7
7
  import { callCumulativeHooks } from '../utils/callCumulativeHooks.js';
8
+ import { applyHeadSettings } from './applyHeadSettings.js';
8
9
  let root;
9
10
  const onRenderClient = async (pageContext) => {
11
+ pageContext._headAlreadySet = pageContext.isHydration;
10
12
  // Use case:
11
13
  // - Store hydration https://github.com/vikejs/vike-react/issues/110
12
14
  await callCumulativeHooks(pageContext.config.onBeforeRenderClient, pageContext);
@@ -38,24 +40,16 @@ const onRenderClient = async (pageContext) => {
38
40
  }
39
41
  pageContext.root = root;
40
42
  if (!pageContext.isHydration) {
41
- // E.g. document.title
42
- updateDocument(pageContext);
43
+ pageContext._headAlreadySet = true;
44
+ applyHead(pageContext);
43
45
  }
44
46
  // Use cases:
45
47
  // - Custom user settings: https://vike.dev/head-tags#custom-settings
46
48
  // - Testing tools: https://github.com/vikejs/vike-react/issues/95
47
49
  await callCumulativeHooks(pageContext.config.onAfterRenderClient, pageContext);
48
50
  };
49
- function updateDocument(pageContext) {
50
- pageContext._headAlreadySet = true;
51
+ function applyHead(pageContext) {
51
52
  const title = getHeadSetting('title', pageContext);
52
53
  const lang = getHeadSetting('lang', pageContext);
53
- // - We skip if `undefined` as we shouldn't remove values set by the Head setting.
54
- // - Setting a default prevents the previous value to be leaked: upon client-side navigation, the value set by the previous page won't be removed if the next page doesn't override it.
55
- // - Most of the time, the user sets a default himself (i.e. a value defined at /pages/+config.js)
56
- // - If he doesn't have a default then he can use `null` to opt into Vike's defaults
57
- if (title !== undefined)
58
- document.title = title || '';
59
- if (lang !== undefined)
60
- document.documentElement.lang = lang || 'en';
54
+ applyHeadSettings(title, lang);
61
55
  }
@@ -14,6 +14,8 @@ const onRenderHtml = async (pageContext) => {
14
14
  const pageHtml = await getPageHtml(pageContext);
15
15
  const headHtml = getHeadHtml(pageContext);
16
16
  const { htmlAttributesString, bodyAttributesString } = getTagAttributes(pageContext);
17
+ // Not needed on the client-side, thus we remove it to save KBs sent to the client
18
+ delete pageContext._configFromHook;
17
19
  return escapeInject `<!DOCTYPE html>
18
20
  <html${dangerouslySkipEscape(htmlAttributesString)}>
19
21
  <head>
@@ -74,8 +76,6 @@ function getHeadHtml(pageContext) {
74
76
  .filter((Head) => Head !== null && Head !== undefined)
75
77
  .map((Head) => getHeadElementHtml(Head, pageContext))
76
78
  .join('\n'));
77
- // Not needed on the client-side, thus we remove it to save KBs sent to the client
78
- delete pageContext._configFromHook;
79
79
  const headHtml = escapeInject `
80
80
  ${titleTags}
81
81
  ${viewportTag}
@@ -1,7 +1,7 @@
1
1
  import type { ImportString, PageContextClient, PageContext as PageContext_, PageContextServer } from 'vike/types';
2
2
  import type { TagAttributes } from '../utils/getTagAttributesString.js';
3
3
  import type { Viewport } from '../renderer/onRenderHtml.js';
4
- import type { ConfigFromHookCumulative } from '../hooks/useConfig/useConfig-server.js';
4
+ import type { ConfigsCumulative } from '../hooks/useConfig/configsCumulative.js';
5
5
  declare global {
6
6
  namespace Vike {
7
7
  interface Config {
@@ -195,5 +195,5 @@ type PickWithoutGetter<T, K extends keyof T> = {
195
195
  [P in K]: Exclude<T[P], Function>;
196
196
  };
197
197
  export type ConfigFromHook = PickWithoutGetter<Vike.Config, 'Head' | 'title' | 'description' | 'image' | 'favicon' | 'lang' | 'viewport' | 'bodyAttributes' | 'htmlAttributes'>;
198
- export type ConfigFromHookResolved = Omit<ConfigFromHook, ConfigFromHookCumulative> & Pick<Vike.ConfigResolved, ConfigFromHookCumulative>;
198
+ export type ConfigFromHookResolved = Omit<ConfigFromHook, ConfigsCumulative> & Pick<Vike.ConfigResolved, ConfigsCumulative>;
199
199
  export {};
@@ -16,5 +16,5 @@ declare global {
16
16
  }
17
17
  export type PageContextInternal = {
18
18
  _configFromHook?: ConfigFromHookResolved;
19
- _headAlreadySet?: true;
19
+ _headAlreadySet?: boolean;
20
20
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike-react",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",