mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
## Summary Client-handled Server Action redirects currently return a `303` without a `Location` header and may include a streamed RSC response body. Some HTTP intermediaries reject this response or strip its body because it looks like an HTTP redirect. Return `200` for client-handled Server Action redirects while continuing to use `x-action-redirect` and the RSC response. Progressive-enhancement form submissions still return a standards-compliant `303` with `Location`. Fixes #92882 Fixes #74026 ## Verification - `HEADLESS=true pnpm test-dev-turbo test/e2e/app-dir/actions/app-action.test.ts test/e2e/app-dir/app-basepath/index.test.ts test/e2e/app-dir/actions/app-action-progressive-enhancement.test.ts` - `HEADLESS=true pnpm test-start-turbo test/e2e/app-dir/actions/app-action.test.ts test/e2e/app-dir/app-basepath/index.test.ts test/e2e/app-dir/actions/app-action-progressive-enhancement.test.ts` - `pnpm --filter=next types` <!-- NEXT_JS_LLM -->
51 lines
1.1 KiB
JavaScript
51 lines
1.1 KiB
JavaScript
'use server'
|
|
|
|
import { redirect } from 'next/navigation'
|
|
import { notFound } from 'next/navigation'
|
|
|
|
// Simple successful action
|
|
export async function successAction(value) {
|
|
return { result: value + 1 }
|
|
}
|
|
|
|
// Action with multiple arguments
|
|
export async function multiArgAction(a, b, c) {
|
|
return { sum: a + b + c }
|
|
}
|
|
|
|
// Action that redirects
|
|
export async function redirectAction(path) {
|
|
redirect(path)
|
|
}
|
|
|
|
// Action that throws notFound (should show 404 status)
|
|
export async function notFoundAction() {
|
|
notFound()
|
|
}
|
|
|
|
// Action that throws an error (should show 500 status)
|
|
export async function errorAction() {
|
|
throw new Error('Intentional error for testing')
|
|
}
|
|
|
|
// Action with object argument
|
|
export async function objectArgAction(data) {
|
|
return { received: data }
|
|
}
|
|
|
|
// Action with array argument
|
|
export async function arrayArgAction(items) {
|
|
return { count: items.length }
|
|
}
|
|
|
|
// Inline action export for testing inline action display
|
|
export const inlineAction = async (value) => {
|
|
return value * 2
|
|
}
|
|
|
|
// Action with promise argument
|
|
export async function promiseArgAction(promiseValue) {
|
|
const resolved = await promiseValue
|
|
return { resolved }
|
|
}
|