webstudio 0.0.0-5844e28 → 0.0.0-73cd6ea
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/lib/cli.js +5123 -2567
- package/package.json +35 -32
- package/templates/cloudflare/package.json +2 -2
- package/templates/cloudflare/vite.config.ts +8 -0
- package/templates/defaults/app/root.tsx +6 -2
- package/templates/defaults/app/route-templates/html.tsx +12 -13
- package/templates/defaults/app/route-templates/xml.tsx +3 -5
- package/templates/defaults/package.json +14 -14
- package/templates/defaults/vite.config.ts +8 -0
- package/templates/react-router/app/root.tsx +6 -2
- package/templates/react-router/app/route-templates/html.tsx +12 -13
- package/templates/react-router/app/route-templates/xml.tsx +3 -1
- package/templates/react-router/package.json +13 -13
- package/templates/react-router/vite.config.ts +8 -0
- package/templates/{vercel → react-router-cloudflare}/app/constants.mjs +3 -7
- package/templates/react-router-cloudflare/app/entry.server.tsx +43 -0
- package/templates/react-router-cloudflare/package.json +12 -0
- package/templates/react-router-cloudflare/react-router.config.ts +7 -0
- package/templates/react-router-cloudflare/tsconfig.json +23 -0
- package/templates/react-router-cloudflare/vite.config.ts +15 -0
- package/templates/react-router-cloudflare/workers/app.ts +26 -0
- package/templates/react-router-cloudflare/wrangler.jsonc +6 -0
- package/templates/react-router-docker/app/constants.mjs +14 -1
- package/templates/react-router-docker/package.json +4 -4
- package/templates/react-router-netlify/package.json +2 -2
- package/templates/react-router-netlify/vite.config.ts +8 -0
- package/templates/react-router-vercel/package.json +2 -2
- package/templates/react-router-vercel/vercel.json +1 -1
- package/templates/saas-helpers/package.json +4 -1
- package/templates/saas-helpers/vite.config.ts +48 -0
- package/templates/ssg/app/route-templates/html/+Head.tsx +14 -6
- package/templates/ssg/app/route-templates/html/+Page.tsx +3 -1
- package/templates/ssg/package.json +10 -10
- package/templates/ssg/renderer/+onRenderHtml.tsx +13 -5
- package/templates/ssg/vite.config.ts +8 -0
- package/templates/vercel/.vercelignore +0 -8
- package/templates/vercel/package.json +0 -1
- package/templates/vercel/vercel.json +0 -11
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export const assetBaseUrl = "/assets/";
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* URL.canParse(props.src)
|
|
9
|
+
* @type {(url: string) => boolean}
|
|
10
|
+
*/
|
|
11
|
+
const UrlCanParse = (url) => {
|
|
12
|
+
try {
|
|
13
|
+
new URL(url);
|
|
14
|
+
return true;
|
|
15
|
+
} catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
7
20
|
/**
|
|
8
21
|
* @type {import("@webstudio-is/image").ImageLoader}
|
|
9
22
|
*/
|
|
@@ -12,7 +25,7 @@ export const imageLoader = (props) => {
|
|
|
12
25
|
return props.src;
|
|
13
26
|
}
|
|
14
27
|
// handle absolute urls
|
|
15
|
-
const path =
|
|
28
|
+
const path = UrlCanParse(props.src) ? `/${props.src}` : props.src;
|
|
16
29
|
// https://github.com/unjs/ipx?tab=readme-ov-file#modifiers
|
|
17
30
|
return `/_image/w_${props.width},q_${props.quality}${path}`;
|
|
18
31
|
};
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"start": "react-router-serve ./build/server/index.js"
|
|
4
4
|
},
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@react-router/node": "^7.
|
|
7
|
-
"@react-router/serve": "^7.
|
|
8
|
-
"h3": "^1.15.
|
|
9
|
-
"ipx": "^3.0.
|
|
6
|
+
"@react-router/node": "^7.5.3",
|
|
7
|
+
"@react-router/serve": "^7.5.3",
|
|
8
|
+
"h3": "^1.15.1",
|
|
9
|
+
"ipx": "^3.0.3"
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -4,4 +4,12 @@ import netlifyPlugin from "@netlify/vite-plugin-react-router";
|
|
|
4
4
|
|
|
5
5
|
export default defineConfig({
|
|
6
6
|
plugins: [reactRouter(), netlifyPlugin()],
|
|
7
|
+
resolve: {
|
|
8
|
+
conditions: ["browser", "development|production"],
|
|
9
|
+
},
|
|
10
|
+
ssr: {
|
|
11
|
+
resolve: {
|
|
12
|
+
conditions: ["node", "development|production"],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
7
15
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
vitePlugin as remix,
|
|
3
|
+
cloudflareDevProxyVitePlugin as remixCloudflareDevProxy,
|
|
4
|
+
} from "@remix-run/dev";
|
|
5
|
+
import { defineConfig } from "vite";
|
|
6
|
+
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
import fg from "fast-glob";
|
|
12
|
+
|
|
13
|
+
const rootDir = ["..", "../..", "../../.."]
|
|
14
|
+
.map((dir) => path.join(__dirname, dir))
|
|
15
|
+
.find((dir) => existsSync(path.join(dir, ".git")));
|
|
16
|
+
|
|
17
|
+
const hasPrivateFolders =
|
|
18
|
+
fg.sync([path.join(rootDir ?? "", "packages/*/private-src/*")], {
|
|
19
|
+
ignore: ["**/node_modules/**"],
|
|
20
|
+
}).length > 0;
|
|
21
|
+
|
|
22
|
+
const conditions = hasPrivateFolders
|
|
23
|
+
? ["webstudio-private", "webstudio"]
|
|
24
|
+
: ["webstudio"];
|
|
25
|
+
|
|
26
|
+
export default defineConfig(({ mode }) => ({
|
|
27
|
+
resolve: {
|
|
28
|
+
conditions: [...conditions, "browser", "development|production"],
|
|
29
|
+
},
|
|
30
|
+
ssr: {
|
|
31
|
+
resolve: {
|
|
32
|
+
conditions: [...conditions, "node", "development|production"],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
plugins: [
|
|
36
|
+
// without this, remixCloudflareDevProxy trying to load workerd even for production (it's not needed for production)
|
|
37
|
+
mode === "production" ? undefined : remixCloudflareDevProxy(),
|
|
38
|
+
remix({
|
|
39
|
+
future: {
|
|
40
|
+
v3_lazyRouteDiscovery: false,
|
|
41
|
+
v3_relativeSplatPath: false,
|
|
42
|
+
v3_singleFetch: false,
|
|
43
|
+
v3_fetcherPersist: false,
|
|
44
|
+
v3_throwAbortReason: false,
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
].filter(Boolean),
|
|
48
|
+
}));
|
|
@@ -20,11 +20,14 @@ export const Head = ({ data }: { data: PageContext["data"] }) => {
|
|
|
20
20
|
let socialImageUrl = pageMeta.socialImageUrl;
|
|
21
21
|
if (pageMeta.socialImageAssetName) {
|
|
22
22
|
socialImageUrl = `${origin}${imageLoader({
|
|
23
|
-
src: pageMeta.socialImageAssetName
|
|
23
|
+
src: `${assetBaseUrl}/${pageMeta.socialImageAssetName}`,
|
|
24
24
|
// Do not transform social image (not enough information do we need to do this)
|
|
25
25
|
format: "raw",
|
|
26
26
|
})}`;
|
|
27
27
|
}
|
|
28
|
+
const isTwitterCardSizeDefined = pageMeta.custom.some(
|
|
29
|
+
(meta) => meta.property === "twitter:card"
|
|
30
|
+
);
|
|
28
31
|
return (
|
|
29
32
|
<>
|
|
30
33
|
{data.url && <meta property="og:url" content={data.url} />}
|
|
@@ -55,12 +58,17 @@ export const Head = ({ data }: { data: PageContext["data"] }) => {
|
|
|
55
58
|
{pageMeta.custom.map(({ property, content }) => (
|
|
56
59
|
<meta key={property} property={property} content={content} />
|
|
57
60
|
))}
|
|
61
|
+
{(pageMeta.socialImageAssetName !== undefined ||
|
|
62
|
+
pageMeta.socialImageUrl !== undefined) &&
|
|
63
|
+
isTwitterCardSizeDefined === false && (
|
|
64
|
+
<meta property="twitter:card" content="summary_large_image" />
|
|
65
|
+
)}
|
|
58
66
|
|
|
59
67
|
{favIconAsset && (
|
|
60
68
|
<link
|
|
61
69
|
rel="icon"
|
|
62
70
|
href={imageLoader({
|
|
63
|
-
src: `${assetBaseUrl}${favIconAsset
|
|
71
|
+
src: `${assetBaseUrl}${favIconAsset}`,
|
|
64
72
|
// width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search
|
|
65
73
|
width: 144,
|
|
66
74
|
height: 144,
|
|
@@ -72,18 +80,18 @@ export const Head = ({ data }: { data: PageContext["data"] }) => {
|
|
|
72
80
|
)}
|
|
73
81
|
{pageFontAssets.map((asset) => (
|
|
74
82
|
<link
|
|
75
|
-
key={asset
|
|
83
|
+
key={asset}
|
|
76
84
|
rel="preload"
|
|
77
|
-
href={`${assetBaseUrl}${asset
|
|
85
|
+
href={`${assetBaseUrl}${asset}`}
|
|
78
86
|
as="font"
|
|
79
87
|
crossOrigin="anonymous"
|
|
80
88
|
/>
|
|
81
89
|
))}
|
|
82
90
|
{pageBackgroundImageAssets.map((asset) => (
|
|
83
91
|
<link
|
|
84
|
-
key={asset
|
|
92
|
+
key={asset}
|
|
85
93
|
rel="preload"
|
|
86
|
-
href={`${assetBaseUrl}${asset
|
|
94
|
+
href={`${assetBaseUrl}${asset}`}
|
|
87
95
|
as="image"
|
|
88
96
|
/>
|
|
89
97
|
))}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PageContext } from "vike/types";
|
|
2
2
|
import { ReactSdkContext } from "@webstudio-is/react-sdk/runtime";
|
|
3
3
|
import { assetBaseUrl, imageLoader } from "__CONSTANTS__";
|
|
4
|
-
import { Page } from "__CLIENT__";
|
|
4
|
+
import { Page, breakpoints } from "__CLIENT__";
|
|
5
5
|
|
|
6
6
|
const PageComponent = ({ data }: { data: PageContext["data"] }) => {
|
|
7
7
|
const { system, resources, url } = data;
|
|
@@ -11,6 +11,8 @@ const PageComponent = ({ data }: { data: PageContext["data"] }) => {
|
|
|
11
11
|
imageLoader,
|
|
12
12
|
assetBaseUrl,
|
|
13
13
|
resources,
|
|
14
|
+
breakpoints,
|
|
15
|
+
onError: console.error,
|
|
14
16
|
}}
|
|
15
17
|
>
|
|
16
18
|
{/* Use the URL as the key to force scripts in HTML Embed to reload on dynamic pages */}
|
|
@@ -8,22 +8,22 @@
|
|
|
8
8
|
"typecheck": "tsc"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@webstudio-is/image": "0.0.0-
|
|
12
|
-
"@webstudio-is/react-sdk": "0.0.0-
|
|
13
|
-
"@webstudio-is/sdk": "0.0.0-
|
|
14
|
-
"@webstudio-is/sdk-components-react": "0.0.0-
|
|
15
|
-
"@webstudio-is/sdk-components-animation": "0.0.0-
|
|
16
|
-
"@webstudio-is/sdk-components-react-radix": "0.0.0-
|
|
11
|
+
"@webstudio-is/image": "0.0.0-73cd6ea",
|
|
12
|
+
"@webstudio-is/react-sdk": "0.0.0-73cd6ea",
|
|
13
|
+
"@webstudio-is/sdk": "0.0.0-73cd6ea",
|
|
14
|
+
"@webstudio-is/sdk-components-react": "0.0.0-73cd6ea",
|
|
15
|
+
"@webstudio-is/sdk-components-animation": "0.0.0-73cd6ea",
|
|
16
|
+
"@webstudio-is/sdk-components-react-radix": "0.0.0-73cd6ea",
|
|
17
17
|
"react": "18.3.0-canary-14898b6a9-20240318",
|
|
18
18
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
19
|
-
"vike": "^0.4.
|
|
19
|
+
"vike": "^0.4.229"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/react": "^18.2.70",
|
|
23
23
|
"@types/react-dom": "^18.2.25",
|
|
24
|
-
"@vitejs/plugin-react": "^4.
|
|
25
|
-
"typescript": "5.
|
|
26
|
-
"vite": "^
|
|
24
|
+
"@vitejs/plugin-react": "^4.4.1",
|
|
25
|
+
"typescript": "5.8.2",
|
|
26
|
+
"vite": "^6.3.4"
|
|
27
27
|
},
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">=20.0.0"
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { renderToString } from "react-dom/server";
|
|
2
2
|
import { dangerouslySkipEscape, escapeInject } from "vike/server";
|
|
3
3
|
import type { OnRenderHtmlSync } from "vike/types";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
import {
|
|
5
|
+
CustomCode,
|
|
6
|
+
projectId,
|
|
7
|
+
lastPublished,
|
|
8
|
+
// @todo think about how to make __generated__ typeable
|
|
9
|
+
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
} from "../app/__generated__/_index";
|
|
8
12
|
|
|
9
13
|
export const onRenderHtml: OnRenderHtmlSync = (pageContext) => {
|
|
10
14
|
const lang = pageContext.data.pageMeta.language || "en";
|
|
@@ -12,7 +16,11 @@ export const onRenderHtml: OnRenderHtmlSync = (pageContext) => {
|
|
|
12
16
|
const Page = pageContext.Page ?? (() => <></>);
|
|
13
17
|
const html = dangerouslySkipEscape(
|
|
14
18
|
renderToString(
|
|
15
|
-
<html
|
|
19
|
+
<html
|
|
20
|
+
lang={lang}
|
|
21
|
+
data-ws-project={projectId}
|
|
22
|
+
data-ws-last-published={lastPublished}
|
|
23
|
+
>
|
|
16
24
|
<head>
|
|
17
25
|
<meta charSet="UTF-8" />
|
|
18
26
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
@@ -4,4 +4,12 @@ import vike from "vike/plugin";
|
|
|
4
4
|
|
|
5
5
|
export default defineConfig({
|
|
6
6
|
plugins: [react(), vike({ prerender: true })],
|
|
7
|
+
resolve: {
|
|
8
|
+
conditions: ["browser", "development|production"],
|
|
9
|
+
},
|
|
10
|
+
ssr: {
|
|
11
|
+
resolve: {
|
|
12
|
+
conditions: ["node", "development|production"],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
7
15
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{}
|