Skip to content

Commit

Permalink
Don't include Turbo-Frame header in promoted frame navigations
Browse files Browse the repository at this point in the history
This commit changes the behavior of frame navigations promoted with the
`[data-turbo-action]` attribute so that they don't include the
`Turbo-Frame` header in their requests. This mimics the existing
behavior of frame navigations promoted with `[data-turbo-target=_top]`.

If we don't do this turbo-rails will see the `Turbo-Frame` header and
render the response as a frame update, with a minimal layout that doesn't
include any assets. When Turbo receives the response it believes it's a
full page response in which the assets have gone stale and it issues a full
page reload with `tracked_element_mismatch` as the reason.

Fixes #1047

This is similar to #1138
  • Loading branch information
afcapel committed Jan 29, 2024
1 parent b7187f1 commit 63ec66b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/core/frames/frame_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ export class FrameController {
// Fetch request delegate

prepareRequest(request) {
request.headers["Turbo-Frame"] = this.id
if (!this.action) {
request.headers["Turbo-Frame"] = this.id
}

if (this.currentNavigationElement?.hasAttribute("data-turbo-stream")) {
request.acceptResponseType(StreamMessage.contentType)
Expand Down
31 changes: 31 additions & 0 deletions src/tests/functional/frame_navigation_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,30 @@ test("lazy-loaded frame promotes navigation", async ({ page }) => {
assert.equal(pathname(page.url()), "/src/tests/fixtures/frames/frame_for_eager.html")
})

test("frame navigation sets the Turbo-Frame header", async ({ page }) => {
await page.goto("/src/tests/fixtures/frame_navigation.html")
assertNextRequesTurboFrameHeader(page, "frame")

await page.click("#inside")
await nextEventNamed(page, "turbo:load")
})

test("frame navigation promoted with data-turbo-target=_top doesn't set the Turbo-Frame header", async ({ page }) => {
await page.goto("/src/tests/fixtures/frame_navigation.html")
assertNextRequesTurboFrameHeader(page, undefined)

await page.click("#top")
await nextEventNamed(page, "turbo:load")
})

test("frame navigation promoted with data-turbo-action doesn't set the Turbo-Frame header", async ({ page }) => {
await page.goto("/src/tests/fixtures/tabs.html")
assertNextRequesTurboFrameHeader(page, undefined)

await page.click("#tab-1")
await nextEventNamed(page, "turbo:frame-render")
})

test("promoted frame navigation updates the URL before rendering", async ({ page }) => {
await page.goto("/src/tests/fixtures/tabs.html")

Expand Down Expand Up @@ -104,3 +128,10 @@ test("promoted frame navigations are cached", async ({ page }) => {
assert.equal(await page.getAttribute("#tab-frame", "src"), null, "caches one.html without #tab-frame[src]")
assert.equal(await page.getAttribute("#tab-frame", "complete"), null, "caches one.html without [complete]")
})

function assertNextRequesTurboFrameHeader(page, expected) {
page.on("request", (request) => {
assert.equal(request.headers()["turbo-frame"], expected)
})
}

0 comments on commit 63ec66b

Please sign in to comment.