Help with using NextJS: I can't get a project up because of arbitrary hardcoded restrictions
Unanswered
Scottish Fold posted this in #help-forum
Scottish FoldOP
I'm trying NextJS for the first time, and it seems impossible to get anything working.
First, there is this:
https://github.com/vercel/next.js/discussions/65259
In summary, NextJS developers arbitrarily decided you cannot use getPathname in server side components.
Yes, the server doesn't have a "pathname". I don't want a "pathname", I want to know the route I'm currently in. Every backend framework (Flask, Rails, and so on) have a way to get the route. Backend development is IMPOSSIBLE without that.
Second: NextJS disallows redirects for static pages. This is also ridiculous: static pages have redirects, this is has been a standard in raw http for at least 30 years.
Now, I'm trying to do something REALLY basic, which is to have a default page. In other words, I want / to be the same as /home.
How can such basic things be so hard in NextJS? And how come the documentation fails to mention things like getting the current route? How does the documentation say "you can't use getPathname" and provide no alternative solution? And then they just ignore any questions on github!
First, there is this:
https://github.com/vercel/next.js/discussions/65259
In summary, NextJS developers arbitrarily decided you cannot use getPathname in server side components.
Yes, the server doesn't have a "pathname". I don't want a "pathname", I want to know the route I'm currently in. Every backend framework (Flask, Rails, and so on) have a way to get the route. Backend development is IMPOSSIBLE without that.
Second: NextJS disallows redirects for static pages. This is also ridiculous: static pages have redirects, this is has been a standard in raw http for at least 30 years.
Now, I'm trying to do something REALLY basic, which is to have a default page. In other words, I want / to be the same as /home.
How can such basic things be so hard in NextJS? And how come the documentation fails to mention things like getting the current route? How does the documentation say "you can't use getPathname" and provide no alternative solution? And then they just ignore any questions on github!
83 Replies
@Scottish Fold I'm trying NextJS for the first time, and it seems impossible to get anything working.
First, there is this:
https://github.com/vercel/next.js/discussions/65259
In summary, NextJS developers arbitrarily decided you cannot use getPathname in server side components.
Yes, the server doesn't have a "pathname". I don't want a "pathname", I want to know the route I'm currently in. Every backend framework (Flask, Rails, and so on) have a way to get the route. Backend development is IMPOSSIBLE without that.
Second: NextJS disallows redirects for static pages. This is also ridiculous: static pages have redirects, this is has been a standard in raw http for at least 30 years.
Now, I'm trying to do something REALLY basic, which is to have a default page. In other words, I want / to be the same as /home.
How can such basic things be so hard in NextJS? And how come the documentation fails to mention things like getting the current route? How does the documentation say "you can't use getPathname" and provide no alternative solution? And then they just ignore any questions on github!
1. calm down. normally, no one would be willing to help you with that kind of language.
2. server components don't have access to the pathname, but page components do have access to the
3. redirect with static pages is possible with tons of ways, e.g. https://nextjs.org/docs/app/api-reference/next-config-js/redirects
4. if you feel like nextjs is bad for you, you are welcome to use other frameworks. nextjs is not for everyone and from your language i can totally see its not for you.
2. server components don't have access to the pathname, but page components do have access to the
params prop, from which you can build the URL. nextjs doesn't build the URL automatically for you and there's nothing you can do about it.3. redirect with static pages is possible with tons of ways, e.g. https://nextjs.org/docs/app/api-reference/next-config-js/redirects
4. if you feel like nextjs is bad for you, you are welcome to use other frameworks. nextjs is not for everyone and from your language i can totally see its not for you.
Scottish FoldOP
2. To get the route is not about building a url. The entire point of routing is to translate a url into a route, that's what routing means. A url is client-side, a route is server-side. Simple example: the "layouts" component needs to know what page is currently being displayed. In fact, it gets a "children" prop. But the "children" prop is not the route, it's the entire page. NextJS needs to expose the route to the developer (not just the entire "children" jsx), but it doesn't, and the documentation mockingly says you can't have it (like in any other backend framework), and gives no alternative.
3. If you follow those instructions, then the compiler explicitly says that you cannot use "redirects" with static pages. See, I'm not the only one for whom this is a surprise!
4. It's not for developers who need http to redirect or who need to access the routes? Yep.
3. If you follow those instructions, then the compiler explicitly says that you cannot use "redirects" with static pages. See, I'm not the only one for whom this is a surprise!
4. It's not for developers who need http to redirect or who need to access the routes? Yep.
@Scottish Fold 2. To get the route is not about building a url. The entire point of routing is to translate a url into a route, that's what routing means. A url is client-side, a route is server-side. Simple example: the "layouts" component needs to know what page is currently being displayed. In fact, it gets a "children" prop. But the "children" prop is not the route, it's the entire page. NextJS *needs* to expose the route to the developer (not just the entire "children" jsx), but it doesn't, and the documentation mockingly says you can't have it (like in *any other backend framework*), and gives no alternative.
3. If you follow those instructions, then the **compiler** explicitly says that you cannot use "redirects" with static pages. See, I'm not the only one for whom this is a surprise!
4. It's not for developers who need http to redirect or who need to access the routes? Yep.
about point 2:
layout server components do not know the params under it because they are not rerendered when navigating. you can always use client components, because such components are rerendered when navigating. https://nextjs-faq.com/get-pathname-in-rsc
about point 3:
are you confusing it with static exports? static pages do not influence the ability to redirect at all. you can always use middleware/next.config.js to redirect.
for static exports, you can add the meta tag for html redirects: https://www.w3.org/TR/WCAG20-TECHS/H76.html
layout server components do not know the params under it because they are not rerendered when navigating. you can always use client components, because such components are rerendered when navigating. https://nextjs-faq.com/get-pathname-in-rsc
about point 3:
are you confusing it with static exports? static pages do not influence the ability to redirect at all. you can always use middleware/next.config.js to redirect.
for static exports, you can add the meta tag for html redirects: https://www.w3.org/TR/WCAG20-TECHS/H76.html
Scottish FoldOP
2. I suspected that, but I needed to be sure.
For example, a header component in a react app will often re-render, because the current page is usually highlighted in the navigation menu.
This is a huge issue because then "layout" is kind of useless. It cannot have a header or footer in it, or anything else, if those components are any different for different routes.
In other words, it seems that there is no way to wrap all pages in another component (I thought this could be achieved through the layout component).
So the developer needs to go page file through page file, and wrap each of them in a "layout" component, and pass the layout component, for each page, a different prop, telling that component what page is currently being wrapped.
That's what frameworks are supposed to do themselves (page wrapping in a HOC, etc), and then offer the developer a way to define that HOC.
Please let me know if I'm mistaken, and NextJS does provide something like that.
3. Yes, I mean static exports.
Well, that's fair. I shouldn't have said I want a redirect, I just wanted to have the / route point at the /home route.
The issue, again, is that NextJS doesn't allow you to define routes manually. Which forces you to do "route redirection" manually.
What is "route redirection"? It is not the same as url redirection. It happens in the backend entirely: when the / route is requested, /home is returned. I'm giving it this weird "route redirection" name because this is usually just called "routing", or "route mapping", or "aliasing" in any other framework, but these concepts don't exist in NextJS afik.
So I'm doing it like this:
import About from "./about/page";
export default About;
which is fine, I guess.
But it's the same issue as with HOC wrapping conceptually.
For example, a header component in a react app will often re-render, because the current page is usually highlighted in the navigation menu.
This is a huge issue because then "layout" is kind of useless. It cannot have a header or footer in it, or anything else, if those components are any different for different routes.
In other words, it seems that there is no way to wrap all pages in another component (I thought this could be achieved through the layout component).
So the developer needs to go page file through page file, and wrap each of them in a "layout" component, and pass the layout component, for each page, a different prop, telling that component what page is currently being wrapped.
That's what frameworks are supposed to do themselves (page wrapping in a HOC, etc), and then offer the developer a way to define that HOC.
Please let me know if I'm mistaken, and NextJS does provide something like that.
3. Yes, I mean static exports.
Well, that's fair. I shouldn't have said I want a redirect, I just wanted to have the / route point at the /home route.
The issue, again, is that NextJS doesn't allow you to define routes manually. Which forces you to do "route redirection" manually.
What is "route redirection"? It is not the same as url redirection. It happens in the backend entirely: when the / route is requested, /home is returned. I'm giving it this weird "route redirection" name because this is usually just called "routing", or "route mapping", or "aliasing" in any other framework, but these concepts don't exist in NextJS afik.
So I'm doing it like this:
import About from "./about/page";
export default About;
which is fine, I guess.
But it's the same issue as with HOC wrapping conceptually.
Scottish FoldOP
I guess I might be able to do that stuff with middleware but I'm not sure yet
I think 2 is templates and 3 middleware
@Scottish Fold 2. I suspected that, but I needed to be sure.
For example, a header component in a react app will often re-render, because the current page is usually highlighted in the navigation menu.
This is a huge issue because then "layout" is kind of useless. It cannot have a header or footer in it, or anything else, if those components are any different for different routes.
In other words, it seems that there is no way to wrap *all* pages in another component (I thought this could be achieved through the layout component).
So the developer needs to go page file through page file, and wrap each of them in a "layout" component, and pass the layout component, for each page, a different prop, telling that component what page is currently being wrapped.
That's what frameworks are supposed to do themselves (page wrapping in a HOC, etc), and then offer the developer a way to define that HOC.
Please let me know if I'm mistaken, and NextJS does provide something like that.
3. Yes, I mean static exports.
Well, that's fair. I shouldn't have said I want a redirect, I just wanted to have the / route point at the /home route.
The issue, again, is that NextJS doesn't allow you to define routes manually. Which forces you to do "route redirection" manually.
What is "route redirection"? It is not the same as url redirection. It happens in the backend entirely: when the / route is requested, /home is returned. I'm giving it this weird "route redirection" name because this is usually just called "routing", or "route mapping", or "aliasing" in any other framework, but these concepts don't exist in NextJS afik.
So I'm doing it like this:
import About from "./about/page";
export default About;
which is fine, I guess.
But it's the same issue as with HOC wrapping conceptually.
2. i want to repeat: server components do not rerender, but client components do.
the server component is supposed to provide the static data that remains unchanged for that entire layout regardless of how you navigate. it's the rerenderable client component part that you should put your header/footer in.
3. static export is just a bunch of html files. nothing is run on the server. how do you expect nextjs to know when a request reaches
a header component in a react app will often re-renderbecause that header is a client component.
the server component is supposed to provide the static data that remains unchanged for that entire layout regardless of how you navigate. it's the rerenderable client component part that you should put your header/footer in.
3. static export is just a bunch of html files. nothing is run on the server. how do you expect nextjs to know when a request reaches
/ to redirect to /home? they are just a bunch of html files, nextjs can't know the incoming request! use the meta tag mentioned above to perform the redirection as you would do for any pure-html sites.static exports do NOT have middleware.
Scottish FoldOP
Yes, so, there are all these problems...
A header doesn't need to be a client component... Does it? We are talking about a static export
@Scottish Fold A header doesn't need to be a client component... Does it? We are talking about a static export
server components do not rerender. it's like html/css without javascript. how do you toggle the active state of links without javascript?
Scottish FoldOP
Like, a template theoretically solves this discussion... It does re-render when the page is changed
https://nextjs-forum.com/post/1224347507434197052#message-1225254644843024454 <- see this for the layout part
Scottish FoldOP
Well, it's not about reactive re-rendering, but "browser re-rendering"
Sort of
well ok im convinced nextjs is simply not for you. please feel free to look for other frameworks or wait for other people to come help. i wish you good luck and will get out now.
Scottish FoldOP
The only thing I'm concerned is that the header changes when I visit a different page. Those pages are, of course, completely different html generated by the static export
This is a very, very simple ask, and, indeed, the templates are advertised to work like this
Take a look at the documentation page, it explicitly tells you that the difference between the layout and the template is what we are talking about
However, the issue is the one I pointed out in the beginning: the template does receive a different "children" prop for every page when the compiler is working on the static export, and it does render differently for every such page
HOWEVER it does not receive the route as a prop
Of course, I can inspect the contents of the jsx children prop and achieve what I need to. But this is stupid.
@joulev well ok im convinced nextjs is simply not for you. please feel free to look for other frameworks or wait for other people to come help. i wish you good luck and will get out now.
Scottish FoldOP
Maybe NextJS is not for you, in the sense you are not doing any serious web development. People who are, certainly faced these issues before.
Not every client expects me to host in vercel you know.
Also, nextjs absolutely has access to the route variable on the server side (this is how it chooses the page to load), the developers simply forgot to expose this variable to the template.
This can be easily changed in NextJS' source code, but it would require me to commit the .next folder to all my repos.
Scottish FoldOP
@joulev
I was right, hundreds of other developers have complained about the exact same thing
https://github.com/vercel/next.js/issues/43704
and, fortunately, workarounds were given in that thread (with hundreds of likes from other developers).
Is NextJS not for these hundreds of people who have had the exact same inquiry and who contributed workarounds to their codebases?
Or maybe webdevelopment is just not for you...
I was right, hundreds of other developers have complained about the exact same thing
https://github.com/vercel/next.js/issues/43704
and, fortunately, workarounds were given in that thread (with hundreds of likes from other developers).
Is NextJS not for these hundreds of people who have had the exact same inquiry and who contributed workarounds to their codebases?
Or maybe webdevelopment is just not for you...
Why do you need the pathname in layout.js?
@Scottish Fold <@484037068239142956>
I was right, hundreds of other developers have complained about the exact same thing
https://github.com/vercel/next.js/issues/43704
and, fortunately, workarounds were given in that thread (with hundreds of likes from other developers).
Is NextJS not for these hundreds of people who have had the exact same inquiry and who contributed workarounds to their codebases?
Or maybe webdevelopment is just not for you...
Cape lion
Can feel your frustation.
In other JS framework like Astro they provide a lot of helps for accessing url, cookies headers and what not.
If you want React SSR and you are okay with not having SPA then try Astro + React combination
In other JS framework like Astro they provide a lot of helps for accessing url, cookies headers and what not.
If you want React SSR and you are okay with not having SPA then try Astro + React combination
Scottish FoldOP
Yep, Astro was a heavy consideration before I tried NextJS, at least for this usecase (static website generation).
I need NextJS for other stuff but Astro might be cool for this particular website
@ᴉuɐpɹɐɐ there is now: using parallel routes
Scottish FoldOP
Thanks. Yes, I'm looking into parallel routes too.
I see the discussion is hot in NextJS github right now about this.
I am hoping they will fix this for templates (allow templates to access the route).
While they don't, I created a "mytemplate" HOC, and I'm wrapping every page in it manually.
This is also fine for this project. But it doesn't look good for NextJS.
I see the discussion is hot in NextJS github right now about this.
I am hoping they will fix this for templates (allow templates to access the route).
While they don't, I created a "mytemplate" HOC, and I'm wrapping every page in it manually.
This is also fine for this project. But it doesn't look good for NextJS.
You can use the headers() to get full url from it
If that suits you
Though thats not recommended on dynamic servers
Scottish FoldOP
Accessing the "headers" seems to disable caching and other features
Let me see the exact wording
@Scottish Fold Accessing the "headers" seems to disable caching and other features
You.. dont need caching right? Since its a static export
Ohhh mybad ure right
Scottish FoldOP
"Accessing header opts into dynamic rendering"
Im not well versed in the world of static export so i might come back later
Scottish FoldOP
I didn't even try it, but accessing headers probably gives an error in the static export compiler
Me too, i didnt realize how it wouldnt make sense
Try the parallel with the catchall route trick. Though its a bit hacky, im just trying to help
Scottish FoldOP
Yes. It doesn't make sense because the "headers" presuppose a particular request, but here there is nothing dynamic happening, only static html
I just want to wrap each page in a HOC
This happens through layouts
@Scottish Fold I just want to wrap each page in a HOC
This sounds like a good solution, just throw away layout.js and BYOB layouts :D
Scottish FoldOP
But I need the layout to know which page it is wrapping 😅
Its not like you need partial rendering in static exports
Scottish FoldOP
Not layout, sorry
Template
Both the layout and the template receive the entire jsx of the page
They just don't receive the name of the page (the filesystem path, whatever)
Time to hack the shit out of that with some fs and path magickery
Hmm
But fr though, try parallel routes with catchall route. The catchall route should pass the params to the page.jsx
Scottish FoldOP
Well if i knew what portion of nextjs' code picks the template and wraps the page in it, I would be able to very quickly submit a fix to their codebase
Nice yes I'll take a look at parallel routes. But my impression is that this would demand me to create a different file for every state of the header, no?
Scottish FoldOP
Got it!
One really weird thing is this artifact that shows up in their docs:
There is no other mention to "routeParam" in the entire docs
It is as if they intended this feature to exist at some point and forgot about it
@Scottish Fold It is as if they intended this feature to exist at some point and forgot about it
I think thats just a visualization of what happened behind the scenes
Scottish FoldOP
Right! So the only thing missing is for the template to access the "key"
Or in other words to replace the word "key" with any other word, so that it becomes a prop
(On their side I mean)
Key is a reserved prop from react. You cant accesss it inside the definition of the template component
Well maybe
Scottish FoldOP
Yes, replace key with any other word and it becomes a prop
I dont think its not that simple if you were to implement getting a serverside pathname
Im betting on using a function instead, like
pathname()Scottish FoldOP
I don't know, for me it makes a lot of sense to pass the pathname as a prop, that's how template HOCs work generally
Whatever code does that nesting, that code does know the pathname already, because it uses the pathname to get the page (the "children" prop)
I made a proposal there in the github. Let's see if they respond
In the meanwhile I'm going with this
I really miss the flexibility of react router
Scottish FoldOP
I had previously incorrectly linked the thread. This is the one:
https://github.com/vercel/next.js/issues/43704
https://github.com/vercel/next.js/issues/43704
@Scottish Fold I don't know, for me it makes a lot of sense to pass the pathname as a prop, that's how template HOCs work generally
those are fine but it just causes uneccesary prop dilling imo,
the pathname() function allows you to use it everywhere (hypothetically speaking)
the same way headers() works but without converting to dynamic routes