diff --git a/.changeset/eighty-papers-hunt.md b/.changeset/eighty-papers-hunt.md new file mode 100644 index 0000000000..5c231f8ee0 --- /dev/null +++ b/.changeset/eighty-papers-hunt.md @@ -0,0 +1,5 @@ +--- +'@shopify/theme': patch +--- + +Fix theme editor shortcut tracking fetch requests instead of page navigation diff --git a/packages/theme/src/cli/utilities/theme-environment/html.test.ts b/packages/theme/src/cli/utilities/theme-environment/html.test.ts index 1ff7800914..88d59fd0ee 100644 --- a/packages/theme/src/cli/utilities/theme-environment/html.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/html.test.ts @@ -39,12 +39,12 @@ describe('getHtmlHandler', async () => { lastRequestedPath: '', } as unknown as DevServerContext - test('sets lastRequestedPath to the rendering URL', async () => { + test('sets lastRequestedPath when Sec-Fetch-Mode is navigate', async () => { const handler = getHtmlHandler(theme, ctx) expect(ctx.lastRequestedPath).toStrictEqual('') - const event = createH3Event('GET', '/search?q=foo&options%5Bprefix%5D=last') + const event = createH3Event('GET', '/search?q=foo&options%5Bprefix%5D=last', {'sec-fetch-mode': 'navigate'}) vi.mocked(render).mockResolvedValueOnce( new Response('', { @@ -60,6 +60,24 @@ describe('getHtmlHandler', async () => { expect(ctx.lastRequestedPath).toStrictEqual('/search?q=foo&options%5Bprefix%5D=last') }) + test('does not update lastRequestedPath when Sec-Fetch-Mode is not navigate', async () => { + const handler = getHtmlHandler(theme, ctx) + ctx.lastRequestedPath = '/previous-page' + + const event = createH3Event('GET', '/search/suggest?q=foo&resources[type]=product', {'sec-fetch-mode': 'cors'}) + + vi.mocked(render).mockResolvedValueOnce( + new Response('', { + status: 200, + headers: {'x-request-id': 'test-request-id'}, + }), + ) + + await handler(event) + + expect(ctx.lastRequestedPath).toStrictEqual('/previous-page') + }) + test('the development server session recovers when a theme id mismatch occurs', async () => { // Given const handler = getHtmlHandler(theme, ctx) diff --git a/packages/theme/src/cli/utilities/theme-environment/html.ts b/packages/theme/src/cli/utilities/theme-environment/html.ts index c8a68462ed..909b6ba3d1 100644 --- a/packages/theme/src/cli/utilities/theme-environment/html.ts +++ b/packages/theme/src/cli/utilities/theme-environment/html.ts @@ -24,7 +24,9 @@ export function getHtmlHandler(theme: Theme, ctx: DevServerContext): EventHandle return defineEventHandler((event) => { const [browserPathname = '/', browserSearch = ''] = event.path.split('?') - ctx.lastRequestedPath = event.path + if (isNavigationRequest(event)) { + ctx.lastRequestedPath = event.path + } const shouldRenderUploadErrorPage = ctx.options.errorOverlay !== 'silent' && ctx.localThemeFileSystem.uploadErrors.size > 0 @@ -160,6 +162,11 @@ function isKnownRenderingRequest(event: H3Event) { return ['section_id', 'sections', 'app_block_id'].some((key) => searchParams.has(key)) } +/** Determines if a request is a user navigation type via sec-fetch-mode header. */ +function isNavigationRequest(event: H3Event): boolean { + return event.headers.get('sec-fetch-mode') === 'navigate' +} + async function tryProxyRequest(event: H3Event, ctx: DevServerContext, response: Response) { outputDebug( `Render failed for ${event.path} with ${response.status} (x-request-id: ${response.headers.get(