diff --git a/cypress/integration/middleware/enhanced.spec.ts b/cypress/integration/middleware/enhanced.spec.ts index 4d5f1f0b87..2d282a18bc 100644 --- a/cypress/integration/middleware/enhanced.spec.ts +++ b/cypress/integration/middleware/enhanced.spec.ts @@ -1,7 +1,7 @@ describe('Enhanced middleware', () => { it('rewrites the response body', () => { cy.visit('/static') - cy.get('#message').contains('This was static but has been transformed in') + cy.get('#message').contains('This was static (& escaping test &) but has been transformed in') cy.contains("This is an ad that isn't shown by default") }) @@ -10,7 +10,7 @@ describe('Enhanced middleware', () => { expect(response.body).to.have.nested.property('pageProps.showAd', true) expect(response.body) .to.have.nested.property('pageProps.message') - .that.includes('This was static but has been transformed in') + .that.includes('This was static (& escaping test &) but has been transformed in') }) }) @@ -27,13 +27,13 @@ describe('Enhanced middleware', () => { it('handles uppercase i18n redirects properly ', () => { cy.visit('/de-DE/static') - cy.get('#message').contains('This was static but has been transformed in') + cy.get('#message').contains('This was static (& escaping test &) but has been transformed in') cy.contains("This is an ad that isn't shown by default") }) it('handles lowercase i18n redirects properly ', () => { cy.visit('/de-de/static') - cy.get('#message').contains('This was static but has been transformed in') + cy.get('#message').contains('This was static (& escaping test &) but has been transformed in') cy.contains("This is an ad that isn't shown by default") }) }) diff --git a/demos/middleware/middleware.ts b/demos/middleware/middleware.ts index d934dc5fa5..d0c7841997 100644 --- a/demos/middleware/middleware.ts +++ b/demos/middleware/middleware.ts @@ -24,7 +24,7 @@ export async function middleware(req: NextRequest) { if (pathname.startsWith('/static')) { // Unlike NextResponse.next(), this actually sends the request to the origin const res = await request.next() - const message = `This was static but has been transformed in ${req.geo?.city}` + const message = `This was static (& escaping test &) but has been transformed in ${req.geo?.city}` // Transform the response HTML and props res.replaceText('p[id=message]', message) diff --git a/packages/runtime/src/templates/edge-shared/utils.ts b/packages/runtime/src/templates/edge-shared/utils.ts index 56e8826c94..c1e5004168 100644 --- a/packages/runtime/src/templates/edge-shared/utils.ts +++ b/packages/runtime/src/templates/edge-shared/utils.ts @@ -212,7 +212,9 @@ export const buildResponse = async ({ // Apply all of the transforms to the props const props = response.dataTransforms.reduce((prev, transform) => transform(prev), data.props) // Replace the data with the transformed props - textChunk.replace(JSON.stringify({ ...data, props })) + // With `html: true` the input is treated as raw HTML + // @see https://developers.cloudflare.com/workers/runtime-apis/html-rewriter/#global-types + textChunk.replace(JSON.stringify({ ...data, props }), { html: true }) } catch (err) { console.log('Could not parse', err) }