From f495363f01f88cc4417cd444655b8144c2b6f421 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 5 Jan 2025 17:50:12 +0700 Subject: [PATCH] fix: resolve favicon images properly (#4712) Fixes https://github.com/webstudio-is/webstudio/issues/4443 --- .../ssg-netlify-by-project-id/app/constants.mjs | 17 +++++++++-------- .../pages/index/+Head.tsx | 2 +- fixtures/ssg/pages/another-page/+Head.tsx | 2 +- fixtures/ssg/pages/index/+Head.tsx | 2 +- .../app/routes/[another-page]._index.tsx | 2 +- .../app/routes/_index.tsx | 2 +- .../app/routes/[script-test]._index.tsx | 2 +- .../app/routes/[world]._index.tsx | 2 +- .../app/routes/_index.tsx | 2 +- .../app/constants.mjs | 17 +++++++++-------- .../app/routes/[another-page]._index.tsx | 2 +- .../app/routes/_index.tsx | 2 +- .../.webstudio/data.json | 16 +++++++++------- .../app/__generated__/$resources.sitemap.xml.ts | 2 +- .../app/__generated__/[another-page]._index.tsx | 12 +++++++++++- .../app/__generated__/_index.tsx | 12 +++++++++++- .../app/constants.mjs | 17 +++++++++-------- .../app/routes/[another-page]._index.tsx | 2 +- .../app/routes/_index.tsx | 2 +- .../package.json | 4 ++-- .../webstudio-remix-vercel/app/constants.mjs | 13 +++++-------- .../routes/[_route_with_symbols_]._index.tsx | 2 +- .../app/routes/[class-names]._index.tsx | 2 +- .../app/routes/[content-block]._index.tsx | 2 +- .../app/routes/[expressions]._index.tsx | 2 +- .../app/routes/[form]._index.tsx | 2 +- .../app/routes/[heading-with-id]._index.tsx | 2 +- .../routes/[nested].[nested-page]._index.tsx | 2 +- .../app/routes/[radix]._index.tsx | 2 +- .../app/routes/[resources]._index.tsx | 2 +- .../app/routes/_index.tsx | 2 +- .../defaults/app/route-templates/html.tsx | 2 +- .../netlify-edge-functions/app/constants.mjs | 17 +++++++++-------- .../netlify-functions/app/constants.mjs | 17 +++++++++-------- .../templates/netlify-functions/package.json | 2 +- .../cli/templates/ssg-netlify/app/constants.mjs | 17 +++++++++-------- .../cli/templates/ssg-vercel/app/constants.mjs | 13 +++++-------- .../ssg/app/route-templates/html/+Head.tsx | 2 +- packages/cli/templates/vercel/app/constants.mjs | 13 +++++-------- 39 files changed, 128 insertions(+), 109 deletions(-) diff --git a/fixtures/ssg-netlify-by-project-id/app/constants.mjs b/fixtures/ssg-netlify-by-project-id/app/constants.mjs index 12bd87557169..cee72e5d3a4b 100644 --- a/fixtures/ssg-netlify-by-project-id/app/constants.mjs +++ b/fixtures/ssg-netlify-by-project-id/app/constants.mjs @@ -24,12 +24,13 @@ export const imageLoader = (props) => { } // https://docs.netlify.com/image-cdn/overview/ - return ( - "/.netlify/images?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + if (props.height) { + searchParams.set("h", props.height.toString()); + } + searchParams.set("q", props.quality.toString()); + // fit=contain by default + return `/.netlify/images?${searchParams}`; }; diff --git a/fixtures/ssg-netlify-by-project-id/pages/index/+Head.tsx b/fixtures/ssg-netlify-by-project-id/pages/index/+Head.tsx index 4f59a43abedb..99f78d65edd3 100644 --- a/fixtures/ssg-netlify-by-project-id/pages/index/+Head.tsx +++ b/fixtures/ssg-netlify-by-project-id/pages/index/+Head.tsx @@ -60,7 +60,7 @@ export const Head = ({ data }: { data: PageContext["data"] }) => { { { { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-cloudflare-template/app/routes/_index.tsx b/fixtures/webstudio-cloudflare-template/app/routes/_index.tsx index 3d6064483e85..66ad6094c1cf 100644 --- a/fixtures/webstudio-cloudflare-template/app/routes/_index.tsx +++ b/fixtures/webstudio-cloudflare-template/app/routes/_index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-custom-template/app/routes/[script-test]._index.tsx b/fixtures/webstudio-custom-template/app/routes/[script-test]._index.tsx index 4d61ca9dc02c..4f9802a30674 100644 --- a/fixtures/webstudio-custom-template/app/routes/[script-test]._index.tsx +++ b/fixtures/webstudio-custom-template/app/routes/[script-test]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-custom-template/app/routes/[world]._index.tsx b/fixtures/webstudio-custom-template/app/routes/[world]._index.tsx index 6f656ae79c5a..7327e076c731 100644 --- a/fixtures/webstudio-custom-template/app/routes/[world]._index.tsx +++ b/fixtures/webstudio-custom-template/app/routes/[world]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-custom-template/app/routes/_index.tsx b/fixtures/webstudio-custom-template/app/routes/_index.tsx index 3d6064483e85..66ad6094c1cf 100644 --- a/fixtures/webstudio-custom-template/app/routes/_index.tsx +++ b/fixtures/webstudio-custom-template/app/routes/_index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-netlify-edge-functions/app/constants.mjs b/fixtures/webstudio-remix-netlify-edge-functions/app/constants.mjs index ea957793b6bd..a288e7c5dce0 100644 --- a/fixtures/webstudio-remix-netlify-edge-functions/app/constants.mjs +++ b/fixtures/webstudio-remix-netlify-edge-functions/app/constants.mjs @@ -18,12 +18,13 @@ export const imageLoader = (props) => { } // https://docs.netlify.com/image-cdn/overview/ - return ( - "/.netlify/images?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + if (props.height) { + searchParams.set("h", props.height.toString()); + } + searchParams.set("q", props.quality.toString()); + // fit=contain by default + return `/.netlify/images?${searchParams}`; }; diff --git a/fixtures/webstudio-remix-netlify-edge-functions/app/routes/[another-page]._index.tsx b/fixtures/webstudio-remix-netlify-edge-functions/app/routes/[another-page]._index.tsx index 9d3f956df026..c4fca377af35 100644 --- a/fixtures/webstudio-remix-netlify-edge-functions/app/routes/[another-page]._index.tsx +++ b/fixtures/webstudio-remix-netlify-edge-functions/app/routes/[another-page]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-netlify-edge-functions/app/routes/_index.tsx b/fixtures/webstudio-remix-netlify-edge-functions/app/routes/_index.tsx index 3d6064483e85..66ad6094c1cf 100644 --- a/fixtures/webstudio-remix-netlify-edge-functions/app/routes/_index.tsx +++ b/fixtures/webstudio-remix-netlify-edge-functions/app/routes/_index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-netlify-functions/.webstudio/data.json b/fixtures/webstudio-remix-netlify-functions/.webstudio/data.json index 8f97956ab8a2..7dc933cfb601 100644 --- a/fixtures/webstudio-remix-netlify-functions/.webstudio/data.json +++ b/fixtures/webstudio-remix-netlify-functions/.webstudio/data.json @@ -1,14 +1,14 @@ { "build": { - "id": "a2e8de30-03d5-4514-a3a6-406b3266a3af", + "id": "f565d527-32e7-4731-bc71-aca9e9574587", "projectId": "d845c167-ea07-4875-b08d-83e97c09dcce", - "version": 38, - "createdAt": "2024-07-29T12:50:07.515+00:00", - "updatedAt": "2024-07-29T12:50:07.515+00:00", + "version": 43, + "createdAt": "2025-01-04T11:01:50.091+00:00", + "updatedAt": "2025-01-04T11:01:50.091+00:00", "pages": { "meta": { "siteName": "", - "faviconAssetId": "", + "faviconAssetId": "d0974db9300c1a3b0fb8b291dd9fabd45ad136478908394280af2f7087e3aecd", "code": "" }, "homePage": { @@ -408,8 +408,10 @@ ] ], "deployment": { - "domains": [], - "projectDomain": "cli-basic-test-d0osr" + "destination": "saas", + "domains": ["cli-basic-test-d0osr"], + "assetsDomain": "cli-basic-test-d0osr", + "excludeWstdDomainFromSearch": false } }, "page": { diff --git a/fixtures/webstudio-remix-netlify-functions/app/__generated__/$resources.sitemap.xml.ts b/fixtures/webstudio-remix-netlify-functions/app/__generated__/$resources.sitemap.xml.ts index 9b3f4dfa6d99..181eac4621f3 100644 --- a/fixtures/webstudio-remix-netlify-functions/app/__generated__/$resources.sitemap.xml.ts +++ b/fixtures/webstudio-remix-netlify-functions/app/__generated__/$resources.sitemap.xml.ts @@ -1,6 +1,6 @@ export const sitemap = [ { path: "/", - lastModified: "2024-07-29", + lastModified: "2025-01-04", }, ]; diff --git a/fixtures/webstudio-remix-netlify-functions/app/__generated__/[another-page]._index.tsx b/fixtures/webstudio-remix-netlify-functions/app/__generated__/[another-page]._index.tsx index bd1885228679..06f808e479a9 100644 --- a/fixtures/webstudio-remix-netlify-functions/app/__generated__/[another-page]._index.tsx +++ b/fixtures/webstudio-remix-netlify-functions/app/__generated__/[another-page]._index.tsx @@ -9,7 +9,17 @@ import { Heading as Heading } from "@webstudio-is/sdk-components-react"; export const siteName = ""; -export const favIconAsset: ImageAsset | undefined = undefined; +export const favIconAsset: ImageAsset | undefined = { + id: "d0974db9300c1a3b0fb8b291dd9fabd45ad136478908394280af2f7087e3aecd", + name: "147-1478573_cat-icon-png-black-cat-png-icon.png_ZJ6-qJjk1RlFzuYwyCXdp.jpeg", + description: null, + projectId: "d845c167-ea07-4875-b08d-83e97c09dcce", + size: 64701, + type: "image", + format: "jpg", + createdAt: "2024-12-06T14:36:07.046+00:00", + meta: { width: 820, height: 985 }, +}; // Font assets on current page (can be preloaded) export const pageFontAssets: FontAsset[] = []; diff --git a/fixtures/webstudio-remix-netlify-functions/app/__generated__/_index.tsx b/fixtures/webstudio-remix-netlify-functions/app/__generated__/_index.tsx index 6563f87af5f1..295d3171e5c3 100644 --- a/fixtures/webstudio-remix-netlify-functions/app/__generated__/_index.tsx +++ b/fixtures/webstudio-remix-netlify-functions/app/__generated__/_index.tsx @@ -16,7 +16,17 @@ import { export const siteName = ""; -export const favIconAsset: ImageAsset | undefined = undefined; +export const favIconAsset: ImageAsset | undefined = { + id: "d0974db9300c1a3b0fb8b291dd9fabd45ad136478908394280af2f7087e3aecd", + name: "147-1478573_cat-icon-png-black-cat-png-icon.png_ZJ6-qJjk1RlFzuYwyCXdp.jpeg", + description: null, + projectId: "d845c167-ea07-4875-b08d-83e97c09dcce", + size: 64701, + type: "image", + format: "jpg", + createdAt: "2024-12-06T14:36:07.046+00:00", + meta: { width: 820, height: 985 }, +}; // Font assets on current page (can be preloaded) export const pageFontAssets: FontAsset[] = []; diff --git a/fixtures/webstudio-remix-netlify-functions/app/constants.mjs b/fixtures/webstudio-remix-netlify-functions/app/constants.mjs index ea957793b6bd..a288e7c5dce0 100644 --- a/fixtures/webstudio-remix-netlify-functions/app/constants.mjs +++ b/fixtures/webstudio-remix-netlify-functions/app/constants.mjs @@ -18,12 +18,13 @@ export const imageLoader = (props) => { } // https://docs.netlify.com/image-cdn/overview/ - return ( - "/.netlify/images?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + if (props.height) { + searchParams.set("h", props.height.toString()); + } + searchParams.set("q", props.quality.toString()); + // fit=contain by default + return `/.netlify/images?${searchParams}`; }; diff --git a/fixtures/webstudio-remix-netlify-functions/app/routes/[another-page]._index.tsx b/fixtures/webstudio-remix-netlify-functions/app/routes/[another-page]._index.tsx index 9d3f956df026..c4fca377af35 100644 --- a/fixtures/webstudio-remix-netlify-functions/app/routes/[another-page]._index.tsx +++ b/fixtures/webstudio-remix-netlify-functions/app/routes/[another-page]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-netlify-functions/app/routes/_index.tsx b/fixtures/webstudio-remix-netlify-functions/app/routes/_index.tsx index 3d6064483e85..66ad6094c1cf 100644 --- a/fixtures/webstudio-remix-netlify-functions/app/routes/_index.tsx +++ b/fixtures/webstudio-remix-netlify-functions/app/routes/_index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-netlify-functions/package.json b/fixtures/webstudio-remix-netlify-functions/package.json index 8865e9782c16..472a00928443 100644 --- a/fixtures/webstudio-remix-netlify-functions/package.json +++ b/fixtures/webstudio-remix-netlify-functions/package.json @@ -2,11 +2,11 @@ "scripts": { "build": "remix vite:build", "dev": "remix vite:dev", - "start": "netlify serve", + "start": "npx netlify-cli serve", "typecheck": "tsc", "cli": "NODE_OPTIONS='--conditions=webstudio --import=tsx' webstudio", "fixtures:link": "pnpm cli link --link https://p-d845c167-ea07-4875-b08d-83e97c09dcce-dot-${BUILDER_HOST:-main.development.webstudio.is}'?authToken=e9d1343f-9298-4fd3-a66e-f89a5af2dd93'", - "fixtures:sync": "pnpm cli sync --buildId a2e8de30-03d5-4514-a3a6-406b3266a3af && pnpm prettier --write ./.webstudio/", + "fixtures:sync": "pnpm cli sync --buildId f565d527-32e7-4731-bc71-aca9e9574587 && pnpm prettier --write ./.webstudio/", "fixtures:build": "pnpm cli build --template netlify-functions --template internal && pnpm prettier --write ./app/ ./package.json ./tsconfig.json" }, "dependencies": { diff --git a/fixtures/webstudio-remix-vercel/app/constants.mjs b/fixtures/webstudio-remix-vercel/app/constants.mjs index 7a8ec5918977..47140fba63a9 100644 --- a/fixtures/webstudio-remix-vercel/app/constants.mjs +++ b/fixtures/webstudio-remix-vercel/app/constants.mjs @@ -18,12 +18,9 @@ export const imageLoader = (props) => { } // https://vercel.com/blog/build-your-own-web-framework#automatic-image-optimization - return ( - "/_vercel/image?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + searchParams.set("q", props.quality.toString()); + return `/_vercel/image?${searchParams}`; }; diff --git a/fixtures/webstudio-remix-vercel/app/routes/[_route_with_symbols_]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[_route_with_symbols_]._index.tsx index cf14a1d6c7b2..635a9f5d5e41 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[_route_with_symbols_]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[_route_with_symbols_]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/[class-names]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[class-names]._index.tsx index 2120cca70aa5..6aa9522fdd7d 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[class-names]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[class-names]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/[content-block]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[content-block]._index.tsx index 9ce8af978fa1..ccca776d7ec8 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[content-block]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[content-block]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/[expressions]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[expressions]._index.tsx index d7d99a1a0620..6f39a6cff5df 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[expressions]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[expressions]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/[form]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[form]._index.tsx index 20e3231a4e05..5044ea9b9f63 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[form]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[form]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/[heading-with-id]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[heading-with-id]._index.tsx index 253829316807..9267491354c3 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[heading-with-id]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[heading-with-id]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/[nested].[nested-page]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[nested].[nested-page]._index.tsx index 5dd0482e937f..794b17c56223 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[nested].[nested-page]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[nested].[nested-page]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/[radix]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[radix]._index.tsx index 9f8c837c30aa..91c2fb8ea014 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[radix]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[radix]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/[resources]._index.tsx b/fixtures/webstudio-remix-vercel/app/routes/[resources]._index.tsx index b2f3bfa9b350..e4c5605967d4 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/[resources]._index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/[resources]._index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/fixtures/webstudio-remix-vercel/app/routes/_index.tsx b/fixtures/webstudio-remix-vercel/app/routes/_index.tsx index 3d6064483e85..66ad6094c1cf 100644 --- a/fixtures/webstudio-remix-vercel/app/routes/_index.tsx +++ b/fixtures/webstudio-remix-vercel/app/routes/_index.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/packages/cli/templates/defaults/app/route-templates/html.tsx b/packages/cli/templates/defaults/app/route-templates/html.tsx index 434fb8802aa7..d05f3b9bce89 100644 --- a/packages/cli/templates/defaults/app/route-templates/html.tsx +++ b/packages/cli/templates/defaults/app/route-templates/html.tsx @@ -205,7 +205,7 @@ export const links: LinksFunction = () => { result.push({ rel: "icon", href: imageLoader({ - src: favIconAsset.name, + src: `${assetBaseUrl}${favIconAsset.name}`, // width,height must be multiple of 48 https://developers.google.com/search/docs/appearance/favicon-in-search width: 144, height: 144, diff --git a/packages/cli/templates/netlify-edge-functions/app/constants.mjs b/packages/cli/templates/netlify-edge-functions/app/constants.mjs index ea957793b6bd..a288e7c5dce0 100644 --- a/packages/cli/templates/netlify-edge-functions/app/constants.mjs +++ b/packages/cli/templates/netlify-edge-functions/app/constants.mjs @@ -18,12 +18,13 @@ export const imageLoader = (props) => { } // https://docs.netlify.com/image-cdn/overview/ - return ( - "/.netlify/images?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + if (props.height) { + searchParams.set("h", props.height.toString()); + } + searchParams.set("q", props.quality.toString()); + // fit=contain by default + return `/.netlify/images?${searchParams}`; }; diff --git a/packages/cli/templates/netlify-functions/app/constants.mjs b/packages/cli/templates/netlify-functions/app/constants.mjs index ea957793b6bd..a288e7c5dce0 100644 --- a/packages/cli/templates/netlify-functions/app/constants.mjs +++ b/packages/cli/templates/netlify-functions/app/constants.mjs @@ -18,12 +18,13 @@ export const imageLoader = (props) => { } // https://docs.netlify.com/image-cdn/overview/ - return ( - "/.netlify/images?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + if (props.height) { + searchParams.set("h", props.height.toString()); + } + searchParams.set("q", props.quality.toString()); + // fit=contain by default + return `/.netlify/images?${searchParams}`; }; diff --git a/packages/cli/templates/netlify-functions/package.json b/packages/cli/templates/netlify-functions/package.json index 372be2dbe510..6de9191f263d 100644 --- a/packages/cli/templates/netlify-functions/package.json +++ b/packages/cli/templates/netlify-functions/package.json @@ -1,6 +1,6 @@ { "scripts": { - "start": "netlify serve" + "start": "npx netlify-cli serve" }, "dependencies": { "@netlify/functions": "^2.8.2", diff --git a/packages/cli/templates/ssg-netlify/app/constants.mjs b/packages/cli/templates/ssg-netlify/app/constants.mjs index 12bd87557169..cee72e5d3a4b 100644 --- a/packages/cli/templates/ssg-netlify/app/constants.mjs +++ b/packages/cli/templates/ssg-netlify/app/constants.mjs @@ -24,12 +24,13 @@ export const imageLoader = (props) => { } // https://docs.netlify.com/image-cdn/overview/ - return ( - "/.netlify/images?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + if (props.height) { + searchParams.set("h", props.height.toString()); + } + searchParams.set("q", props.quality.toString()); + // fit=contain by default + return `/.netlify/images?${searchParams}`; }; diff --git a/packages/cli/templates/ssg-vercel/app/constants.mjs b/packages/cli/templates/ssg-vercel/app/constants.mjs index 7024371ed6ec..6ec2f904e945 100644 --- a/packages/cli/templates/ssg-vercel/app/constants.mjs +++ b/packages/cli/templates/ssg-vercel/app/constants.mjs @@ -24,12 +24,9 @@ export const imageLoader = (props) => { } // https://vercel.com/blog/build-your-own-web-framework#automatic-image-optimization - return ( - "/_vercel/image?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + searchParams.set("q", props.quality.toString()); + return `/_vercel/image?${searchParams}`; }; diff --git a/packages/cli/templates/ssg/app/route-templates/html/+Head.tsx b/packages/cli/templates/ssg/app/route-templates/html/+Head.tsx index f97fa1329a09..1b0f4f18774b 100644 --- a/packages/cli/templates/ssg/app/route-templates/html/+Head.tsx +++ b/packages/cli/templates/ssg/app/route-templates/html/+Head.tsx @@ -60,7 +60,7 @@ export const Head = ({ data }: { data: PageContext["data"] }) => { { } // https://vercel.com/blog/build-your-own-web-framework#automatic-image-optimization - return ( - "/_vercel/image?url=" + - encodeURIComponent(props.src) + - "&w=" + - props.width + - "&q=" + - props.quality - ); + const searchParams = new URLSearchParams(); + searchParams.set("url", props.src); + searchParams.set("w", props.width.toString()); + searchParams.set("q", props.quality.toString()); + return `/_vercel/image?${searchParams}`; };