From ae63207a0ea81580dc280eff4db30bf464b7f17f Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 2 Aug 2025 18:29:56 +0200 Subject: [PATCH 1/3] fix: support videos in self-hosted websites Ref https://discord.com/channels/955905230107738152/955905231227609158/1400561168648638576 User tried to self hosted a website with video component which got converted to /cgi/video which does not exist in self hosted targets. Here moved the logic into own custom loader and fall back to original url. --- apps/builder/app/canvas/canvas.tsx | 3 ++- .../app/routes/[another-page]._index.tsx | 17 ++++++++--------- .../app/routes/_index.tsx | 17 ++++++++--------- .../app/routes/[another-page]._index.tsx | 17 ++++++++--------- .../react-router-docker/app/routes/_index.tsx | 17 ++++++++--------- .../app/routes/[another-page]._index.tsx | 17 ++++++++--------- .../react-router-netlify/app/routes/_index.tsx | 17 ++++++++--------- .../app/routes/[another-page]._index.tsx | 17 ++++++++--------- .../react-router-vercel/app/routes/_index.tsx | 17 ++++++++--------- .../app/routes/[another-page]._index.tsx | 17 ++++++++--------- .../app/routes/_index.tsx | 17 ++++++++--------- .../routes/[_route_with_symbols_]._index.tsx | 17 ++++++++--------- .../app/routes/[animations]._index.tsx | 17 ++++++++--------- .../app/routes/[class-names]._index.tsx | 17 ++++++++--------- .../app/routes/[content-block]._index.tsx | 17 ++++++++--------- .../app/routes/[duration]._index.tsx | 17 ++++++++--------- .../app/routes/[expressions]._index.tsx | 17 ++++++++--------- .../app/routes/[form]._index.tsx | 17 ++++++++--------- .../app/routes/[head-tag]._index.tsx | 17 ++++++++--------- .../app/routes/[heading-with-id]._index.tsx | 17 ++++++++--------- .../routes/[nested].[nested-page]._index.tsx | 17 ++++++++--------- .../app/routes/[radix]._index.tsx | 17 ++++++++--------- .../app/routes/[resources]._index.tsx | 17 ++++++++--------- .../app/routes/[text-duration]._index.tsx | 17 ++++++++--------- .../webstudio-features/app/routes/_index.tsx | 17 ++++++++--------- .../defaults/app/route-templates/html.tsx | 17 ++++++++--------- .../react-router/app/route-templates/html.tsx | 17 ++++++++--------- packages/image/src/image-loaders.ts | 9 +++++++++ packages/react-sdk/placeholder.d.ts | 3 ++- packages/react-sdk/src/context.tsx | 4 +++- packages/sdk-components-react/src/video.tsx | 8 ++++---- 31 files changed, 228 insertions(+), 241 deletions(-) diff --git a/apps/builder/app/canvas/canvas.tsx b/apps/builder/app/canvas/canvas.tsx index 0db6362abac6..b55cb8088484 100644 --- a/apps/builder/app/canvas/canvas.tsx +++ b/apps/builder/app/canvas/canvas.tsx @@ -4,7 +4,7 @@ import { useStore } from "@nanostores/react"; import { type Instances, coreMetas } from "@webstudio-is/sdk"; import { coreTemplates } from "@webstudio-is/sdk/core-templates"; import type { Components } from "@webstudio-is/react-sdk"; -import { wsImageLoader } from "@webstudio-is/image"; +import { wsImageLoader, wsVideoLoader } from "@webstudio-is/image"; import { ReactSdkContext } from "@webstudio-is/react-sdk/runtime"; import * as baseComponents from "@webstudio-is/sdk-components-react"; import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas"; @@ -133,6 +133,7 @@ const useElementsTree = (components: Components, instances: Instances) => { renderer: isPreviewMode ? "preview" : "canvas", assetBaseUrl, imageLoader: wsImageLoader, + videoLoader: wsVideoLoader, resources: {}, breakpoints, // error reporting diff --git a/fixtures/react-router-cloudflare/app/routes/[another-page]._index.tsx b/fixtures/react-router-cloudflare/app/routes/[another-page]._index.tsx index a1ab01857d8e..17d3491d0b80 100644 --- a/fixtures/react-router-cloudflare/app/routes/[another-page]._index.tsx +++ b/fixtures/react-router-cloudflare/app/routes/[another-page]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[another-page]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/react-router-cloudflare/app/routes/_index.tsx b/fixtures/react-router-cloudflare/app/routes/_index.tsx index c9dc7e83ff77..dec09db55604 100644 --- a/fixtures/react-router-cloudflare/app/routes/_index.tsx +++ b/fixtures/react-router-cloudflare/app/routes/_index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/_index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/react-router-docker/app/routes/[another-page]._index.tsx b/fixtures/react-router-docker/app/routes/[another-page]._index.tsx index a1ab01857d8e..17d3491d0b80 100644 --- a/fixtures/react-router-docker/app/routes/[another-page]._index.tsx +++ b/fixtures/react-router-docker/app/routes/[another-page]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[another-page]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/react-router-docker/app/routes/_index.tsx b/fixtures/react-router-docker/app/routes/_index.tsx index c9dc7e83ff77..dec09db55604 100644 --- a/fixtures/react-router-docker/app/routes/_index.tsx +++ b/fixtures/react-router-docker/app/routes/_index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/_index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/react-router-netlify/app/routes/[another-page]._index.tsx b/fixtures/react-router-netlify/app/routes/[another-page]._index.tsx index a1ab01857d8e..17d3491d0b80 100644 --- a/fixtures/react-router-netlify/app/routes/[another-page]._index.tsx +++ b/fixtures/react-router-netlify/app/routes/[another-page]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[another-page]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/react-router-netlify/app/routes/_index.tsx b/fixtures/react-router-netlify/app/routes/_index.tsx index c9dc7e83ff77..dec09db55604 100644 --- a/fixtures/react-router-netlify/app/routes/_index.tsx +++ b/fixtures/react-router-netlify/app/routes/_index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/_index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/react-router-vercel/app/routes/[another-page]._index.tsx b/fixtures/react-router-vercel/app/routes/[another-page]._index.tsx index a1ab01857d8e..17d3491d0b80 100644 --- a/fixtures/react-router-vercel/app/routes/[another-page]._index.tsx +++ b/fixtures/react-router-vercel/app/routes/[another-page]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[another-page]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/react-router-vercel/app/routes/_index.tsx b/fixtures/react-router-vercel/app/routes/_index.tsx index c9dc7e83ff77..dec09db55604 100644 --- a/fixtures/react-router-vercel/app/routes/_index.tsx +++ b/fixtures/react-router-vercel/app/routes/_index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/_index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-cloudflare-template/app/routes/[another-page]._index.tsx b/fixtures/webstudio-cloudflare-template/app/routes/[another-page]._index.tsx index ac077c8564dd..8b285af2d9a7 100644 --- a/fixtures/webstudio-cloudflare-template/app/routes/[another-page]._index.tsx +++ b/fixtures/webstudio-cloudflare-template/app/routes/[another-page]._index.tsx @@ -37,7 +37,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[another-page]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -151,8 +151,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -167,7 +167,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -176,7 +176,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -271,8 +271,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-cloudflare-template/app/routes/_index.tsx b/fixtures/webstudio-cloudflare-template/app/routes/_index.tsx index f636f7fb56a3..98dfabad5346 100644 --- a/fixtures/webstudio-cloudflare-template/app/routes/_index.tsx +++ b/fixtures/webstudio-cloudflare-template/app/routes/_index.tsx @@ -37,7 +37,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/_index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -151,8 +151,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -167,7 +167,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -176,7 +176,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -271,8 +271,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[_route_with_symbols_]._index.tsx b/fixtures/webstudio-features/app/routes/[_route_with_symbols_]._index.tsx index a7677fa869ec..edc9ce20a752 100644 --- a/fixtures/webstudio-features/app/routes/[_route_with_symbols_]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[_route_with_symbols_]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[_route_with_symbols_]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[animations]._index.tsx b/fixtures/webstudio-features/app/routes/[animations]._index.tsx index 89415d5ad07a..e765d6ae7169 100644 --- a/fixtures/webstudio-features/app/routes/[animations]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[animations]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[animations]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[class-names]._index.tsx b/fixtures/webstudio-features/app/routes/[class-names]._index.tsx index 7200178cc4fa..b1f500d54174 100644 --- a/fixtures/webstudio-features/app/routes/[class-names]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[class-names]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[class-names]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[content-block]._index.tsx b/fixtures/webstudio-features/app/routes/[content-block]._index.tsx index 19b58fb925c2..4707da8caa18 100644 --- a/fixtures/webstudio-features/app/routes/[content-block]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[content-block]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[content-block]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[duration]._index.tsx b/fixtures/webstudio-features/app/routes/[duration]._index.tsx index df5f72ffef28..41ce6045d803 100644 --- a/fixtures/webstudio-features/app/routes/[duration]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[duration]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[duration]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[expressions]._index.tsx b/fixtures/webstudio-features/app/routes/[expressions]._index.tsx index 9f1b46705246..ea8fc413a6a1 100644 --- a/fixtures/webstudio-features/app/routes/[expressions]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[expressions]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[expressions]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[form]._index.tsx b/fixtures/webstudio-features/app/routes/[form]._index.tsx index 74b1787cea7f..1b5da5bec09b 100644 --- a/fixtures/webstudio-features/app/routes/[form]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[form]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[form]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[head-tag]._index.tsx b/fixtures/webstudio-features/app/routes/[head-tag]._index.tsx index ff56a506a11c..18a752310741 100644 --- a/fixtures/webstudio-features/app/routes/[head-tag]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[head-tag]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[head-tag]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[heading-with-id]._index.tsx b/fixtures/webstudio-features/app/routes/[heading-with-id]._index.tsx index 4e57e41bbf0a..88e4ae7fb778 100644 --- a/fixtures/webstudio-features/app/routes/[heading-with-id]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[heading-with-id]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[heading-with-id]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[nested].[nested-page]._index.tsx b/fixtures/webstudio-features/app/routes/[nested].[nested-page]._index.tsx index d09961d9ea28..ef970f1cdc90 100644 --- a/fixtures/webstudio-features/app/routes/[nested].[nested-page]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[nested].[nested-page]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[nested].[nested-page]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[radix]._index.tsx b/fixtures/webstudio-features/app/routes/[radix]._index.tsx index 3a3e9764d4e5..035aa84f2dc4 100644 --- a/fixtures/webstudio-features/app/routes/[radix]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[radix]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[radix]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[resources]._index.tsx b/fixtures/webstudio-features/app/routes/[resources]._index.tsx index 49fbbbaf905c..91664fecce12 100644 --- a/fixtures/webstudio-features/app/routes/[resources]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[resources]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[resources]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/[text-duration]._index.tsx b/fixtures/webstudio-features/app/routes/[text-duration]._index.tsx index bc4fb303eda6..eaf748752264 100644 --- a/fixtures/webstudio-features/app/routes/[text-duration]._index.tsx +++ b/fixtures/webstudio-features/app/routes/[text-duration]._index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/[text-duration]._index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/fixtures/webstudio-features/app/routes/_index.tsx b/fixtures/webstudio-features/app/routes/_index.tsx index c9dc7e83ff77..dec09db55604 100644 --- a/fixtures/webstudio-features/app/routes/_index.tsx +++ b/fixtures/webstudio-features/app/routes/_index.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "../__generated__/_index.server"; -import { assetBaseUrl, imageLoader } from "../constants.mjs"; +import * as constants from "../constants.mjs"; import css from "../__generated__/index.css?url"; import { sitemap } from "../__generated__/$resources.sitemap.xml"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/packages/cli/templates/defaults/app/route-templates/html.tsx b/packages/cli/templates/defaults/app/route-templates/html.tsx index 55f0e342db03..12581dcc3689 100644 --- a/packages/cli/templates/defaults/app/route-templates/html.tsx +++ b/packages/cli/templates/defaults/app/route-templates/html.tsx @@ -37,7 +37,7 @@ import { getRemixParams, contactEmail, } from "__SERVER__"; -import { assetBaseUrl, imageLoader } from "__CONSTANTS__"; +import * as constants from "__CONSTANTS__"; import css from "__CSS__?url"; import { sitemap } from "__SITEMAP__"; @@ -151,8 +151,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -167,7 +167,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -176,7 +176,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -271,8 +271,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/packages/cli/templates/react-router/app/route-templates/html.tsx b/packages/cli/templates/react-router/app/route-templates/html.tsx index e31c3fd6aae9..b9dbbbb84259 100644 --- a/packages/cli/templates/react-router/app/route-templates/html.tsx +++ b/packages/cli/templates/react-router/app/route-templates/html.tsx @@ -36,7 +36,7 @@ import { getRemixParams, contactEmail, } from "__SERVER__"; -import { assetBaseUrl, imageLoader } from "__CONSTANTS__"; +import * as constants from "__CONSTANTS__"; import css from "__CSS__?url"; import { sitemap } from "__SITEMAP__"; @@ -150,8 +150,8 @@ export const links: LinksFunction = () => { if (favIconAsset) { result.push({ rel: "icon", - href: imageLoader({ - src: `${assetBaseUrl}${favIconAsset}`, + href: constants.imageLoader({ + src: `${constants.assetBaseUrl}${favIconAsset}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, @@ -166,7 +166,7 @@ export const links: LinksFunction = () => { for (const asset of pageFontAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${asset}`, + href: `${constants.assetBaseUrl}${asset}`, as: "font", crossOrigin: "anonymous", }); @@ -175,7 +175,7 @@ export const links: LinksFunction = () => { for (const backgroundImageAsset of pageBackgroundImageAssets) { result.push({ rel: "preload", - href: `${assetBaseUrl}${backgroundImageAsset}`, + href: `${constants.assetBaseUrl}${backgroundImageAsset}`, as: "image", }); } @@ -270,8 +270,7 @@ const Outlet = () => { return ( { pageMeta={pageMeta} host={host} siteName={siteName} - imageLoader={imageLoader} - assetBaseUrl={assetBaseUrl} + imageLoader={constants.imageLoader} + assetBaseUrl={constants.assetBaseUrl} /> {pageMeta.title} diff --git a/packages/image/src/image-loaders.ts b/packages/image/src/image-loaders.ts index 555fed111aa7..c0e37d31c867 100644 --- a/packages/image/src/image-loaders.ts +++ b/packages/image/src/image-loaders.ts @@ -60,3 +60,12 @@ export const wsImageLoader: ImageLoader = (props) => { // Cloudflare docs say that we don't need to urlencode the path params return resultUrl.href; }; + +export type VideoLoader = (options: { src: string }) => string; + +export const wsVideoLoader: VideoLoader = ({ src }) => { + if (src.startsWith("/cgi/asset")) { + src = src.slice("/cgi/asset".length); + } + return `/cgi/video/${src}`; +}; diff --git a/packages/react-sdk/placeholder.d.ts b/packages/react-sdk/placeholder.d.ts index c49f48f75caf..5cb28b269c65 100644 --- a/packages/react-sdk/placeholder.d.ts +++ b/packages/react-sdk/placeholder.d.ts @@ -1,7 +1,8 @@ declare module "__CONSTANTS__" { - import type { ImageLoader } from "@webstudio-is/image"; + import type { ImageLoader, VideoLoader } from "@webstudio-is/image"; export const assetBaseUrl: string; export const imageLoader: ImageLoader; + export const videoLoader: undefined | VideoLoader; } declare module "__CLIENT__" { diff --git a/packages/react-sdk/src/context.tsx b/packages/react-sdk/src/context.tsx index 9ca2d1148a8b..0d760361676a 100644 --- a/packages/react-sdk/src/context.tsx +++ b/packages/react-sdk/src/context.tsx @@ -1,5 +1,5 @@ import { createContext, useContext, useMemo } from "react"; -import type { ImageLoader } from "@webstudio-is/image"; +import type { ImageLoader, VideoLoader } from "@webstudio-is/image"; import { createJsonStringifyProxy, isPlainObject, @@ -29,6 +29,7 @@ export type Params = { export const ReactSdkContext = createContext< Params & { imageLoader: ImageLoader; + videoLoader?: VideoLoader; // resources need to be any to support accessing unknown fields without extra checks // eslint-disable-next-line @typescript-eslint/no-explicit-any resources: Record; @@ -38,6 +39,7 @@ export const ReactSdkContext = createContext< >({ assetBaseUrl: "/", imageLoader: ({ src }) => src, + videoLoader: ({ src }) => src, resources: {}, breakpoints: [], onError: (error) => { diff --git a/packages/sdk-components-react/src/video.tsx b/packages/sdk-components-react/src/video.tsx index fab3d7146768..41a5d933fb42 100644 --- a/packages/sdk-components-react/src/video.tsx +++ b/packages/sdk-components-react/src/video.tsx @@ -48,11 +48,11 @@ export const Video = forwardRef< const videoIdProps = { [videoIdAttribute]: id, }; - const { assetBaseUrl } = useContext(ReactSdkContext); + const { videoLoader } = useContext(ReactSdkContext); - const src = srcProp?.startsWith(assetBaseUrl) - ? `/cgi/video/${srcProp.slice(assetBaseUrl.length)}` - : srcProp; + // fallback to provided src + const src = + srcProp && videoLoader ? videoLoader({ src: srcProp }) : undefined; useEffect(() => { if ($progress === undefined) { From 0a26aabc38eabfa957a993da8bc923e199e54ecd Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 2 Aug 2025 18:33:38 +0200 Subject: [PATCH 2/3] Trigger rebuild From b49781b78b631cff8a4f1e928864a88ae384769f Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 2 Aug 2025 18:48:34 +0200 Subject: [PATCH 3/3] Fix double slash --- packages/image/src/image-loaders.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/image/src/image-loaders.ts b/packages/image/src/image-loaders.ts index c0e37d31c867..8e614ff29594 100644 --- a/packages/image/src/image-loaders.ts +++ b/packages/image/src/image-loaders.ts @@ -64,8 +64,8 @@ export const wsImageLoader: ImageLoader = (props) => { export type VideoLoader = (options: { src: string }) => string; export const wsVideoLoader: VideoLoader = ({ src }) => { - if (src.startsWith("/cgi/asset")) { - src = src.slice("/cgi/asset".length); + if (src.startsWith("/cgi/asset/")) { + src = src.slice("/cgi/asset/".length); } return `/cgi/video/${src}`; };