Skip to content

Commit

Permalink
fix multi-level redirect in server actions
Browse files Browse the repository at this point in the history
  • Loading branch information
ztanner committed Nov 13, 2024
1 parent 6ade559 commit a04970a
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 22 deletions.
7 changes: 6 additions & 1 deletion packages/next/src/server/app-render/action-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ function getAppRelativeRedirectUrl(
host: Host,
redirectUrl: string
): URL | null {
if (redirectUrl.startsWith('/') || redirectUrl.startsWith('./')) {
if (redirectUrl.startsWith('/') || redirectUrl.startsWith('.')) {
// Make sure we are appending the basePath to relative URLS
return new URL(`${basePath}${redirectUrl}`, 'http://n')
}
Expand Down Expand Up @@ -296,6 +296,8 @@ async function createRedirectRenderResult(
redirectUrl
)

console.log({ appRelativeRedirectUrl })

if (appRelativeRedirectUrl) {
if (!originalHost) {
throw new Error(
Expand Down Expand Up @@ -442,6 +444,7 @@ export async function handleAction({
const contentType = req.headers['content-type']
const { serverActionsManifest, page } = ctx.renderOpts

console.log('HANDLE ACTION INVOKED')
const {
actionId,
isURLEncodedAction,
Expand Down Expand Up @@ -899,6 +902,8 @@ export async function handleAction({
}
})

console.log('wtf', actionResult)

return {
type: 'done',
result: actionResult,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export async function relativeRedirect() {
return redirect('./subpage')
}

export async function multiRelativeRedirect() {
return redirect('../subpage')
}

export async function absoluteRedirect() {
return redirect('/subpage')
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
'use client'

import { startTransition } from 'react'
import { absoluteRedirect, relativeRedirect } from '../actions'
import {
absoluteRedirect,
multiRelativeRedirect,
relativeRedirect,
} from '../actions'

export default function Page() {
return (
Expand All @@ -17,6 +21,16 @@ export default function Page() {
>
relative redirect
</button>
<button
onClick={async () => {
startTransition(async () => {
await multiRelativeRedirect()
})
}}
id="multi-relative-subdir-redirect"
>
multi-level relative redirect
</button>
<button
onClick={async () => {
startTransition(async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
experimental: {},
}
const nextConfig = {}

module.exports = nextConfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// @ts-check
import { nextTestSetup } from 'e2e-utils'
import { check } from 'next-test-utils'
import { retry } from 'next-test-utils'

describe('server-actions-relative-redirect', () => {
const { next } = nextTestSetup({
Expand All @@ -11,51 +10,54 @@ describe('server-actions-relative-redirect', () => {
const browser = await next.browser('/')
await browser.waitForElementByCss('#relative-redirect').click()

await check(async () => {
await retry(async () => {
expect(await browser.waitForElementByCss('#page-loaded').text()).toBe(
'hello nested page'
)

return 'success'
}, 'success')
})
})

it('should work with absolute redirect', async () => {
const browser = await next.browser('/')
await browser.waitForElementByCss('#absolute-redirect').click()

await check(async () => {
await retry(async () => {
expect(await browser.waitForElementByCss('#page-loaded').text()).toBe(
'hello nested page'
)

return 'success'
}, 'success')
})
})

it('should work with relative redirect from subdir', async () => {
const browser = await next.browser('/subdir')
await browser.waitForElementByCss('#relative-subdir-redirect').click()

await check(async () => {
await retry(async () => {
expect(await browser.waitForElementByCss('#page-loaded').text()).toBe(
'hello subdir nested page'
)

return 'success'
}, 'success')
})
})

it('should work with absolute redirect from subdir', async () => {
const browser = await next.browser('/subdir')
await browser.waitForElementByCss('#absolute-subdir-redirect').click()

await check(async () => {
await retry(async () => {
expect(await browser.waitForElementByCss('#page-loaded').text()).toBe(
'hello nested page'
)
})
})

return 'success'
}, 'success')
it('should work with multi-level relative redirect from subdir', async () => {
const browser = await next.browser('/subdir')
await browser.waitForElementByCss('#multi-relative-subdir-redirect').click()

await retry(async () => {
expect(await browser.waitForElementByCss('#page-loaded').text()).toBe(
'hello nested page'
)
})
})
})

0 comments on commit a04970a

Please sign in to comment.