Closed sebpowell closed 1 year ago
I want to try if I can contribute to this issue. I'm complete newbie here. Can you guide me ?
Hey.
FYI, you should always link to a reproduction of your issue. It is almost always really difficult to help without.
Back to the question, 404 pages are only handled in the app directory when explicitly calling the notFound() function. Next will then show the closest NotFound page in the tree. To show 404 pages implicitly you need to locate them in the pages folder.
I have it working this way in this reproduction. Take and look and see if you are missing something from this setup :)
@Gawdfrey Thanks for the quick response! And apologies yes, I should have included this.
I checked your link, and mine is setup the same way, and for whatever reason just started working this morning 🤷. Maybe it was serving up a cached version or something.
Going to close this now, thank you for your help!
Just a quick question, is there a way to add the layout in app
to the 404 page in pages
?
Just a quick question, is there a way to add the layout in
app
to the 404 page inpages
?
Not as I am aware of. The way I have done it previously is using _app if I wanted a common layout for both the 500 and 404 pages.
We have to wait until the implicit not found functionality arrives before we share the same layout unfortunately.
Hey, mine it's kind of working, but when the 404 page is loaded it triggers the following erro:
I'm using the next middleware, could it be it?
(if i did something wrong in this comment i'm sory, i'm new in here)
Hey, mine it's kind of working, but when the 404 page is loaded it triggers the following erro:
I'm using the next middleware, could it be it?
(if i did something wrong in this comment i'm sory, i'm new in here)
Usually good to include a replication of your code. Hard to help without. As you say it might be middleware if it does any routing, but as said, hard to say without looking at any code.
Alright, sory.
My middleware is like this:
import { validSubdomains } from '@utils/validSubdomainsList';
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
const reqHost = request.headers.get('host');
const reqURL = new URL(request.url);
const currentSubdomain = reqHost?.slice(0, reqHost.indexOf('.'));
const isValidSubdomain = validSubdomains.find(
(subdomain) => subdomain === currentSubdomain
);
const token = request.cookies.get('aplication.token')?.value;
console.log("token", {token})
// Verify with the api if the token is valid
const isIndexPage = reqURL.pathname === '/';
if (isIndexPage) {
if (!token) {
return NextResponse.redirect(new URL(`/login`, request.url));
}
return NextResponse.redirect(new URL(`/dashboard`, request.url));
}
if (isValidSubdomain) {
const isNotAuthenticatedRoute = [
'/login',
'/register',
'/forgot',
].includes(reqURL.pathname);
if (isNotAuthenticatedRoute && token) {
return NextResponse.redirect(new URL(reqURL.pathname, request.url));
}
if (!isNotAuthenticatedRoute && !token) {
return NextResponse.redirect(new URL(`/login`, request.url));
}
return NextResponse.rewrite(new URL(`${reqURL.pathname}`, request.url));
} else {
return NextResponse.rewrite(new URL("/subdomain-not-valid", request.url));
}
}
export const config = {
matcher: ['/((?!api|_next/static|favicon.ico).*)'],
};
Alright, sory.
My middleware is like this:
import { validSubdomains } from '@utils/validSubdomainsList'; import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server'; export function middleware(request: NextRequest) { const reqHost = request.headers.get('host'); const reqURL = new URL(request.url); const currentSubdomain = reqHost?.slice(0, reqHost.indexOf('.')); const isValidSubdomain = validSubdomains.find( (subdomain) => subdomain === currentSubdomain ); const token = request.cookies.get('aplication.token')?.value; console.log("token", {token}) // Verify with the api if the token is valid const isIndexPage = reqURL.pathname === '/'; if (isIndexPage) { if (!token) { return NextResponse.redirect(new URL(`/login`, request.url)); } return NextResponse.redirect(new URL(`/dashboard`, request.url)); } if (isValidSubdomain) { const isNotAuthenticatedRoute = [ '/login', '/register', '/forgot', ].includes(reqURL.pathname); if (isNotAuthenticatedRoute && token) { return NextResponse.redirect(new URL(reqURL.pathname, request.url)); } if (!isNotAuthenticatedRoute && !token) { return NextResponse.redirect(new URL(`/login`, request.url)); } return NextResponse.rewrite(new URL(`${reqURL.pathname}`, request.url)); } else { return NextResponse.rewrite(new URL("/subdomain-not-valid", request.url)); } } export const config = { matcher: ['/((?!api|_next/static|favicon.ico).*)'], };
Cant see any apparent issues on a quick look. But the error says you are trying to route to "/dashboar" but in the middleware only "/dashboard" is mentioned. Might be worth checking out if that url is being botched somehow
So, the lack of mention of '/dashboar' doesn't seem to have anything to do with the error. To test it, I removed the part that checks whether the user needs to be logged in for the route, and placed it somewhere else. However, it still throws the same error.
Currently, the middleware looks like this:
import { validSubdomains } from '@utils/validSubdomainsList';
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
const reqHost = request.headers.get('host');
const reqURL = new URL(request.url);
const currentSubdomain = reqHost?.slice(0, reqHost.indexOf('.'));
const isValidSubdomain = validSubdomains.find(
(subdomain) => subdomain === currentSubdomain
);
const token = request.cookies.get('medical-registration.token')?.value;
console.log("token", {token})
// Verify with the api if the token is valid
const isIndexPage = reqURL.pathname === '/';
if (isIndexPage) {
if (!token) {
return NextResponse.redirect(new URL(`/login`, request.url));
}
return NextResponse.redirect(new URL(`/dashboard`, request.url));
}
if (!isValidSubdomain) {
return NextResponse.rewrite(new URL("/subdomain-not-valid", request.url));
}
}
export const config = {
matcher: ['/((?!api|_next/static|favicon.ico).*)'],
};
Hi @LawEyez,
An approach to put the 404
page in the app
directory is to create an app/[others]/page.tsx
file with the following content:
import { redirect } from "next/navigation";
export default async function NotFound() {
redirect("/404");
}
In this way, any non-existent route will be served by the generic [others]
route, which will redirect to /404
. The latter will render the content of app/404/page.tsx
, whose content you can freely change.
@iosifache Hi! I think your solution is the most fastest way to custom 404 pages.
But I have a question, won't doing that affect SEO? From my opinion that solution seems to not have a status code of 404, but 301.
Does it work like next 12 version's 404 page? Asking out of curiosity. Thanks!
Hi Guys, for me it worked to just create a 404.tsx page under /src/pages and import the style from '@/app/globals.css'
@ssoima when you do it in that way a error isen't triggered? Something about hard navigations
@JamDev0, no error is triggered. Try it with a blank project.
The current issue with the not-found is that it seems somehow throws an error at least on my side and "Link" tag doesn't work anymore. From the doc, the not-found component doesn't accept any props like reset() or so. Therefore, if I use not-found, the user need to force refresh the page after clikcing "Link href="/">Home</Llink"
So far, dyanmic catch all route seems the best option. And src/pages/404.tsx simply didn't work for me. Please enlightne me how you are all working around or any.
I have the same issue with the not-found.tsx page breaking Link elements.
Just create /app/not-found.jsx
https://beta.nextjs.org/docs/api-reference/file-conventions/not-found https://beta.nextjs.org/docs/api-reference/notfound
thanks for the links! another thing that caused me to trip, was that this is not triggered when using dynamicParams = false
. Or am I missing something?
Anyways, I am using dynamicParams
again, and then use an explicit notFound()
in my Page
function :)
I am facing a Similar Problem When Adding 404.tsx
or 404.jsx
to the app directory. Even on My Actual Route Not Working Properly.
it should be not-found.tsx
seems not-found.ts working with the latest version for "Link"
Thanks its working with not-found.jsx or not-found.tsx
app/not-found runs in the root directory, which means you can't go back to app/page.tsx. so when you wrote a path that is not in your app directory, you will be redirected to not-found, but you cannot return to the index/home page. Is it possible to make this change in RootLayout?
We still need to get a custom layout page for 404
+1 on custom layouts for 404 pages, in my opinion we should be able to create a not-found
folder to coincide with the not-found file where we can define custom layouts and components.
I'm currently building an app which would require a custom layout for the 404 page and without some major remodels across the codebase this isn't looking worth the work - unless of course I'm missing something, if anybody has been able to solve this problem (a different layout for a 404 than other pages - including root) I'd appreciate any advice.
In the meantime, I'll just have to watch and hope this get's tuned
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.
What is the improvement or update you wish to see?
I've just finished upgrading to Next 13 – feels like a big improvement, well done for all your hard work.
Just one problem I seem to be having – creating a custom 404 page. According to the upgrade guide, the new
app
directory doesn't support this yet. I assumed that it might work by using thepages
directory instead, but it doesn't seem to get picked up by that either. Is this expected? Or am I perhaps missing something?Just to be clear, this is what I've tried:
and
Neither of these seem to work.
Is there any context that might help us understand?
See above.
Does the docs page already exist? Please link to it.
https://beta.nextjs.org/docs/upgrade-guide#migrating-from-pages-to-app