vike-solid 0.6.2 → 0.7.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 +1 -1
- package/dist/+config.d.ts +35 -59
- package/dist/+config.js +38 -12
- package/dist/Config-DEYhmA4K.d.ts +156 -0
- package/dist/helpers/clientOnly.d.ts +13 -0
- package/dist/helpers/clientOnly.js +24 -0
- package/dist/hooks/useConfig/useConfig-client.d.ts +12 -0
- package/dist/hooks/useConfig/useConfig-client.js +46 -0
- package/dist/hooks/useConfig/useConfig-server.d.ts +12 -0
- package/dist/hooks/useConfig/useConfig-server.js +54 -0
- package/dist/renderer/onRenderClient.js +38 -25
- package/dist/renderer/onRenderHtml.js +115 -47
- package/package.json +19 -17
- package/dist/components/clientOnly.d.ts +0 -23
- package/dist/components/clientOnly.js +0 -64
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -4
package/README.md
CHANGED
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
|
|
8
8
|
- Docs at [`vike.dev/vike-solid`](https://vike.dev/vike-solid)
|
|
9
9
|
- [Examples](https://github.com/vikejs/vike-solid/tree/main/examples)
|
|
10
|
-
- [
|
|
10
|
+
- [CHANGELOG.md](https://github.com/vikejs/vike-solid/blob/main/CHANGELOG.md)
|
package/dist/+config.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ConfigEffect } from 'vike/types';
|
|
2
|
-
import { JSX
|
|
2
|
+
import { JSX } from 'solid-js';
|
|
3
|
+
import './Config-DEYhmA4K.js';
|
|
3
4
|
|
|
4
5
|
declare function ssrEffect({ configDefinedAt, configValue }: Parameters<ConfigEffect>[0]): ReturnType<ConfigEffect>;
|
|
5
6
|
|
|
@@ -12,59 +13,6 @@ declare global {
|
|
|
12
13
|
}
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
declare global {
|
|
16
|
-
namespace Vike {
|
|
17
|
-
interface Config {
|
|
18
|
-
/** The page's root Solid component */
|
|
19
|
-
Page?: () => JSX.Element;
|
|
20
|
-
/** Solid element renderer and appended into <head></head> */
|
|
21
|
-
Head?: Component;
|
|
22
|
-
/**
|
|
23
|
-
* A component that defines the visual layout of the page common to several pages.
|
|
24
|
-
*
|
|
25
|
-
* Technically: the `<Layout>` component wraps the root component `<Page>`.
|
|
26
|
-
*
|
|
27
|
-
* https://vike.dev/Layout
|
|
28
|
-
*/
|
|
29
|
-
Layout?: Component;
|
|
30
|
-
/** <title>${title}</title> */
|
|
31
|
-
title?: string | ((pageContext: PageContext) => string);
|
|
32
|
-
/** <link rel="icon" href="${favicon}" /> */
|
|
33
|
-
favicon?: string;
|
|
34
|
-
/** <html lang="${lang}">
|
|
35
|
-
*
|
|
36
|
-
* @default 'en'
|
|
37
|
-
*
|
|
38
|
-
*/
|
|
39
|
-
lang?: string;
|
|
40
|
-
/**
|
|
41
|
-
* If `true`, the page is rendered twice: on the server-side (to HTML) and on the client-side (hydration).
|
|
42
|
-
*
|
|
43
|
-
* If `false`, the page is rendered only once in the browser.
|
|
44
|
-
*
|
|
45
|
-
* https://vike.dev/ssr
|
|
46
|
-
*
|
|
47
|
-
* @default true
|
|
48
|
-
*
|
|
49
|
-
*/
|
|
50
|
-
ssr?: boolean;
|
|
51
|
-
/**
|
|
52
|
-
* Whether to stream the page's HTML. Requires Server-Side Rendering (`ssr: true`).
|
|
53
|
-
* If true, the stream will be a Node Stream. If you need a Web Stream, use `stream: 'web'`.
|
|
54
|
-
*
|
|
55
|
-
* @default false
|
|
56
|
-
*
|
|
57
|
-
* https://vike.dev/stream
|
|
58
|
-
*
|
|
59
|
-
*/
|
|
60
|
-
stream?: boolean | "web";
|
|
61
|
-
}
|
|
62
|
-
interface ConfigResolved {
|
|
63
|
-
Layout?: Array<Component>;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
16
|
declare const _default: {
|
|
69
17
|
name: string;
|
|
70
18
|
require: {
|
|
@@ -74,11 +22,13 @@ declare const _default: {
|
|
|
74
22
|
onRenderClient: "import:vike-solid/renderer/onRenderClient:onRenderClient";
|
|
75
23
|
clientRouting: true;
|
|
76
24
|
hydrationCanBeAborted: true;
|
|
25
|
+
passToClient: string[];
|
|
77
26
|
meta: {
|
|
78
27
|
Head: {
|
|
79
28
|
env: {
|
|
80
29
|
server: true;
|
|
81
30
|
};
|
|
31
|
+
cumulative: true;
|
|
82
32
|
};
|
|
83
33
|
Layout: {
|
|
84
34
|
env: {
|
|
@@ -93,11 +43,26 @@ declare const _default: {
|
|
|
93
43
|
client: true;
|
|
94
44
|
};
|
|
95
45
|
};
|
|
46
|
+
description: {
|
|
47
|
+
env: {
|
|
48
|
+
server: true;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
image: {
|
|
52
|
+
env: {
|
|
53
|
+
server: true;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
viewport: {
|
|
57
|
+
env: {
|
|
58
|
+
server: true;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
96
61
|
favicon: {
|
|
97
62
|
env: {
|
|
98
63
|
server: true;
|
|
99
|
-
client: true;
|
|
100
64
|
};
|
|
65
|
+
global: true;
|
|
101
66
|
};
|
|
102
67
|
lang: {
|
|
103
68
|
env: {
|
|
@@ -116,15 +81,26 @@ declare const _default: {
|
|
|
116
81
|
server: true;
|
|
117
82
|
};
|
|
118
83
|
};
|
|
119
|
-
|
|
84
|
+
htmlAttributes: {
|
|
120
85
|
env: {
|
|
121
|
-
|
|
86
|
+
server: true;
|
|
87
|
+
};
|
|
88
|
+
global: true;
|
|
89
|
+
cumulative: true;
|
|
90
|
+
};
|
|
91
|
+
bodyAttributes: {
|
|
92
|
+
env: {
|
|
93
|
+
server: true;
|
|
122
94
|
};
|
|
95
|
+
global: true;
|
|
96
|
+
cumulative: true;
|
|
123
97
|
};
|
|
124
|
-
|
|
98
|
+
onAfterRenderClient: {
|
|
125
99
|
env: {
|
|
126
|
-
|
|
100
|
+
server: false;
|
|
101
|
+
client: true;
|
|
127
102
|
};
|
|
103
|
+
cumulative: true;
|
|
128
104
|
};
|
|
129
105
|
};
|
|
130
106
|
};
|
package/dist/+config.js
CHANGED
|
@@ -33,12 +33,14 @@ var _config = {
|
|
|
33
33
|
// https://vike.dev/clientRouting
|
|
34
34
|
clientRouting: true,
|
|
35
35
|
hydrationCanBeAborted: true,
|
|
36
|
+
passToClient: ["_configFromHook"],
|
|
36
37
|
// https://vike.dev/meta
|
|
37
38
|
meta: {
|
|
38
39
|
Head: {
|
|
39
40
|
env: {
|
|
40
41
|
server: true
|
|
41
|
-
}
|
|
42
|
+
},
|
|
43
|
+
cumulative: true
|
|
42
44
|
},
|
|
43
45
|
Layout: {
|
|
44
46
|
env: {
|
|
@@ -53,12 +55,27 @@ var _config = {
|
|
|
53
55
|
client: true
|
|
54
56
|
}
|
|
55
57
|
},
|
|
56
|
-
|
|
58
|
+
description: {
|
|
57
59
|
env: {
|
|
58
|
-
server: true
|
|
59
|
-
client: true
|
|
60
|
+
server: true
|
|
60
61
|
}
|
|
61
62
|
},
|
|
63
|
+
image: {
|
|
64
|
+
env: {
|
|
65
|
+
server: true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
viewport: {
|
|
69
|
+
env: {
|
|
70
|
+
server: true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
favicon: {
|
|
74
|
+
env: {
|
|
75
|
+
server: true
|
|
76
|
+
},
|
|
77
|
+
global: true
|
|
78
|
+
},
|
|
62
79
|
lang: {
|
|
63
80
|
env: {
|
|
64
81
|
server: true,
|
|
@@ -76,17 +93,26 @@ var _config = {
|
|
|
76
93
|
server: true
|
|
77
94
|
}
|
|
78
95
|
},
|
|
79
|
-
|
|
80
|
-
name: {
|
|
96
|
+
htmlAttributes: {
|
|
81
97
|
env: {
|
|
82
|
-
|
|
83
|
-
}
|
|
98
|
+
server: true
|
|
99
|
+
},
|
|
100
|
+
global: true,
|
|
101
|
+
cumulative: true // for Vike extensions
|
|
84
102
|
},
|
|
85
|
-
|
|
86
|
-
require: {
|
|
103
|
+
bodyAttributes: {
|
|
87
104
|
env: {
|
|
88
|
-
|
|
89
|
-
}
|
|
105
|
+
server: true
|
|
106
|
+
},
|
|
107
|
+
global: true,
|
|
108
|
+
cumulative: true // for Vike extensions
|
|
109
|
+
},
|
|
110
|
+
onAfterRenderClient: {
|
|
111
|
+
env: {
|
|
112
|
+
server: false,
|
|
113
|
+
client: true
|
|
114
|
+
},
|
|
115
|
+
cumulative: true
|
|
90
116
|
}
|
|
91
117
|
}
|
|
92
118
|
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { JSX, Component } from 'solid-js';
|
|
2
|
+
import { PageContext, PageContextServer, PageContextClient } from 'vike/types';
|
|
3
|
+
|
|
4
|
+
type TagAttributes = Record<string, string | number | boolean | undefined | null>;
|
|
5
|
+
|
|
6
|
+
type Viewport = "responsive" | number | null;
|
|
7
|
+
|
|
8
|
+
declare global {
|
|
9
|
+
namespace Vike {
|
|
10
|
+
interface Config {
|
|
11
|
+
/**
|
|
12
|
+
* The page's root Solid component.
|
|
13
|
+
*
|
|
14
|
+
* https://vike.dev/Page
|
|
15
|
+
*/
|
|
16
|
+
Page?: () => JSX.Element;
|
|
17
|
+
/**
|
|
18
|
+
* Add arbitrary `<head>` tags.
|
|
19
|
+
*
|
|
20
|
+
* https://vike.dev/Head
|
|
21
|
+
*/
|
|
22
|
+
Head?: Head;
|
|
23
|
+
/**
|
|
24
|
+
* A component that defines the visual layout common to several pages.
|
|
25
|
+
*
|
|
26
|
+
* Technically: the `<Layout>` component wraps the root component `<Page>`.
|
|
27
|
+
*
|
|
28
|
+
* https://vike.dev/Layout
|
|
29
|
+
*/
|
|
30
|
+
Layout?: Component;
|
|
31
|
+
/**
|
|
32
|
+
* Set the page's tilte.
|
|
33
|
+
*
|
|
34
|
+
* Generates:
|
|
35
|
+
* ```jsx
|
|
36
|
+
* <head>
|
|
37
|
+
* <title>{title}</title>
|
|
38
|
+
* <meta property="og:title" content={title} />
|
|
39
|
+
* </head>
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* https://vike.dev/title
|
|
43
|
+
*/
|
|
44
|
+
title?: string | ((pageContext: PageContext) => string);
|
|
45
|
+
/**
|
|
46
|
+
* Set the page's description.
|
|
47
|
+
*
|
|
48
|
+
* Generates:
|
|
49
|
+
* ```jsx
|
|
50
|
+
* <head>
|
|
51
|
+
* <meta name="description" content={description}>
|
|
52
|
+
* <meta property="og:description" content={description}>
|
|
53
|
+
* </head>
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* https://vike.dev/description
|
|
57
|
+
*/
|
|
58
|
+
description?: string | ((pageContext: PageContextServer) => string);
|
|
59
|
+
/**
|
|
60
|
+
* Set the page's preview image upon URL sharing.
|
|
61
|
+
*
|
|
62
|
+
* Generates:
|
|
63
|
+
* ```jsx
|
|
64
|
+
* <head>
|
|
65
|
+
* <meta property="og:image" content={image}>
|
|
66
|
+
* <meta name="twitter:card" content="summary_large_image">
|
|
67
|
+
* </head>
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* https://vike.dev/image
|
|
71
|
+
*/
|
|
72
|
+
image?: string | ((pageContext: PageContextServer) => string);
|
|
73
|
+
/**
|
|
74
|
+
* Set the page's width shown to the user on mobile/tablet devices.
|
|
75
|
+
*
|
|
76
|
+
* @default "responsive"
|
|
77
|
+
*
|
|
78
|
+
* https://vike.dev/viewport
|
|
79
|
+
*/
|
|
80
|
+
viewport?: Viewport;
|
|
81
|
+
/**
|
|
82
|
+
* Set the page's favicon.
|
|
83
|
+
*
|
|
84
|
+
* Generates:
|
|
85
|
+
* ```jsx
|
|
86
|
+
* <head>
|
|
87
|
+
* <link rel="icon" href={favicon} />
|
|
88
|
+
* </head>
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* https://vike.dev/favicon
|
|
92
|
+
*/
|
|
93
|
+
favicon?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Set the page's language (`<html lang>`).
|
|
96
|
+
*
|
|
97
|
+
* @default 'en'
|
|
98
|
+
*
|
|
99
|
+
* https://vike.dev/lang
|
|
100
|
+
*/
|
|
101
|
+
lang?: string | ((pageContext: PageContext) => string) | null;
|
|
102
|
+
/**
|
|
103
|
+
* Add tag attributes such as `<html class="dark">`.
|
|
104
|
+
*
|
|
105
|
+
* https://vike.dev/htmlAttributes
|
|
106
|
+
*/
|
|
107
|
+
htmlAttributes?: TagAttributes;
|
|
108
|
+
/**
|
|
109
|
+
* Add tag attributes such as `<body class="dark">`.
|
|
110
|
+
*
|
|
111
|
+
* https://vike.dev/bodyAttributes
|
|
112
|
+
*/
|
|
113
|
+
bodyAttributes?: TagAttributes;
|
|
114
|
+
/**
|
|
115
|
+
* If `true`, the page is rendered twice: on the server-side (to HTML) and on the client-side (hydration).
|
|
116
|
+
*
|
|
117
|
+
* If `false`, the page is rendered only once in the browser.
|
|
118
|
+
*
|
|
119
|
+
* @default true
|
|
120
|
+
*
|
|
121
|
+
* https://vike.dev/ssr
|
|
122
|
+
*/
|
|
123
|
+
ssr?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Whether to stream the page's HTML. Requires Server-Side Rendering (`ssr: true`).
|
|
126
|
+
*
|
|
127
|
+
* If `true`, the stream will be a Node Stream. If you need a Web Stream, use `stream: 'web'`.
|
|
128
|
+
*
|
|
129
|
+
* @default false
|
|
130
|
+
*
|
|
131
|
+
* https://vike.dev/stream
|
|
132
|
+
*/
|
|
133
|
+
stream?: boolean | "web";
|
|
134
|
+
/**
|
|
135
|
+
* Client-side hook called after the page is rendered.
|
|
136
|
+
*
|
|
137
|
+
* https://vike.dev/onAfterRenderClient
|
|
138
|
+
*/
|
|
139
|
+
onAfterRenderClient?: (pageContext: PageContextClient) => void;
|
|
140
|
+
}
|
|
141
|
+
interface ConfigResolved {
|
|
142
|
+
Layout?: Array<Component>;
|
|
143
|
+
Head?: Array<Head>;
|
|
144
|
+
bodyAttributes?: TagAttributes[];
|
|
145
|
+
htmlAttributes?: TagAttributes[];
|
|
146
|
+
onAfterRenderClient?: Function[];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
type Head = Component | JSX.Element;
|
|
151
|
+
type PickWithoutGetter<T, K extends keyof T> = {
|
|
152
|
+
[P in K]: Exclude<T[P], Function>;
|
|
153
|
+
};
|
|
154
|
+
type ConfigFromHook = PickWithoutGetter<Vike.Config, "Head" | "title" | "description" | "image">;
|
|
155
|
+
|
|
156
|
+
export type { ConfigFromHook as C };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Component, ComponentProps, JSX } from 'solid-js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Load and render a component only on the client-side.
|
|
5
|
+
* @see {@link https://vike.dev/clientOnly}
|
|
6
|
+
*/
|
|
7
|
+
declare function clientOnly<T extends Component<any>>(fn: () => Promise<{
|
|
8
|
+
default: T;
|
|
9
|
+
} | T>): (props: ComponentProps<T> & {
|
|
10
|
+
fallback?: JSX.Element;
|
|
11
|
+
}) => any;
|
|
12
|
+
|
|
13
|
+
export { clientOnly };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createSignal, splitProps, sharedConfig, onMount, createMemo, untrack } from 'solid-js';
|
|
2
|
+
import { isServer } from 'solid-js/web';
|
|
3
|
+
|
|
4
|
+
// Copied from https://github.com/solidjs/solid-start/blob/2d75d5fedfd11f739b03ca34decf23865868ac09/packages/start/src/shared/clientOnly.tsx#L7
|
|
5
|
+
/**
|
|
6
|
+
* Load and render a component only on the client-side.
|
|
7
|
+
* @see {@link https://vike.dev/clientOnly}
|
|
8
|
+
*/
|
|
9
|
+
function clientOnly(fn) {
|
|
10
|
+
if (isServer) return props => props.fallback;
|
|
11
|
+
const [comp, setComp] = createSignal();
|
|
12
|
+
fn().then(m => setComp(() => "default" in m ? m.default : m));
|
|
13
|
+
return props => {
|
|
14
|
+
let Comp;
|
|
15
|
+
let m;
|
|
16
|
+
const [, rest] = splitProps(props, ["fallback"]);
|
|
17
|
+
if ((Comp = comp()) && !sharedConfig.context) return Comp(rest);
|
|
18
|
+
const [mounted, setMounted] = createSignal(!sharedConfig.context);
|
|
19
|
+
onMount(() => setMounted(true));
|
|
20
|
+
return createMemo(() => (Comp = comp(), m = mounted(), untrack(() => Comp && m ? Comp(rest) : props.fallback)));
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { clientOnly };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { C as ConfigFromHook } from '../../Config-DEYhmA4K.js';
|
|
2
|
+
import 'solid-js';
|
|
3
|
+
import 'vike/types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Set configurations inside React components and Vike hooks.
|
|
7
|
+
*
|
|
8
|
+
* https://vike.dev/useConfig
|
|
9
|
+
*/
|
|
10
|
+
declare function useConfig(): (config: ConfigFromHook) => void;
|
|
11
|
+
|
|
12
|
+
export { useConfig };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { usePageContext } from '../usePageContext.js';
|
|
2
|
+
import { getPageContext } from 'vike/getPageContext';
|
|
3
|
+
import 'solid-js/web';
|
|
4
|
+
import 'solid-js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Set configurations inside React components and Vike hooks.
|
|
8
|
+
*
|
|
9
|
+
* https://vike.dev/useConfig
|
|
10
|
+
*/
|
|
11
|
+
function useConfig() {
|
|
12
|
+
const configSetter = config => setConfigOverPageContext(config, pageContext);
|
|
13
|
+
|
|
14
|
+
// Vike hook
|
|
15
|
+
let pageContext = getPageContext();
|
|
16
|
+
if (pageContext) return configSetter;
|
|
17
|
+
|
|
18
|
+
// React component
|
|
19
|
+
pageContext = usePageContext();
|
|
20
|
+
return config => {
|
|
21
|
+
if (!("_headAlreadySet" in pageContext)) {
|
|
22
|
+
configSetter(config);
|
|
23
|
+
} else {
|
|
24
|
+
sideEffect(config);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const configsClientSide = ["title"];
|
|
29
|
+
function setConfigOverPageContext(config, pageContext) {
|
|
30
|
+
pageContext._configFromHook ??= {};
|
|
31
|
+
configsClientSide.forEach(configName => {
|
|
32
|
+
const configValue = config[configName];
|
|
33
|
+
if (!configValue) return;
|
|
34
|
+
pageContext._configFromHook[configName] = configValue;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function sideEffect(config) {
|
|
38
|
+
const {
|
|
39
|
+
title
|
|
40
|
+
} = config;
|
|
41
|
+
if (title) {
|
|
42
|
+
window.document.title = title;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { useConfig };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { C as ConfigFromHook } from '../../Config-DEYhmA4K.js';
|
|
2
|
+
import 'solid-js';
|
|
3
|
+
import 'vike/types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Set configurations inside React components and Vike hooks.
|
|
7
|
+
*
|
|
8
|
+
* https://vike.dev/useConfig
|
|
9
|
+
*/
|
|
10
|
+
declare function useConfig(): (config: ConfigFromHook) => void;
|
|
11
|
+
|
|
12
|
+
export { useConfig };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { usePageContext } from '../usePageContext.js';
|
|
2
|
+
import { getPageContext } from 'vike/getPageContext';
|
|
3
|
+
import 'solid-js/web';
|
|
4
|
+
import 'solid-js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Set configurations inside React components and Vike hooks.
|
|
8
|
+
*
|
|
9
|
+
* https://vike.dev/useConfig
|
|
10
|
+
*/
|
|
11
|
+
function useConfig() {
|
|
12
|
+
const configSetter = config => setConfigOverPageContext(config, pageContext);
|
|
13
|
+
|
|
14
|
+
// Vike hook
|
|
15
|
+
let pageContext = getPageContext();
|
|
16
|
+
if (pageContext) return configSetter;
|
|
17
|
+
|
|
18
|
+
// React component
|
|
19
|
+
pageContext = usePageContext();
|
|
20
|
+
return config => {
|
|
21
|
+
if (!pageContext._headAlreadySet) {
|
|
22
|
+
configSetter(config);
|
|
23
|
+
} else {
|
|
24
|
+
throw new Error("Using useConfig() with HTML streaming isn't supported yet");
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const configsHtmlOnly = ["Head", "description", "image"];
|
|
29
|
+
const configsCumulative = ["Head"];
|
|
30
|
+
const configsOverridable = ["title", "description", "image"];
|
|
31
|
+
function setConfigOverPageContext(config, pageContext) {
|
|
32
|
+
pageContext._configFromHook ??= {};
|
|
33
|
+
if (pageContext.isClientSideNavigation) {
|
|
34
|
+
// Remove HTML only configs which the client-side doesn't need (also avoiding serialization errors)
|
|
35
|
+
for (const configName of configsHtmlOnly) delete config[configName];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Cumulative values
|
|
39
|
+
configsCumulative.forEach(configName => {
|
|
40
|
+
const configValue = config[configName];
|
|
41
|
+
if (!configValue) return;
|
|
42
|
+
pageContext._configFromHook[configName] ??= [];
|
|
43
|
+
pageContext._configFromHook[configName].push(configValue);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Overridable values
|
|
47
|
+
configsOverridable.forEach(configName => {
|
|
48
|
+
const configValue = config[configName];
|
|
49
|
+
if (!configValue) return;
|
|
50
|
+
pageContext._configFromHook[configName] = configValue;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { useConfig };
|
|
@@ -8,6 +8,10 @@ function isCallable(thing) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
function getHeadSetting(headSetting, pageContext) {
|
|
11
|
+
{
|
|
12
|
+
const val = pageContext._configFromHook?.[headSetting];
|
|
13
|
+
if (val !== undefined) return val;
|
|
14
|
+
}
|
|
11
15
|
const config = pageContext.configEntries[headSetting]?.[0];
|
|
12
16
|
if (!config) return undefined;
|
|
13
17
|
const val = config.configValue;
|
|
@@ -67,6 +71,21 @@ function Passthrough(props) {
|
|
|
67
71
|
return memo(() => props.children);
|
|
68
72
|
}
|
|
69
73
|
|
|
74
|
+
async function callCumulativeHooks(values, pageContext) {
|
|
75
|
+
if (!values) return [];
|
|
76
|
+
const valuesPromises = values.map(val => {
|
|
77
|
+
if (typeof val === "function") {
|
|
78
|
+
// Hook
|
|
79
|
+
return val(pageContext);
|
|
80
|
+
} else {
|
|
81
|
+
// Plain value
|
|
82
|
+
return val;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
const valuesResolved = await Promise.all(valuesPromises);
|
|
86
|
+
return valuesResolved;
|
|
87
|
+
}
|
|
88
|
+
|
|
70
89
|
// https://vike.dev/onRenderClient
|
|
71
90
|
const [pageContextStore, setPageContext] = createStore({});
|
|
72
91
|
let dispose;
|
|
@@ -89,34 +108,28 @@ const onRenderClient = async pageContext => {
|
|
|
89
108
|
// Client-side navigation
|
|
90
109
|
|
|
91
110
|
setPageContext(pageContext);
|
|
92
|
-
const title = getHeadSetting("title", pageContext) || "";
|
|
93
|
-
const lang = getHeadSetting("lang", pageContext) || "en";
|
|
94
|
-
const favicon = getHeadSetting("favicon", pageContext);
|
|
95
|
-
|
|
96
|
-
// We skip if the value is undefined because we shouldn't remove values set in HTML (by the Head setting).
|
|
97
|
-
// - This also means that previous values will leak: upon client-side navigation, the title set by the previous
|
|
98
|
-
// page won't be removed if the next page doesn't override it. But that's okay because usually pages always have
|
|
99
|
-
// a favicon and title, which means that previous values are always overridden. Also, as a workaround, the user
|
|
100
|
-
// can set the value to `null` to ensure that previous values are overridden.
|
|
101
|
-
if (title !== undefined) document.title = title;
|
|
102
|
-
if (lang !== undefined) document.documentElement.lang = lang;
|
|
103
|
-
if (favicon !== undefined) setFavicon(favicon);
|
|
104
111
|
}
|
|
112
|
+
if (!pageContext.isHydration) {
|
|
113
|
+
// E.g. document.title
|
|
114
|
+
updateDocument(pageContext);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Use cases:
|
|
118
|
+
// - Custom user settings: https://vike.dev/head-tags#custom-settings
|
|
119
|
+
// - Testing tools: https://github.com/vikejs/vike-react/issues/95
|
|
120
|
+
await callCumulativeHooks(pageContext.config.onAfterRenderClient, pageContext);
|
|
105
121
|
};
|
|
122
|
+
function updateDocument(pageContext) {
|
|
123
|
+
pageContext._headAlreadySet = true;
|
|
124
|
+
const title = getHeadSetting("title", pageContext);
|
|
125
|
+
const lang = getHeadSetting("lang", pageContext);
|
|
106
126
|
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
if (!link) {
|
|
115
|
-
link = document.createElement("link");
|
|
116
|
-
link.rel = "icon";
|
|
117
|
-
document.head.appendChild(link);
|
|
118
|
-
}
|
|
119
|
-
link.href = faviconUrl;
|
|
127
|
+
// - We skip if `undefined` as we shouldn't remove values set by the Head setting.
|
|
128
|
+
// - 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.
|
|
129
|
+
// - Most of the time, the user sets a default himself (i.e. a value defined at /pages/+config.js)
|
|
130
|
+
// - If he doesn't have a default then he can use `null` to opt into Vike's defaults
|
|
131
|
+
if (title !== undefined) document.title = title || "";
|
|
132
|
+
if (lang !== undefined) document.documentElement.lang = lang || "en";
|
|
120
133
|
}
|
|
121
134
|
|
|
122
135
|
export { onRenderClient };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createComponent, Dynamic, renderToString, renderToStream
|
|
2
|
-
import {
|
|
1
|
+
import { createComponent, Dynamic, generateHydrationScript, renderToString, renderToStream } from 'solid-js/web';
|
|
2
|
+
import { escapeInject, dangerouslySkipEscape, stampPipe } from 'vike/server';
|
|
3
3
|
import { PageContextProvider, usePageContext } from '../hooks/usePageContext.js';
|
|
4
4
|
import { createComputed, createComponent as createComponent$1 } from 'solid-js';
|
|
5
5
|
import { createStore, reconcile } from 'solid-js/store';
|
|
@@ -9,6 +9,10 @@ function isCallable(thing) {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
function getHeadSetting(headSetting, pageContext) {
|
|
12
|
+
{
|
|
13
|
+
const val = pageContext._configFromHook?.[headSetting];
|
|
14
|
+
if (val !== undefined) return val;
|
|
15
|
+
}
|
|
12
16
|
const config = pageContext.configEntries[headSetting]?.[0];
|
|
13
17
|
if (!config) return undefined;
|
|
14
18
|
const val = config.configValue;
|
|
@@ -68,61 +72,125 @@ function Passthrough(props) {
|
|
|
68
72
|
return props.children;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
function getTagAttributesString(tagAttributes) {
|
|
76
|
+
const tagAttributesString = Object.entries(tagAttributes).filter(([_key, value]) => value !== false && value !== null && value !== undefined).map(([key, value]) => `${ensureIsValidAttributeName(key)}=${JSON.stringify(String(value))}`).join(" ");
|
|
77
|
+
if (tagAttributesString.length === 0) return "";
|
|
78
|
+
return ` ${tagAttributesString}`;
|
|
79
|
+
}
|
|
80
|
+
function ensureIsValidAttributeName(str) {
|
|
81
|
+
if (/^[a-z][a-z0-9\-]*$/i.test(str) && !str.endsWith("-")) return str;
|
|
82
|
+
throw new Error(`Invalid HTML tag attribute name ${JSON.stringify(str)}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
72
85
|
const onRenderHtml = async pageContext => {
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
get children() {
|
|
82
|
-
return createComponent(Head, {});
|
|
83
|
-
}
|
|
84
|
-
}));
|
|
85
|
-
const headHtml = dangerouslySkipEscape(head);
|
|
86
|
-
let pageView = "";
|
|
87
|
-
if (pageContext.Page) {
|
|
88
|
-
if (!pageContext.config.stream) {
|
|
89
|
-
pageView = dangerouslySkipEscape(renderToString(() => getPageElement(pageContext)));
|
|
90
|
-
} else if (pageContext.config.stream === "web") {
|
|
91
|
-
pageView = renderToStream(() => getPageElement(pageContext)).pipeTo;
|
|
92
|
-
stampPipe(pageView, "web-stream");
|
|
93
|
-
} else {
|
|
94
|
-
pageView = renderToStream(() => getPageElement(pageContext)).pipe;
|
|
95
|
-
stampPipe(pageView, "node-stream");
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
const documentHtml = escapeInject`<!DOCTYPE html>
|
|
99
|
-
<html lang='${lang}'>
|
|
86
|
+
const pageHtml = getPageHtml(pageContext);
|
|
87
|
+
const headHtml = getHeadHtml(pageContext);
|
|
88
|
+
const {
|
|
89
|
+
htmlAttributesString,
|
|
90
|
+
bodyAttributesString
|
|
91
|
+
} = getTagAttributes(pageContext);
|
|
92
|
+
return escapeInject`<!DOCTYPE html>
|
|
93
|
+
<html${dangerouslySkipEscape(htmlAttributesString)}>
|
|
100
94
|
<head>
|
|
101
95
|
<meta charset="UTF-8" />
|
|
102
|
-
${titleTag}
|
|
103
96
|
${headHtml}
|
|
104
|
-
${faviconTag}
|
|
105
97
|
${dangerouslySkipEscape(generateHydrationScript())}
|
|
106
98
|
</head>
|
|
107
|
-
<body>
|
|
108
|
-
<div id="root">${
|
|
99
|
+
<body${dangerouslySkipEscape(bodyAttributesString)}>
|
|
100
|
+
<div id="root">${pageHtml}</div>
|
|
109
101
|
</body>
|
|
110
|
-
<!-- built with https://github.com/vikejs/vike-solid -->
|
|
111
102
|
</html>`;
|
|
112
|
-
return documentHtml;
|
|
113
103
|
};
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
104
|
+
function getPageHtml(pageContext) {
|
|
105
|
+
let pageHtml = "";
|
|
106
|
+
if (pageContext.Page) {
|
|
107
|
+
if (!pageContext.config.stream) {
|
|
108
|
+
pageHtml = dangerouslySkipEscape(renderToString(() => getPageElement(pageContext)));
|
|
109
|
+
} else if (pageContext.config.stream === "web") {
|
|
110
|
+
pageHtml = renderToStream(() => getPageElement(pageContext)).pipeTo;
|
|
111
|
+
stampPipe(pageHtml, "web-stream");
|
|
112
|
+
} else {
|
|
113
|
+
pageHtml = renderToStream(() => getPageElement(pageContext)).pipe;
|
|
114
|
+
stampPipe(pageHtml, "node-stream");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return pageHtml;
|
|
118
|
+
}
|
|
119
|
+
function getHeadHtml(pageContext) {
|
|
120
|
+
pageContext._headAlreadySet = true;
|
|
121
|
+
const title = getHeadSetting("title", pageContext);
|
|
122
|
+
const favicon = getHeadSetting("favicon", pageContext);
|
|
123
|
+
const description = getHeadSetting("description", pageContext);
|
|
124
|
+
const image = getHeadSetting("image", pageContext);
|
|
125
|
+
const titleTags = !title ? "" : escapeInject`<title>${title}</title><meta property="og:title" content="${title}">`;
|
|
126
|
+
const faviconTag = !favicon ? "" : escapeInject`<link rel="icon" href="${favicon}" />`;
|
|
127
|
+
const descriptionTags = !description ? "" : escapeInject`<meta name="description" content="${description}"><meta property="og:description" content="${description}">`;
|
|
128
|
+
const imageTags = !image ? "" : escapeInject`<meta property="og:image" content="${image}"><meta name="twitter:card" content="summary_large_image">`;
|
|
129
|
+
const viewportTag = dangerouslySkipEscape(getViewportTag(pageContext.config.viewport));
|
|
130
|
+
const headElementsHtml = dangerouslySkipEscape([
|
|
131
|
+
// Added by +Head
|
|
132
|
+
...(pageContext.config.Head ?? []),
|
|
133
|
+
// Added by useConfig()
|
|
134
|
+
...(pageContext._configFromHook?.Head ?? [])].filter(Head => Head !== null && Head !== undefined).map(Head => getHeadElementHtml(Head, pageContext)).join("\n"));
|
|
135
|
+
const headHtml = escapeInject`
|
|
136
|
+
${titleTags}
|
|
137
|
+
${viewportTag}
|
|
138
|
+
${headElementsHtml}
|
|
139
|
+
${faviconTag}
|
|
140
|
+
${descriptionTags}
|
|
141
|
+
${imageTags}
|
|
142
|
+
`;
|
|
143
|
+
return headHtml;
|
|
144
|
+
}
|
|
145
|
+
function getHeadElementHtml(Head, pageContext) {
|
|
146
|
+
let headElement;
|
|
147
|
+
if (isElement(Head)) {
|
|
148
|
+
headElement = () => Head;
|
|
149
|
+
} else {
|
|
150
|
+
headElement = () => createComponent(PageContextProvider, {
|
|
151
|
+
pageContext: pageContext,
|
|
152
|
+
get children() {
|
|
153
|
+
return createComponent(Head, {});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const headElementHtml = renderToString(headElement);
|
|
158
|
+
return headElementHtml;
|
|
159
|
+
}
|
|
160
|
+
function isElement(value) {
|
|
161
|
+
return !isCallable(value);
|
|
162
|
+
}
|
|
163
|
+
function getTagAttributes(pageContext) {
|
|
164
|
+
let lang = getHeadSetting("lang", pageContext);
|
|
165
|
+
// Don't set `lang` to its default value if it's `null` (so that users can set it to `null` in order to remove the default value)
|
|
166
|
+
if (lang === undefined) lang = "en";
|
|
167
|
+
const bodyAttributes = mergeTagAttributesList(pageContext.config.bodyAttributes);
|
|
168
|
+
const htmlAttributes = mergeTagAttributesList(pageContext.config.htmlAttributes);
|
|
169
|
+
const bodyAttributesString = getTagAttributesString(bodyAttributes);
|
|
170
|
+
const htmlAttributesString = getTagAttributesString({
|
|
171
|
+
...htmlAttributes,
|
|
172
|
+
lang: lang ?? htmlAttributes.lang
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
htmlAttributesString,
|
|
176
|
+
bodyAttributesString
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function mergeTagAttributesList(tagAttributesList = []) {
|
|
180
|
+
const tagAttributes = {};
|
|
181
|
+
tagAttributesList.forEach(tagAttrs => Object.assign(tagAttributes, tagAttrs));
|
|
182
|
+
return tagAttributes;
|
|
183
|
+
}
|
|
184
|
+
function getViewportTag(viewport) {
|
|
185
|
+
if (viewport === "responsive" || viewport === undefined) {
|
|
186
|
+
// `user-scalable=no` isn't recommended anymore:
|
|
187
|
+
// - https://stackoverflow.com/questions/22354435/to-user-scalable-no-or-not-to-user-scalable-no/22544312#comment120949420_22544312
|
|
188
|
+
return '<meta name="viewport" content="width=device-width,initial-scale=1">';
|
|
189
|
+
}
|
|
190
|
+
if (typeof viewport === "number") {
|
|
191
|
+
return `<meta name="viewport" content="width=${viewport}">`;
|
|
123
192
|
}
|
|
124
|
-
|
|
125
|
-
throw new Error("Update Vike to 0.4.173 or above");
|
|
193
|
+
return "";
|
|
126
194
|
}
|
|
127
195
|
|
|
128
196
|
export { onRenderHtml };
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vike-solid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "rollup -c rollup.config.js --watch",
|
|
7
|
+
"dev:check-types": "tsc --noEmit --watch",
|
|
7
8
|
"build": "tsc --noEmit && rollup -c rollup.config.js",
|
|
8
9
|
"release": "LANG=en_US release-me patch",
|
|
9
10
|
"release:minor": "LANG=en_US release-me minor",
|
|
@@ -18,30 +19,33 @@
|
|
|
18
19
|
"vite": "^4.4 || ^5.0.2"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
|
-
"@babel/core": "^7.24.
|
|
22
|
-
"@babel/preset-env": "^7.24.
|
|
22
|
+
"@babel/core": "^7.24.9",
|
|
23
|
+
"@babel/preset-env": "^7.24.8",
|
|
23
24
|
"@babel/preset-typescript": "^7.24.7",
|
|
24
25
|
"@brillout/release-me": "^0.3.9",
|
|
25
26
|
"@rollup/plugin-babel": "^6.0.4",
|
|
26
27
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
27
28
|
"@types/node": "^18.17.4",
|
|
28
|
-
"babel-preset-solid": "^1.8.
|
|
29
|
+
"babel-preset-solid": "^1.8.18",
|
|
29
30
|
"bumpp": "^9.4.1",
|
|
30
|
-
"rollup": "^4.
|
|
31
|
+
"rollup": "^4.19.0",
|
|
31
32
|
"rollup-plugin-dts": "^6.1.1",
|
|
32
|
-
"solid-js": "^1.8.
|
|
33
|
+
"solid-js": "^1.8.18",
|
|
33
34
|
"tslib": "^2.6.3",
|
|
34
|
-
"typescript": "^5.5.
|
|
35
|
-
"vike": "^0.4.
|
|
36
|
-
"vite": "^5.3.
|
|
35
|
+
"typescript": "^5.5.3",
|
|
36
|
+
"vike": "^0.4.182",
|
|
37
|
+
"vite": "^5.3.4"
|
|
37
38
|
},
|
|
38
39
|
"exports": {
|
|
39
|
-
".": "./dist/index.js",
|
|
40
40
|
"./config": "./dist/+config.js",
|
|
41
41
|
"./vite": "./dist/vite-plugin-vike-solid.js",
|
|
42
42
|
"./usePageContext": "./dist/hooks/usePageContext.js",
|
|
43
43
|
"./useData": "./dist/hooks/useData.js",
|
|
44
|
-
"./
|
|
44
|
+
"./useConfig": {
|
|
45
|
+
"browser": "./dist/hooks/useConfig/useConfig-client.js",
|
|
46
|
+
"default": "./dist/hooks/useConfig/useConfig-server.js"
|
|
47
|
+
},
|
|
48
|
+
"./clientOnly": "./dist/helpers/clientOnly.js",
|
|
45
49
|
"./renderer/onRenderHtml": "./dist/renderer/onRenderHtml.js",
|
|
46
50
|
"./renderer/onRenderClient": "./dist/renderer/onRenderClient.js",
|
|
47
51
|
"./client": {
|
|
@@ -50,9 +54,6 @@
|
|
|
50
54
|
},
|
|
51
55
|
"typesVersions": {
|
|
52
56
|
"*": {
|
|
53
|
-
".": [
|
|
54
|
-
"dist/index.d.ts"
|
|
55
|
-
],
|
|
56
57
|
"config": [
|
|
57
58
|
"dist/+config.d.ts"
|
|
58
59
|
],
|
|
@@ -68,8 +69,11 @@
|
|
|
68
69
|
"useData": [
|
|
69
70
|
"dist/hooks/useData.d.ts"
|
|
70
71
|
],
|
|
72
|
+
"useConfig": [
|
|
73
|
+
"dist/hooks/useConfig/useConfig-server.d.ts"
|
|
74
|
+
],
|
|
71
75
|
"clientOnly": [
|
|
72
|
-
"dist/
|
|
76
|
+
"dist/helpers/clientOnly.d.ts"
|
|
73
77
|
]
|
|
74
78
|
}
|
|
75
79
|
},
|
|
@@ -77,8 +81,6 @@
|
|
|
77
81
|
"dist/",
|
|
78
82
|
"client.d.ts"
|
|
79
83
|
],
|
|
80
|
-
"main": "dist/index.js",
|
|
81
|
-
"types": "dist/index.d.ts",
|
|
82
84
|
"repository": "github:vikejs/vike-solid",
|
|
83
85
|
"license": "MIT"
|
|
84
86
|
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Component, JSX, ComponentProps } from 'solid-js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated Replaced by {@link clientOnly}
|
|
5
|
-
*/
|
|
6
|
-
declare function ClientOnly<T>(props: {
|
|
7
|
-
load: () => Promise<{
|
|
8
|
-
default: Component<T>;
|
|
9
|
-
} | Component<T>>;
|
|
10
|
-
children: (Component: Component<T>) => JSX.Element;
|
|
11
|
-
fallback: JSX.Element;
|
|
12
|
-
}): JSX.Element;
|
|
13
|
-
/**
|
|
14
|
-
* Load and render a component only on the client-side.
|
|
15
|
-
* @see {@link https://vike.dev/clientOnly}
|
|
16
|
-
*/
|
|
17
|
-
declare function clientOnly<T extends Component<any>>(fn: () => Promise<{
|
|
18
|
-
default: T;
|
|
19
|
-
} | T>): (props: ComponentProps<T> & {
|
|
20
|
-
fallback?: JSX.Element;
|
|
21
|
-
}) => any;
|
|
22
|
-
|
|
23
|
-
export { ClientOnly, clientOnly };
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { createComponent, Dynamic, isServer, ssr, ssrHydrationKey } from 'solid-js/web';
|
|
2
|
-
import { createSignal, createEffect, Suspense, splitProps, sharedConfig, onMount, createMemo, untrack, lazy } from 'solid-js';
|
|
3
|
-
|
|
4
|
-
var _tmpl$ = ["<p", ">Error loading component.</p>"];
|
|
5
|
-
function ClientOnlyError() {
|
|
6
|
-
return ssr(_tmpl$, ssrHydrationKey());
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @deprecated Replaced by {@link clientOnly}
|
|
11
|
-
*/
|
|
12
|
-
function ClientOnly(props) {
|
|
13
|
-
const [getComponent, setComponent] = createSignal(undefined);
|
|
14
|
-
createEffect(() => {
|
|
15
|
-
const loadComponent = () => {
|
|
16
|
-
const Component = lazy(() => props.load().then(LoadedComponent => {
|
|
17
|
-
return {
|
|
18
|
-
default: () => props.children("default" in LoadedComponent ? LoadedComponent.default : LoadedComponent)
|
|
19
|
-
};
|
|
20
|
-
}).catch(error => {
|
|
21
|
-
console.error("Component loading failed:", error);
|
|
22
|
-
return {
|
|
23
|
-
default: ClientOnlyError
|
|
24
|
-
};
|
|
25
|
-
}));
|
|
26
|
-
setComponent(() => Component);
|
|
27
|
-
};
|
|
28
|
-
loadComponent();
|
|
29
|
-
});
|
|
30
|
-
return createComponent(Suspense, {
|
|
31
|
-
get fallback() {
|
|
32
|
-
return props.fallback;
|
|
33
|
-
},
|
|
34
|
-
get children() {
|
|
35
|
-
return createComponent(Dynamic, {
|
|
36
|
-
get component() {
|
|
37
|
-
return getComponent();
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Copied from https://github.com/solidjs/solid-start/blob/2d75d5fedfd11f739b03ca34decf23865868ac09/packages/start/src/shared/clientOnly.tsx#L7
|
|
45
|
-
/**
|
|
46
|
-
* Load and render a component only on the client-side.
|
|
47
|
-
* @see {@link https://vike.dev/clientOnly}
|
|
48
|
-
*/
|
|
49
|
-
function clientOnly(fn) {
|
|
50
|
-
if (isServer) return props => props.fallback;
|
|
51
|
-
const [comp, setComp] = createSignal();
|
|
52
|
-
fn().then(m => setComp(() => "default" in m ? m.default : m));
|
|
53
|
-
return props => {
|
|
54
|
-
let Comp;
|
|
55
|
-
let m;
|
|
56
|
-
const [, rest] = splitProps(props, ["fallback"]);
|
|
57
|
-
if ((Comp = comp()) && !sharedConfig.context) return Comp(rest);
|
|
58
|
-
const [mounted, setMounted] = createSignal(!sharedConfig.context);
|
|
59
|
-
onMount(() => setMounted(true));
|
|
60
|
-
return createMemo(() => (Comp = comp(), m = mounted(), untrack(() => Comp && m ? Comp(rest) : props.fallback)));
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export { ClientOnly, clientOnly };
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { default } from './+config.js';
|
|
2
|
-
|
|
3
|
-
// TODO/next-major-release: remove this file/export
|
|
4
|
-
console.warn("[vike-solid][warning][deprecation] Replace `import vikeSolid from 'vike-solid'` with `import vikeSolid from 'vike-solid/config'` (typically in your /pages/+config.js)");
|