vike-solid 0.2.8 → 0.3.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/README.md CHANGED
@@ -5,7 +5,4 @@
5
5
 
6
6
  SolidJS integration for [Vike](https://github.com/vikejs/vike).
7
7
 
8
- > [!NOTE]
9
- > For integrations with React and Vue, see the other [`vike-*` packages](https://vike.dev/vike-packages).
10
-
11
8
  See [examples/](https://github.com/vikejs/vike-solid/tree/main/examples).
package/dist/+config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // Depending on the value of `config.meta.ssr`, set other config options' `env`
2
2
  // accordingly.
3
- // See https://vike.dev/meta#modify-existing-configurations
3
+ // See https://vike.dev/meta#:~:text=Modifying%20the%20environment%20of%20existing%20hooks
4
4
  const toggleSsrRelatedConfig = ({
5
5
  configDefinedAt,
6
6
  configValue
@@ -26,19 +26,14 @@ const toggleSsrRelatedConfig = ({
26
26
  };
27
27
  };
28
28
  var _config = {
29
+ // https://vike.dev/onRenderHtml
29
30
  onRenderHtml: "import:vike-solid/renderer/onRenderHtml:onRenderHtml",
31
+ // https://vike.dev/onRenderClient
30
32
  onRenderClient: "import:vike-solid/renderer/onRenderClient:onRenderClient",
31
- // TODO/next-major-release: remove pageProps (i.e. tell users to use data() instead of onBeforeRender() to fetch data)
32
- // TODO/next-major-release: remove support for setting title over onBeforeRender()
33
- // A page can define an onBeforeRender() hook to be run on the server, which
34
- // can fetch data and return it as additional page context. Typically it will
35
- // return the page's root Solid component's props and additional data that can
36
- // be used by the renderers.
37
- // It is a cumulative config option, so a web app using vike-solid can extend
38
- // this list.
39
- passToClient: ["pageProps", "title"],
33
+ // https://vike.dev/clientRouting
40
34
  clientRouting: true,
41
35
  hydrationCanBeAborted: true,
36
+ // https://vike.dev/meta
42
37
  meta: {
43
38
  Head: {
44
39
  env: {
@@ -57,19 +52,16 @@ var _config = {
57
52
  client: true
58
53
  }
59
54
  },
60
- description: {
61
- env: {
62
- server: true
63
- }
64
- },
65
55
  favicon: {
66
56
  env: {
67
- server: true
57
+ server: true,
58
+ client: true
68
59
  }
69
60
  },
70
61
  lang: {
71
62
  env: {
72
- server: true
63
+ server: true,
64
+ client: true
73
65
  }
74
66
  },
75
67
  ssr: {
@@ -87,5 +79,6 @@ var _config = {
87
79
  };
88
80
 
89
81
  // We purposely define the ConfigVikeSolid interface in this file: that way we ensure it's always applied whenever the user `import vikeSolid from 'vike-solid'`
82
+ // https://vike.dev/pageContext#typescript
90
83
 
91
84
  export { _config as default };
@@ -1,47 +1,27 @@
1
- import { createComponent, Dynamic, mergeProps, memo, hydrate, render } from 'solid-js/web';
1
+ import { createComponent, Dynamic, memo, hydrate, render } from 'solid-js/web';
2
2
  import { P as PageContextProvider, u as usePageContext } from './PageContextProvider-OTjP33FZ.js';
3
3
  import { createStore, reconcile } from 'solid-js/store';
4
4
  import 'solid-js';
5
5
 
6
- /**
7
- * Get the page's title if defined, either from the additional data fetched by
8
- * the page's data() and onBeforeRender() hook or from the config.
9
- */
10
- function getTitle(pageContext) {
11
- // from data() hook
12
- if (pageContext.data?.title !== undefined) {
13
- return pageContext.data.title;
14
- }
6
+ function isCallable(thing) {
7
+ return thing instanceof Function || typeof thing === 'function';
8
+ }
15
9
 
16
- // TODO/next-major-release: remove support for setting title over onBeforeRender()
17
- // from onBeforeRender() hook
18
- if (pageContext.title !== undefined) {
19
- return pageContext.title;
20
- }
21
- const titleConfig = pageContext.configEntries.title?.[0];
22
- if (!titleConfig) {
23
- return null;
24
- }
25
- const title = titleConfig.configValue;
26
- if (typeof title === "string") {
27
- return title;
28
- }
29
- if (!title) {
30
- return null;
31
- }
32
- const {
33
- configDefinedAt
34
- } = titleConfig;
35
- if (typeof title === "function") {
36
- const val = title(pageContext);
37
- if (typeof val === "string") {
38
- return val;
39
- }
40
- if (val) {
41
- throw new Error(configDefinedAt + " should return a string");
10
+ function getHeadSetting(headSetting, pageContext) {
11
+ const config = pageContext.configEntries[headSetting]?.[0];
12
+ if (!config) return undefined;
13
+ const val = config.configValue;
14
+ if (typeof val === "string") return val;
15
+ if (!val) return null;
16
+ if (isCallable(val)) {
17
+ const valStr = val(pageContext);
18
+ if (typeof valStr !== "string") {
19
+ throw new Error(config.configDefinedAt + " should return a string");
42
20
  }
21
+ return valStr;
22
+ } else {
23
+ throw new Error(config.configDefinedAt + " should be a string or a function returning a string");
43
24
  }
44
- throw new Error(configDefinedAt + " should be a string or a function returning a string");
45
25
  }
46
26
 
47
27
  function getPageElement(pageContext) {
@@ -70,12 +50,11 @@ function Layout(props) {
70
50
  }
71
51
  function Page() {
72
52
  const pageContext = usePageContext();
73
- // TODO/next-major-release: remove pageProps (i.e. tell users to use data() instead of onBeforeRender() to fetch data)
74
- return createComponent(Dynamic, mergeProps({
53
+ return createComponent(Dynamic, {
75
54
  get component() {
76
55
  return pageContext.Page;
77
56
  }
78
- }, () => pageContext.pageProps ?? {}));
57
+ });
79
58
  }
80
59
  function Passthrough(props) {
81
60
  return memo(() => props.children);
@@ -100,17 +79,37 @@ const onRenderClient = async pageContext => {
100
79
  }
101
80
  rendered = true;
102
81
  } else {
103
- // Client routing
104
- // See https://vike.dev/server-routing-vs-client-routing
82
+ // Client-side navigation
105
83
 
106
84
  setPageContext(reconcile(pageContext));
85
+ const title = getHeadSetting("title", pageContext) || "";
86
+ const lang = getHeadSetting("lang", pageContext) || "en";
87
+ const favicon = getHeadSetting("favicon", pageContext);
107
88
 
108
- // Get the page's `title` config value, which may be different from the
109
- // previous page. It can even be null, in which case we should unset the
110
- // document title.
111
- const title = getTitle(pageContext);
112
- document.title = title || "";
89
+ // We skip if the value is undefined because we shouldn't remove values set in HTML (by the Head setting).
90
+ // - This also means that previous values will leak: upon client-side navigation, the title set by the previous
91
+ // page won't be removed if the next page doesn't override it. But that's okay because usually pages always have
92
+ // a favicon and title, which means that previous values are always overridden. Also, as a workaround, the user
93
+ // can set the value to `null` to ensure that previous values are overridden.
94
+ if (title !== undefined) document.title = title;
95
+ if (lang !== undefined) document.documentElement.lang = lang;
96
+ if (favicon !== undefined) setFavicon(favicon);
113
97
  }
114
98
  };
115
99
 
100
+ // https://stackoverflow.com/questions/260857/changing-website-favicon-dynamically/260876#260876
101
+ function setFavicon(faviconUrl) {
102
+ let link = document.querySelector("link[rel~='icon']");
103
+ if (!faviconUrl) {
104
+ if (link) document.head.removeChild(link);
105
+ return;
106
+ }
107
+ if (!link) {
108
+ link = document.createElement("link");
109
+ link.rel = "icon";
110
+ document.head.appendChild(link);
111
+ }
112
+ link.href = faviconUrl;
113
+ }
114
+
116
115
  export { onRenderClient };
@@ -1,47 +1,27 @@
1
- import { createComponent, Dynamic, mergeProps, renderToString, renderToStream, generateHydrationScript } from 'solid-js/web';
1
+ import { createComponent, Dynamic, renderToString, renderToStream, generateHydrationScript } from 'solid-js/web';
2
2
  import { version, escapeInject, dangerouslySkipEscape, stampPipe } from 'vike/server';
3
3
  import { P as PageContextProvider, u as usePageContext } from './PageContextProvider-OTjP33FZ.js';
4
4
  import 'solid-js';
5
5
 
6
- /**
7
- * Get the page's title if defined, either from the additional data fetched by
8
- * the page's data() and onBeforeRender() hook or from the config.
9
- */
10
- function getTitle(pageContext) {
11
- // from data() hook
12
- if (pageContext.data?.title !== undefined) {
13
- return pageContext.data.title;
14
- }
6
+ function isCallable(thing) {
7
+ return thing instanceof Function || typeof thing === 'function';
8
+ }
15
9
 
16
- // TODO/next-major-release: remove support for setting title over onBeforeRender()
17
- // from onBeforeRender() hook
18
- if (pageContext.title !== undefined) {
19
- return pageContext.title;
20
- }
21
- const titleConfig = pageContext.configEntries.title?.[0];
22
- if (!titleConfig) {
23
- return null;
24
- }
25
- const title = titleConfig.configValue;
26
- if (typeof title === "string") {
27
- return title;
28
- }
29
- if (!title) {
30
- return null;
31
- }
32
- const {
33
- configDefinedAt
34
- } = titleConfig;
35
- if (typeof title === "function") {
36
- const val = title(pageContext);
37
- if (typeof val === "string") {
38
- return val;
39
- }
40
- if (val) {
41
- throw new Error(configDefinedAt + " should return a string");
10
+ function getHeadSetting(headSetting, pageContext) {
11
+ const config = pageContext.configEntries[headSetting]?.[0];
12
+ if (!config) return undefined;
13
+ const val = config.configValue;
14
+ if (typeof val === "string") return val;
15
+ if (!val) return null;
16
+ if (isCallable(val)) {
17
+ const valStr = val(pageContext);
18
+ if (typeof valStr !== "string") {
19
+ throw new Error(config.configDefinedAt + " should return a string");
42
20
  }
21
+ return valStr;
22
+ } else {
23
+ throw new Error(config.configDefinedAt + " should be a string or a function returning a string");
43
24
  }
44
- throw new Error(configDefinedAt + " should be a string or a function returning a string");
45
25
  }
46
26
 
47
27
  function getPageElement(pageContext) {
@@ -70,12 +50,11 @@ function Layout(props) {
70
50
  }
71
51
  function Page() {
72
52
  const pageContext = usePageContext();
73
- // TODO/next-major-release: remove pageProps (i.e. tell users to use data() instead of onBeforeRender() to fetch data)
74
- return createComponent(Dynamic, mergeProps({
53
+ return createComponent(Dynamic, {
75
54
  get component() {
76
55
  return pageContext.Page;
77
56
  }
78
- }, () => pageContext.pageProps ?? {}));
57
+ });
79
58
  }
80
59
  function Passthrough(props) {
81
60
  return props.children;
@@ -83,15 +62,11 @@ function Passthrough(props) {
83
62
 
84
63
  checkVikeVersion();
85
64
  const onRenderHtml = async pageContext => {
86
- const {
87
- stream,
88
- favicon,
89
- description
90
- } = pageContext.config;
91
- const title = getTitle(pageContext);
65
+ const title = getHeadSetting("title", pageContext);
66
+ const favicon = getHeadSetting("favicon", pageContext);
67
+ const lang = getHeadSetting("lang", pageContext) || "en";
92
68
  const titleTag = !title ? "" : escapeInject`<title>${title}</title>`;
93
- const faviconTag = !favicon ? '' : escapeInject`<link rel="icon" href="${favicon}" />`;
94
- const descriptionTag = !description ? '' : escapeInject`<meta name="description" content="${description}" />`;
69
+ const faviconTag = !favicon ? "" : escapeInject`<link rel="icon" href="${favicon}" />`;
95
70
  const Head = pageContext.config.Head || (() => []);
96
71
  const headHtml = renderToString(() => createComponent(PageContextProvider, {
97
72
  pageContext: pageContext,
@@ -99,24 +74,22 @@ const onRenderHtml = async pageContext => {
99
74
  return createComponent(Head, {});
100
75
  }
101
76
  }));
102
- let pageView = '';
77
+ let pageView = "";
103
78
  if (!!pageContext.Page) {
104
- if (!stream) {
79
+ if (!pageContext.config.stream) {
105
80
  pageView = dangerouslySkipEscape(renderToString(() => getPageElement(pageContext)));
106
81
  } else {
107
82
  pageView = renderToStream(() => getPageElement(pageContext)).pipe;
108
83
  stampPipe(pageView, "node-stream");
109
84
  }
110
85
  }
111
- const lang = pageContext.config.lang || "en";
112
86
  const documentHtml = escapeInject`<!DOCTYPE html>
113
87
  <html lang='${lang}'>
114
88
  <head>
115
89
  <meta charset="UTF-8" />
116
90
  ${titleTag}
117
- ${faviconTag}
118
- ${descriptionTag}
119
91
  ${dangerouslySkipEscape(headHtml)}
92
+ ${faviconTag}
120
93
  ${dangerouslySkipEscape(generateHydrationScript())}
121
94
  </head>
122
95
  <body>
@@ -128,12 +101,12 @@ const onRenderHtml = async pageContext => {
128
101
  };
129
102
  function checkVikeVersion() {
130
103
  if (version) {
131
- const versionParts = version.split('.').map(s => parseInt(s, 10));
104
+ const versionParts = version.split(".").map(s => parseInt(s, 10));
132
105
  if (versionParts[0] > 0) return;
133
106
  if (versionParts[1] > 4) return;
134
107
  if (versionParts[2] >= 147) return;
135
108
  }
136
- throw new Error('Update Vike to its latest version (or vike@0.4.147 and any version above)');
109
+ throw new Error("Update Vike to 0.4.147 or above");
137
110
  }
138
111
 
139
112
  export { onRenderHtml };
@@ -1,7 +1,7 @@
1
1
  import { createComponent, Dynamic, ssr, ssrHydrationKey } from 'solid-js/web';
2
2
  import { createSignal, createEffect, Suspense, lazy } from 'solid-js';
3
3
 
4
- const _tmpl$ = ["<p", ">Error loading component.</p>"];
4
+ var _tmpl$ = ["<p", ">Error loading component.</p>"];
5
5
  function ClientOnlyError() {
6
6
  return ssr(_tmpl$, ssrHydrationKey());
7
7
  }
@@ -1,20 +1,11 @@
1
1
  import { PageContext, ConfigEffect } from 'vike/types';
2
2
  import { JSX, Component } from 'solid-js';
3
3
 
4
- type Page = (pageProps: PageProps) => JSX.Element;
5
- type PageProps = Record<string, unknown>;
4
+ type Page = () => JSX.Element;
6
5
  declare global {
7
6
  namespace Vike {
8
7
  interface PageContext {
9
8
  Page?: Page;
10
- /** Properties of the page's root Solid component - e.g. set by onBeforeRender() hook */
11
- pageProps?: Record<string, unknown>;
12
- /** &lt;title>${title}&lt;/title> - set by onBeforeRender() hook, has precedence over the config */
13
- title?: string;
14
- data?: {
15
- /** &lt;title>${title}&lt;/title> - set by data() hook, has precedence over the onBeforeRender() hook */
16
- title?: string;
17
- };
18
9
  }
19
10
  }
20
11
  }
@@ -22,7 +13,6 @@ declare global {
22
13
  declare const _default: {
23
14
  onRenderHtml: "import:vike-solid/renderer/onRenderHtml:onRenderHtml";
24
15
  onRenderClient: "import:vike-solid/renderer/onRenderClient:onRenderClient";
25
- passToClient: string[];
26
16
  clientRouting: true;
27
17
  hydrationCanBeAborted: true;
28
18
  meta: {
@@ -43,19 +33,16 @@ declare const _default: {
43
33
  client: true;
44
34
  };
45
35
  };
46
- description: {
47
- env: {
48
- server: true;
49
- };
50
- };
51
36
  favicon: {
52
37
  env: {
53
38
  server: true;
39
+ client: true;
54
40
  };
55
41
  };
56
42
  lang: {
57
43
  env: {
58
44
  server: true;
45
+ client: true;
59
46
  };
60
47
  };
61
48
  ssr: {
@@ -82,7 +69,6 @@ declare global {
82
69
  /** A component, usually common to several pages, that wraps the root component `Page` */
83
70
  Layout?: Component;
84
71
  title?: string | ((pageContext: PageContext) => string);
85
- description?: string;
86
72
  favicon?: string;
87
73
  /**
88
74
  * @default 'en'
package/package.json CHANGED
@@ -1,31 +1,31 @@
1
1
  {
2
2
  "name": "vike-solid",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "dependencies": {
6
- "vite-plugin-solid": "^2.8.0"
6
+ "vite-plugin-solid": "^2.9.1"
7
7
  },
8
8
  "peerDependencies": {
9
9
  "solid-js": "^1.8.7",
10
10
  "vite": "^4.4 || ^5.0.2",
11
- "vike": "^0.4.152"
11
+ "vike": "^0.4.159"
12
12
  },
13
13
  "devDependencies": {
14
14
  "@babel/core": "^7.23.7",
15
- "@babel/preset-env": "^7.23.7",
15
+ "@babel/preset-env": "^7.23.8",
16
16
  "@babel/preset-typescript": "^7.23.3",
17
17
  "@rollup/plugin-babel": "^6.0.4",
18
18
  "@rollup/plugin-node-resolve": "^15.2.3",
19
19
  "@types/node": "^18.17.4",
20
- "babel-preset-solid": "^1.8.6",
21
- "bumpp": "^9.2.1",
22
- "rollup": "^4.9.2",
20
+ "babel-preset-solid": "^1.8.12",
21
+ "bumpp": "^9.3.0",
22
+ "rollup": "^4.9.6",
23
23
  "rollup-plugin-dts": "^6.1.0",
24
- "solid-js": "^1.8.7",
24
+ "solid-js": "^1.8.12",
25
25
  "tslib": "^2.6.2",
26
26
  "typescript": "^5.3.3",
27
- "vite": "^5.0.10",
28
- "vike": "^0.4.153"
27
+ "vite": "^5.0.12",
28
+ "vike": "^0.4.160"
29
29
  },
30
30
  "exports": {
31
31
  ".": "./dist/+config.js",