From 97a682fb92bd203d8803ed12716ad299806504e5 Mon Sep 17 00:00:00 2001 From: Fatih Altinok Date: Mon, 30 Sep 2024 05:31:42 +0300 Subject: [PATCH 01/17] [skeleton] Close aside when Esc is pressed (#2503) --- templates/skeleton/app/components/Aside.tsx | 25 ++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/templates/skeleton/app/components/Aside.tsx b/templates/skeleton/app/components/Aside.tsx index c535668ba3..4b0a95d659 100644 --- a/templates/skeleton/app/components/Aside.tsx +++ b/templates/skeleton/app/components/Aside.tsx @@ -1,4 +1,10 @@ -import {createContext, type ReactNode, useContext, useState} from 'react'; +import { + createContext, + type ReactNode, + useContext, + useEffect, + useState, +} from 'react'; type AsideType = 'search' | 'cart' | 'mobile' | 'closed'; type AsideContextValue = { @@ -29,6 +35,23 @@ export function Aside({ const {type: activeType, close} = useAside(); const expanded = type === activeType; + useEffect(() => { + const abortController = new AbortController(); + + if (expanded) { + document.addEventListener( + 'keydown', + function handler(event: KeyboardEvent) { + if (event.key === 'Escape') { + close(); + } + }, + {signal: abortController.signal}, + ); + } + return () => abortController.abort(); + }, [close, expanded]); + return (
Date: Mon, 30 Sep 2024 05:40:53 +0300 Subject: [PATCH 02/17] [skeleton] Make cart banner optimistic (#2502) --- templates/skeleton/app/components/Header.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/templates/skeleton/app/components/Header.tsx b/templates/skeleton/app/components/Header.tsx index 09fba1dc6f..8a437a1000 100644 --- a/templates/skeleton/app/components/Header.tsx +++ b/templates/skeleton/app/components/Header.tsx @@ -1,6 +1,10 @@ import {Suspense} from 'react'; -import {Await, NavLink} from '@remix-run/react'; -import {type CartViewPayload, useAnalytics} from '@shopify/hydrogen'; +import {Await, NavLink, useAsyncValue} from '@remix-run/react'; +import { + type CartViewPayload, + useAnalytics, + useOptimisticCart, +} from '@shopify/hydrogen'; import type {HeaderQuery, CartApiQueryFragment} from 'storefrontapi.generated'; import {useAside} from '~/components/Aside'; @@ -159,15 +163,18 @@ function CartToggle({cart}: Pick) { return ( }> - {(cart) => { - if (!cart) return ; - return ; - }} + ); } +function CartBanner() { + const originalCart = useAsyncValue() as CartApiQueryFragment | null; + const cart = useOptimisticCart(originalCart); + return ; +} + const FALLBACK_HEADER_MENU = { id: 'gid://shopify/Menu/199655587896', items: [ From 0bc154c92e2bf636e99fa22557a18a89c6546c1e Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 2 Oct 2024 07:55:29 +0900 Subject: [PATCH 03/17] Add more comments around workerd usage (#2575) * Add clarifications around MiniOxygen and workerd * More comments --- packages/mini-oxygen/src/worker/assets.ts | 4 ++ packages/mini-oxygen/src/worker/devtools.ts | 37 +++++++++++++++--- packages/mini-oxygen/src/worker/handler.ts | 9 ++++- packages/mini-oxygen/src/worker/index.ts | 26 +++++++++++++ packages/mini-oxygen/src/worker/inspector.ts | 21 ++++++++++ packages/mini-oxygen/src/worker/logger.ts | 41 ++++++++++++++++---- 6 files changed, 124 insertions(+), 14 deletions(-) diff --git a/packages/mini-oxygen/src/worker/assets.ts b/packages/mini-oxygen/src/worker/assets.ts index ec267218df..84ff3faf19 100644 --- a/packages/mini-oxygen/src/worker/assets.ts +++ b/packages/mini-oxygen/src/worker/assets.ts @@ -21,6 +21,10 @@ export function buildAssetsUrl(assetsPort: number) { /** * Creates a server that serves static assets from the build directory. * Mimics Shopify CDN URLs for Oxygen v2. + * Note: this is not used when running with Vite because it already + * serves transformed assets before reaching MiniOxygen. + * See the following for more details: + * https://github.com/Shopify/hydrogen/pull/2078#issuecomment-2121705993 */ export function createAssetsServer(assetsDirectory: string) { return createServer(async (req: IncomingMessage, res: ServerResponse) => { diff --git a/packages/mini-oxygen/src/worker/devtools.ts b/packages/mini-oxygen/src/worker/devtools.ts index 99979f28ee..7bc84e6b47 100644 --- a/packages/mini-oxygen/src/worker/devtools.ts +++ b/packages/mini-oxygen/src/worker/devtools.ts @@ -20,6 +20,14 @@ const FAVICON_URL = export type InspectorProxy = ReturnType; +/** + * Creates a proxy server that forwards messages between the local + * debugger (e.g. VSCode, Browser DevTools) and the Workerd inspector. + * It also serves a custom in-browser DevTools UI for MiniOxygen by + * proxying the Cloudflare DevTools (used in Wrangler / Miniflare), + * and fixes a few issues related to serving this tool locally. + * + */ export function createInspectorProxy( port: number, newInspectorConnection: InspectorConnection, @@ -45,13 +53,15 @@ export function createInspectorProxy( const sourceMapPathname = '/__index.js.map'; const sourceMapURL = `http://localhost:${port}${sourceMapPathname}`; + // Create the proxy server used when running with `--debug` flag: const server = createServer((req: IncomingMessage, res: ServerResponse) => { // Remove query params. E.g. `/json/list?for_tab` const [url = '/', queryString = ''] = req.url?.split('?') || []; switch (url) { - // We implement a couple of well known end points - // that are queried for metadata by chrome://inspect + // We implement a couple of well known end points that are queried + // for metadata when opening `chrome://inspect` in the browser. + // https://chromedevtools.github.io/devtools-protocol/#endpoints case '/json/version': res.setHeader('Content-Type', 'application/json'); res.end( @@ -84,7 +94,9 @@ export function createInspectorProxy( } return; case sourceMapPathname: - // Handle proxied sourcemaps + // Handle proxied sourcemaps. This is only used when serving + // a built application in h2:preview or classic project dev. + // h2:dev with Vite uses inlined sourcemaps instead. res.setHeader('Content-Type', 'text/plain'); res.setHeader('Cache-Control', 'no-store'); res.setHeader( @@ -100,6 +112,7 @@ export function createInspectorProxy( } break; case '/favicon.ico': + // The browser requests for this automatically when opening DevTools. proxyHttp(FAVICON_URL, req.headers, res); break; case '/': @@ -112,7 +125,7 @@ export function createInspectorProxy( ); res.end(); } else { - // Proxy CFW DevTools UI. + // Proxy the main page of the original CFW DevTools UI. proxyHttp( CFW_DEVTOOLS + '/js_app', req.headers, @@ -128,6 +141,7 @@ export function createInspectorProxy( } break; default: + // Proxy assets from the original CFW DevTools UI, modifying them as needed. if ( url === '/panels/sources/sources-meta.js' || (url.startsWith('/core/i18n/locales/') && url.endsWith('.json')) @@ -157,7 +171,8 @@ export function createInspectorProxy( wsServer.on('connection', (ws, req) => { if (wsServer.clients.size > 1) { - // Only support one active Devtools instance at a time. + // Only support one active DevTools instance at a time. E.g. + // either VSCode/editor debugger or 1 browser DevTools tab. console.error( 'Tried to open a new devtools window when a previous one was already open.', ); @@ -190,12 +205,22 @@ export function createInspectorProxy( if (inspector.ws) onInspectorConnection(); + /** + * This function is called when the inspector connection is established + * for the first time or when the inspector is reconnected. That happens + * when the source code is reloaded in h2:preview, h2:debug:cpu. + * However, it no longer happens in h2:dev with Vite because the worker + * instance is not reloaded after source code changes, only patched with HMR. + */ function onInspectorConnection() { inspector.ws.addEventListener('message', sendMessageToDebugger); // In case this is a DevTools connection, send a warning // message to the console to inform about reconnection. // VSCode can reconnect automatically with `restart: true`. + // > TODO: it would be good to send this message also in h2:dev with Vite. + // > However, that requires a completely different type of wiring: + // > Getting Vite's HMR notifications from this part of the code somehow. debuggerWs?.send( JSON.stringify({ method: 'Runtime.consoleAPICalled', @@ -234,6 +259,8 @@ export function createInspectorProxy( } return { + // Every time workerd is restarted (e.g. env var change, etc.), + // the inspector connection needs to be re-established. updateInspectorConnection(newConnection: InspectorConnection) { inspector = newConnection; onInspectorConnection(); diff --git a/packages/mini-oxygen/src/worker/handler.ts b/packages/mini-oxygen/src/worker/handler.ts index 9d6db740d2..2ae7aae796 100644 --- a/packages/mini-oxygen/src/worker/handler.ts +++ b/packages/mini-oxygen/src/worker/handler.ts @@ -12,7 +12,14 @@ export function getMiniOxygenHandlerScript() { return `export default { fetch: ${miniOxygenHandler} }\n${withRequestHook}`; } -// This function is stringified, do not use anything from outer scope here: +/** + * Main entry point for the worker. It serves as a router, dispatching requests + * to the appropriate handlers, but also to handle common cases like static assets + * and polyfills Oxygen headers. + * + * Since this function is stringified and executed in the "worker", do not + * add anything from the outer scope here. + */ async function miniOxygenHandler( request: Request, env: MiniOxygenHandlerEnv, diff --git a/packages/mini-oxygen/src/worker/index.ts b/packages/mini-oxygen/src/worker/index.ts index 06701b6e4c..8e61e5556d 100644 --- a/packages/mini-oxygen/src/worker/index.ts +++ b/packages/mini-oxygen/src/worker/index.ts @@ -67,15 +67,41 @@ type GetNewOptions = ( ) => ReloadableOptions | Promise; export type MiniOxygenOptions = InputMiniflareOptions & { + /** + * Allows attaching a debugger to the worker instance. + * @default false + */ debug?: boolean; + /** + * Path to the source map file to use in debuggers, if needed. + * @default undefined + */ sourceMapPath?: string; + /** + * Allows serving static assets from a directory or another origin. + * @default undefined + */ assets?: AssetOptions; + /** + * Hook into requests and responses. Useful for debugging and logging. + * @default undefined + */ requestHook?: RequestHook | null; + /** + * Name of the worker used for attaching a debugger. + * @default undefined The first worker in the array is used. + */ inspectWorkerName?: string; }; export type MiniOxygenInstance = ReturnType; +/** + * Creates a MiniOxygen instance using the Workers runtime (workerd). + * + * @param options - Options for the MiniOxygen instance. + * @returns A MiniOxygen instance. + */ export function createMiniOxygen({ debug = false, inspectorPort, diff --git a/packages/mini-oxygen/src/worker/inspector.ts b/packages/mini-oxygen/src/worker/inspector.ts index e82abf2c7b..3e9f42eb80 100644 --- a/packages/mini-oxygen/src/worker/inspector.ts +++ b/packages/mini-oxygen/src/worker/inspector.ts @@ -46,6 +46,20 @@ export interface ErrorProperties { stack?: string; } +/** + * Creates a connection to the workerd inspector. + * + * The messages are sent via WebSockets following the Chrome DevTools Protocol: + * https://chromedevtools.github.io/devtools-protocol/ + * + * The inspector connection has two purposes: + * 1. Attach debuggers to the workerd instance. + * 2. Ingest logs (e.g. user's `console.log` calls) from workerd into + * the main Node.js process, so that we can display them in the terminal. + * + * @param options - Options for the inspector. + * @returns A function to reconnect to the inspector. + */ export function createInspectorConnector(options: { privateInspectorPort: number; publicInspectorPort?: number; @@ -86,9 +100,16 @@ export function createInspectorConnector(options: { }; } +/** + * Since a workerd instance can have multiple workers, we need to find the + * inspector URL for the main worker that runs user code, since that's the + * worker we want to debug. We use the port number to query all the existing + * workers and find the one that matches the user worker name. + */ async function findInspectorUrl(inspectorPort: number, workerName: string) { try { // Fetch the inspector JSON response from the DevTools Inspector protocol + // https://chromedevtools.github.io/devtools-protocol/#endpoints const jsonUrl = `http://127.0.0.1:${inspectorPort}/json`; const body = (await ( await fetch(jsonUrl) diff --git a/packages/mini-oxygen/src/worker/logger.ts b/packages/mini-oxygen/src/worker/logger.ts index 36f4818ddc..0106b2987f 100644 --- a/packages/mini-oxygen/src/worker/logger.ts +++ b/packages/mini-oxygen/src/worker/logger.ts @@ -7,6 +7,14 @@ import type { MessageData, } from './inspector.js'; +/** + * Adds event listeners for console messages and exceptions to the inspector connection. + * Then, it handles logs and errors in the main Node.js process to display them in the terminal. + * It also formats and displays source maps for errors using information that only exists + * in the Node.js process, although this is not used for Vite processes because Vite already + * provides source maps for errors. + * @param inspector + */ export function addInspectorConsoleLogger(inspector: InspectorConnection) { inspector.ws.addEventListener('message', async (event) => { if (typeof event.data !== 'string') { @@ -28,6 +36,12 @@ export function addInspectorConsoleLogger(inspector: InspectorConnection) { }); } +/** + * Creates an Error instance in the Node.js process from an unhandled exception in workerd. + * @param exceptionDetails + * @param inspector + * @returns Resolves to an actual Error instance with stack trace and message. + */ export async function createErrorFromException( exceptionDetails: Protocol.Runtime.ExceptionDetails, inspector: InspectorConnection, @@ -56,6 +70,12 @@ export async function createErrorFromException( ); } +/** + * Creates an Error instance in the Node.js process from a logged error in workerd. + * @param ro RemoteObject representing the error logged. + * @param inspector + * @returns Resolves to an actual Error instance with stack trace and message. + */ export async function createErrorFromLog( ro: Protocol.Runtime.RemoteObject, inspector: InspectorConnection, @@ -85,14 +105,6 @@ export async function createErrorFromLog( return inspector.reconstructError(errorProperties, ro); } -/** - * This function converts a message serialised as a devtools event - * into arguments suitable to be called by a console method, and - * then actually calls the method with those arguments. Effectively, - * we're just doing a little bit of the work of the devtools console, - * directly in the terminal. - */ - const mapConsoleAPIMessageTypeToConsoleMethod: { [key in Protocol.Runtime.ConsoleAPICalledEvent['type']]: Exclude< keyof Console, @@ -119,6 +131,17 @@ const mapConsoleAPIMessageTypeToConsoleMethod: { endGroup: 'groupEnd', }; +/** + * This function converts a message serialised as a devtools event + * into arguments suitable to be called by a console method, and + * then actually calls the method with those arguments. Effectively, + * we're just doing a little bit of the work of the devtools console, + * directly in the terminal. + * + * Here we decide how to display each type of argument. For example, + * for Errors we reconstruct the stack trace; for Maps, we display + * the key-value pairs, etc. + */ async function logConsoleMessage( evt: Protocol.Runtime.ConsoleAPICalledEvent, inspector: InspectorConnection, @@ -132,9 +155,11 @@ async function logConsoleMessage( case 'undefined': case 'symbol': case 'bigint': + // Simple types are just pushed as-is args.push(ro.value); break; case 'function': + // Functions are displayed as "[Function: ]" args.push(`[Function: ${ro.description ?? ''}]`); break; case 'object': From 06a0312f59454f99666d9c7e136310c7672edc59 Mon Sep 17 00:00:00 2001 From: Scott Dixon <59898611+scottdixon@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:11:44 +1000 Subject: [PATCH 04/17] Update starter template with latest Hydrogen version (#2580) --- .changeset/slimy-drinks-fly.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/slimy-drinks-fly.md diff --git a/.changeset/slimy-drinks-fly.md b/.changeset/slimy-drinks-fly.md new file mode 100644 index 0000000000..b0106544b2 --- /dev/null +++ b/.changeset/slimy-drinks-fly.md @@ -0,0 +1,6 @@ +--- +'@shopify/cli-hydrogen': patch +'@shopify/create-hydrogen': patch +--- + +Update starter template with latest Hydrogen version. From f04156849eea9c97c795148d20afaedf3d26a704 Mon Sep 17 00:00:00 2001 From: "shopify-github-actions-access[bot]" <109624739+shopify-github-actions-access[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:22:37 +1000 Subject: [PATCH 05/17] [ci] release 2024-07 (#2569) Co-authored-by: github-actions[bot] --- .changeset/slimy-drinks-fly.md | 6 ------ .changeset/spicy-rats-press.md | 5 ----- packages/cli/CHANGELOG.md | 9 +++++++++ packages/cli/oclif.manifest.json | 2 +- packages/cli/package.json | 4 ++-- packages/create-hydrogen/CHANGELOG.md | 6 ++++++ packages/create-hydrogen/package.json | 2 +- packages/mini-oxygen/CHANGELOG.md | 6 ++++++ packages/mini-oxygen/package.json | 2 +- 9 files changed, 26 insertions(+), 16 deletions(-) delete mode 100644 .changeset/slimy-drinks-fly.md delete mode 100644 .changeset/spicy-rats-press.md diff --git a/.changeset/slimy-drinks-fly.md b/.changeset/slimy-drinks-fly.md deleted file mode 100644 index b0106544b2..0000000000 --- a/.changeset/slimy-drinks-fly.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@shopify/cli-hydrogen': patch -'@shopify/create-hydrogen': patch ---- - -Update starter template with latest Hydrogen version. diff --git a/.changeset/spicy-rats-press.md b/.changeset/spicy-rats-press.md deleted file mode 100644 index 46fc865b00..0000000000 --- a/.changeset/spicy-rats-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@shopify/mini-oxygen': patch ---- - -Update internal version of the worker runtime. diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 595e2ba934..1bb1db5e73 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,14 @@ # @shopify/cli-hydrogen +## 8.4.5 + +### Patch Changes + +- Update starter template with latest Hydrogen version. ([#2580](https://github.com/Shopify/hydrogen/pull/2580)) by [@scottdixon](https://github.com/scottdixon) + +- Updated dependencies [[`04b4c7c3`](https://github.com/Shopify/hydrogen/commit/04b4c7c3362aa07fc12ce749bfc5a955aa1254e4)]: + - @shopify/mini-oxygen@3.0.6 + ## 8.4.4 ### Patch Changes diff --git a/packages/cli/oclif.manifest.json b/packages/cli/oclif.manifest.json index 63df812c1d..6ed8b1c42e 100644 --- a/packages/cli/oclif.manifest.json +++ b/packages/cli/oclif.manifest.json @@ -1758,5 +1758,5 @@ ] } }, - "version": "8.4.4" + "version": "8.4.5" } \ No newline at end of file diff --git a/packages/cli/package.json b/packages/cli/package.json index 3ee7fedab8..5198fe9d8d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -4,7 +4,7 @@ "access": "public", "@shopify:registry": "https://registry.npmjs.org" }, - "version": "8.4.4", + "version": "8.4.5", "license": "MIT", "type": "module", "scripts": { @@ -56,7 +56,7 @@ "@graphql-codegen/cli": "^5.0.2", "@remix-run/dev": "^2.1.0", "@shopify/hydrogen-codegen": "^0.3.1", - "@shopify/mini-oxygen": "^3.0.5", + "@shopify/mini-oxygen": "^3.0.6", "graphql-config": "^5.0.3", "vite": "^5.1.0" }, diff --git a/packages/create-hydrogen/CHANGELOG.md b/packages/create-hydrogen/CHANGELOG.md index 4efd59d335..d79d924d32 100644 --- a/packages/create-hydrogen/CHANGELOG.md +++ b/packages/create-hydrogen/CHANGELOG.md @@ -1,5 +1,11 @@ # @shopify/create-hydrogen +## 5.0.8 + +### Patch Changes + +- Update starter template with latest Hydrogen version. ([#2580](https://github.com/Shopify/hydrogen/pull/2580)) by [@scottdixon](https://github.com/scottdixon) + ## 5.0.7 ### Patch Changes diff --git a/packages/create-hydrogen/package.json b/packages/create-hydrogen/package.json index f8b6500042..e29ae5f04d 100644 --- a/packages/create-hydrogen/package.json +++ b/packages/create-hydrogen/package.json @@ -5,7 +5,7 @@ "@shopify:registry": "https://registry.npmjs.org" }, "license": "MIT", - "version": "5.0.7", + "version": "5.0.8", "type": "module", "scripts": { "build": "tsup --clean", diff --git a/packages/mini-oxygen/CHANGELOG.md b/packages/mini-oxygen/CHANGELOG.md index 1ee5916d89..7e30ff769a 100644 --- a/packages/mini-oxygen/CHANGELOG.md +++ b/packages/mini-oxygen/CHANGELOG.md @@ -1,5 +1,11 @@ # @shopify/mini-oxygen +## 3.0.6 + +### Patch Changes + +- Update internal version of the worker runtime. ([#2567](https://github.com/Shopify/hydrogen/pull/2567)) by [@frandiox](https://github.com/frandiox) + ## 3.0.5 ### Patch Changes diff --git a/packages/mini-oxygen/package.json b/packages/mini-oxygen/package.json index 6aa0ac96cb..a54d4fb03c 100644 --- a/packages/mini-oxygen/package.json +++ b/packages/mini-oxygen/package.json @@ -4,7 +4,7 @@ "access": "public", "@shopify:registry": "https://registry.npmjs.org" }, - "version": "3.0.5", + "version": "3.0.6", "license": "MIT", "type": "module", "description": "Development assistant for custom Shopify Oxygen hosted storefronts", From 229d4aa039bf44ced34122c273254d8961a3ed0c Mon Sep 17 00:00:00 2001 From: Scott Dixon <59898611+scottdixon@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:50:17 +1000 Subject: [PATCH 06/17] Image component: support local assets in development (#2573) --- .changeset/blue-ads-design.md | 5 +++++ packages/hydrogen-react/src/Image.test.tsx | 21 +++++++++++++++++++++ packages/hydrogen-react/src/Image.tsx | 5 +++-- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 .changeset/blue-ads-design.md diff --git a/.changeset/blue-ads-design.md b/.changeset/blue-ads-design.md new file mode 100644 index 0000000000..9447414d52 --- /dev/null +++ b/.changeset/blue-ads-design.md @@ -0,0 +1,5 @@ +--- +'@shopify/hydrogen-react': patch +--- + +Image component: support local assets in development diff --git a/packages/hydrogen-react/src/Image.test.tsx b/packages/hydrogen-react/src/Image.test.tsx index 9a15c52abb..4f4a3a1b84 100644 --- a/packages/hydrogen-react/src/Image.test.tsx +++ b/packages/hydrogen-react/src/Image.test.tsx @@ -78,6 +78,27 @@ describe('', () => { crop, }); }); + + it('handles remote assets', () => { + render(); + expect(screen.getByRole('img')).toHaveAttribute( + 'src', + 'https://cdn.shopify.com/s/files/1/0551/4566/0472/products/Main.jpg?width=100&crop=center', + ); + }); + + it('handles local assets', () => { + const props = { + ...defaultProps, + src: '/assets/image.png', + }; + + render(); + expect(screen.getByRole('img')).toHaveAttribute( + 'src', + '/assets/image.png?width=100&crop=center', + ); + }); }); describe('aspect-ratio', () => { diff --git a/packages/hydrogen-react/src/Image.tsx b/packages/hydrogen-react/src/Image.tsx index c2a06f0bc5..30276c2409 100644 --- a/packages/hydrogen-react/src/Image.tsx +++ b/packages/hydrogen-react/src/Image.tsx @@ -549,12 +549,13 @@ const FluidImage = React.forwardRef( * }) * ``` */ +const PLACEHOLDER_DOMAIN = 'https://placeholder.shopify.com'; export function shopifyLoader({src, width, height, crop}: LoaderParams) { if (!src) { return ''; } - const url = new URL(src); + const url = new URL(src, PLACEHOLDER_DOMAIN); if (width) { url.searchParams.append('width', Math.round(width).toString()); @@ -567,7 +568,7 @@ export function shopifyLoader({src, width, height, crop}: LoaderParams) { if (crop) { url.searchParams.append('crop', crop); } - return url.href; + return url.href.replace(PLACEHOLDER_DOMAIN, ''); } /** From c1696a527e8aaf28c7b4eea2f5262992bf0e485b Mon Sep 17 00:00:00 2001 From: Fatih Altinok Date: Fri, 4 Oct 2024 07:30:00 +0300 Subject: [PATCH 07/17] [skeleton] Use datalist for query suggestions for autocomplete experience (#2506) --- .changeset/hip-pandas-leave.md | 5 +++ .../skeleton/app/components/PageLayout.tsx | 8 +++-- .../components/SearchResultsPredictive.tsx | 35 ++++++------------- 3 files changed, 20 insertions(+), 28 deletions(-) create mode 100644 .changeset/hip-pandas-leave.md diff --git a/.changeset/hip-pandas-leave.md b/.changeset/hip-pandas-leave.md new file mode 100644 index 0000000000..3c7f0ae26c --- /dev/null +++ b/.changeset/hip-pandas-leave.md @@ -0,0 +1,5 @@ +--- +'skeleton': minor +--- + +Use HTML datalist element for query suggestions for autocomplete experience diff --git a/templates/skeleton/app/components/PageLayout.tsx b/templates/skeleton/app/components/PageLayout.tsx index c763690287..d6a808b5e4 100644 --- a/templates/skeleton/app/components/PageLayout.tsx +++ b/templates/skeleton/app/components/PageLayout.tsx @@ -1,5 +1,5 @@ import {Await, Link} from '@remix-run/react'; -import {Suspense} from 'react'; +import {Suspense, useId} from 'react'; import type { CartApiQueryFragment, FooterQuery, @@ -70,6 +70,7 @@ function CartAside({cart}: {cart: PageLayoutProps['cart']}) { } function SearchAside() { + const queriesDatalistId = useId(); return (