-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Feature/410 gone #78706
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: canary
Are you sure you want to change the base?
Feature/410 gone #78706
Conversation
|
I hope this for next 14 |
|
I hope this for next 16 |
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
| | 'not-found' | ||
| | 'forbidden' | ||
| | 'unauthorized' | ||
| | 'gone' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid TypeScript syntax: The MetadataItems type definition uses incorrect tuple array syntax that will cause compilation errors.
📄 Review details
🔍 Technical Analysis
The MetadataItems type is defined with invalid TypeScript syntax:
export type MetadataItems = [
Metadata | MetadataResolver | null,
StaticMetadata,
Viewport | ViewportResolver | null,
][]This attempts to use a tuple type with an array suffix ([]), which is not valid TypeScript syntax. The compiler will reject this type definition.
The code appears to intend for MetadataItems to be an array of 3-element tuples, based on how it's used throughout the codebase (e.g., accessing metadataItems[i][0], metadataItems[i][1], and metadataItems[i][2]).
🔧 Suggested Fix
Change the type definition to use proper TypeScript array-of-tuples syntax:
export type MetadataItems = Array<[
Metadata | MetadataResolver | null,
StaticMetadata,
Viewport | ViewportResolver | null,
]>This correctly defines MetadataItems as an array where each element is a 3-element tuple containing metadata, static metadata, and viewport information.
👍 or 👎 to improve Vade.
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
| import { gone } from 'next/navigation' | ||
|
|
||
| async function getPost(slug: string) { | ||
| const res = await fetch(`https://api.example.com/posts/${slug}`) | ||
| if (res.status === 410) return { isDeleted: true } | ||
| if (!res.ok) return null | ||
| return res.json() | ||
| } | ||
|
|
||
| export default async function Post({ params }: { params: { slug: string } }) { | ||
| const post = await getPost(params.slug) | ||
|
|
||
| // For content that doesn't exist | ||
| if (!post) { | ||
| notFound() | ||
| } | ||
|
|
||
| // For content that has been deliberately removed | ||
| if (post.isDeleted) { | ||
| gone() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example is missing the notFound import which is required since it's used on line 50. Please update the import statement to include both functions:
import { gone, notFound } from 'next/navigation'This will ensure the example works correctly when copied by developers.
| import { gone } from 'next/navigation' | |
| async function getPost(slug: string) { | |
| const res = await fetch(`https://api.example.com/posts/${slug}`) | |
| if (res.status === 410) return { isDeleted: true } | |
| if (!res.ok) return null | |
| return res.json() | |
| } | |
| export default async function Post({ params }: { params: { slug: string } }) { | |
| const post = await getPost(params.slug) | |
| // For content that doesn't exist | |
| if (!post) { | |
| notFound() | |
| } | |
| // For content that has been deliberately removed | |
| if (post.isDeleted) { | |
| gone() | |
| } | |
| import { gone, notFound } from 'next/navigation' | |
| async function getPost(slug: string) { | |
| const res = await fetch(`https://api.example.com/posts/${slug}`) | |
| if (res.status === 410) return { isDeleted: true } | |
| if (!res.ok) return null | |
| return res.json() | |
| } | |
| export default async function Post({ params }: { params: { slug: string } }) { | |
| const post = await getPost(params.slug) | |
| // For content that doesn't exist | |
| if (!post) { | |
| notFound() | |
| } | |
| // For content that has been deliberately removed | |
| if (post.isDeleted) { | |
| gone() | |
| } |
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
| if (invalidKeys.length) { | ||
| throw new Error(invalidKeysMsg('getStaticProps', invalidKeys)) | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The gone key is missing from the valid keys list in getStaticProps validation, which will cause { gone: true } returns to be flagged as invalid keys.
📄 Review details
🔍 Technical Analysis
In the getStaticProps validation logic, the invalidKeys filter checks for valid return keys but doesn't include 'gone' alongside 'revalidate', 'props', 'redirect', and 'notFound'. This means when a user returns { gone: true } from getStaticProps, it will be flagged as an invalid key and throw an "Additional keys were returned from getStaticProps" error before the gone logic can process it.
The current validation code:
const invalidKeys = Object.keys(data).filter(
(key) =>
key !== 'revalidate' &&
key !== 'props' &&
key !== 'redirect' &&
key !== 'notFound'
// Missing: && key !== 'gone'
)This completely prevents the gone feature from working in the Pages Router with getStaticProps.
🔧 Suggested Fix
Add && key !== 'gone' to the invalidKeys filter on line 923, similar to how other valid keys are handled.
👍 or 👎 to improve Vade.
|
|
||
| if (metadata.isGone) { | ||
| return new RenderResult(null, { metadata }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error message incorrectly mentions "getStaticProps" when it should say "getServerSideProps".
📄 Review details
🔍 Technical Analysis
In the getServerSideProps section, the error message for when /404 page returns notFound: true incorrectly references "getStaticProps" instead of "getServerSideProps". The error message reads:
The /404 page can not return notFound in "getStaticProps", please remove it to continue!
This is confusing for developers who are using getServerSideProps and will make debugging more difficult.
🔧 Suggested Fix
Change the error message to reference "getServerSideProps" instead of "getStaticProps" to match the context where this error occurs.
👍 or 👎 to improve Vade.
|
We are all waiting for this feature. 🙏 |
|
Any updates on this? |
|
waiting 🔥🔥 |
|
+1 waiting |
|
+1 Yes please |
Next.js 410 Gone Status Feature
This PR adds support for HTTP 410 Gone status in Next.js, providing developers with a way to indicate that content has been permanently removed. This is an important status code for SEO and user experience, as it differentiates between content that doesn't exist (404) and content that previously existed but has been deliberately removed (410).
Features
gone()function for App Routergone: truein getServerSideProps and getStaticProps for Pages Routergone.jsfile convention similar tonot-found.jsImplementation Details
This PR implements:
App Router Support:
gone()function in thenext/navigationmodulegone.jsfile convention for customizing the 410 error pagePages Router Support:
{ gone: true }from data fetching functions/410page support similar to/404pageAPI Route Support:
Documentation
Tests
The PR includes:
gone()functionExample Usage
App Router
Pages Router
Example Project
An example project is included in
gone-statusdemonstrating both App Router and Pages Router implementations of the feature.Breaking Changes
None. This is a new feature with no changes to existing behavior.
Fixes #18684
Extends #73753