Can I use parallel routes and nested dynamic routes with output: 'export'?
Answered
West African Lion posted this in #help-forum
West African LionOP
Hello there, and thanks for the attention already.
I am trying to develop a static blog - which I need to host on Github Pages - and explore possibilities with Next, and how much I can do with its different features.
Using
In my NextConfig, I have
In this configuration, everything works properly if I render the
Switching to using parallel routes and this configuration:
makes it go into a server error.
Needless to say, the
What am I missing? Am I using a wrong configuration?
Can I use parallel routes and nested dynamic routes with output: 'export'?
(Could this be related to issue #56253 on Github?)
Open to give more information, were they required!
I am trying to develop a static blog - which I need to host on Github Pages - and explore possibilities with Next, and how much I can do with its different features.
Using
next@13.5.6, I currently have the following project structure:app/
(posts)/
[postPages]/
- page.tsx
- layout.tsx
- page.tsxIn my NextConfig, I have
output: 'export' set.[postPages]/page.tsx contains:export const dynamic = "force-static";
export function generateStaticParams() { ... }In this configuration, everything works properly if I render the
props.children in my layout.Switching to using parallel routes and this configuration:
app/
(posts)/
@list/
[postPages]/
- page.tsx
- default.tsx
- layout.tsx
- page.tsxmakes it go into a server error.
Error: Page "/(posts)/@list/[postPages]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.
Needless to say, the
generateStaticParams() is there; as well as the dynamic config.What am I missing? Am I using a wrong configuration?
Can I use parallel routes and nested dynamic routes with output: 'export'?
(Could this be related to issue #56253 on Github?)
Open to give more information, were they required!
118 Replies
@Ray maybe try updating `next@latest`
West African LionOP
I will try in half an hour tops; thanks for the suggestion.
Do you think that might be a bug? What I am inferring from your answer seems to be:
Do you think that might be a bug? What I am inferring from your answer seems to be:
That should work.Is that correct?
Answer
as long as the page is static, it should be fine
oh I just tried with 14.0.4 and the page is not getting generated
West African LionOP
(Sadly, I have not been able to try it yet, but...)
That seems to suggest something unexpected is happening, right?
Earlier on, I have tried looking into the source code where the error is thrown; it seems like the
That seems to suggest something unexpected is happening, right?
Earlier on, I have tried looking into the source code where the error is thrown; it seems like the
fallbackMode variable is not getting valorised, and it stays undefined.let say I have
app/@list/[postPages]/page.tsx, I have to create a page on app/[postPages]/page.tsx to make it buildnot sure is it a bug or its an unsupported feature
@Ray not sure is it a bug or its an unsupported feature
West African LionOP
That is what I was wondering, actually - hence the title of my question.
but after it build, I dont see anything from
@list in the output@Ray let say I have `app/@list/[postPages]/page.tsx`, I have to create a page on `app/[postPages]/page.tsx` to make it build
West African LionOP
This looks like a hybrid solution, but...
so not sure it is a bug about the complier ignoring it or it is unsupported
@Ray but after it build, I dont see anything from `@list` in the output
West African LionOP
What you mean is that it won't be solved anyway, even by "duplicating" the pages?
maybe you could open a issue
@West African Lion What you mean is that it won't be solved anyway, even by "duplicating" the pages?
because it just generate those page in
[postPages]/page.tsx@Ray maybe you could open a issue
West African LionOP
I'd be open to trying that. Crafting the repro steps could take me some time.
sorry to interrupt; Is
@list a dynamic thing?its parallel route
has value at build time ?
or should?
yes
generateStaticParams provide the valueWest African LionOP
In my understanding,
@list is valorised by the framework; it is not something I explicitly tell to introduce there, except by having the subfolder with that kind of name.@goodsie sorry to interrupt; Is `@list` a dynamic thing?
West African LionOP
(No interruption; the more people looking at it, the closer we could get to a solution! 😄 )
but generate the page twice
West African LionOP
Earlier, I also have tried getting an older version; I think the 13.4.19, if my memory doesn't trick me?
With that some fiddling, I could get it to build, but it got me a 404. That's why I started to wonder whether it is supposed to be an unsupported feature and I was forcing the system in some way or not.
(It seemed to me that there were other examples of that, though.)
With that some fiddling, I could get it to build, but it got me a 404. That's why I started to wonder whether it is supposed to be an unsupported feature and I was forcing the system in some way or not.
(It seemed to me that there were other examples of that, though.)
A thing I have not tried yet is adding another "path segment" in between the parallel route and the nested dynamic one.
it is not generating the page properly
it got that there were more than 1. but it liked the values from the first entry better than the others.

ah it work
oh wait dynamic one work too
@Ray do you mean this?
West African LionOP
No, I meant adding the "[name]†folder in the "one" folder
@Ray oh wait dynamic one work too
West African LionOP
But this makes it feel like a bug, 100%.
and specifiy the value in the outside one
@West African Lion But this makes it feel like a bug, 100%.
West African LionOP
It is as if it wasn't seeing anything before calling the generateStaticParams function in @list, and it is ignoring the whole folder.
@Ray and specifiy the value in the outside one
West African LionOP
Is that still required after adding the "one" folder in there, though?
i deleted it
yeah it work
dynamicParams is not needed I think
learning is fun with Ray 

West African LionOP
Just to recap, then... What is the final tree structure of your project, Ray?
Is it:
With the two page.tsx generating different pages/components?
Is it:
[name]
page.tsx
@top
[name]
page.tsxWith the two page.tsx generating different pages/components?
@Ray Click to see attachment
West African LionOP
How are those even distinguished once they are generated?
yes
generateStaticParams in app/[name]/page.tsx@West African Lion How are those even distinguished once they are generated?
ignore the report I think lol
@Ray `generateStaticParams` in `app/[name]/page.tsx`
West African LionOP
Now I am even wondering something else: what if I remove the
Page there, and just generateStaticParams there?it say you need page component there
West African LionOP
If so, it could sound like a problem with where it is looking for the function!
what problem?
West African LionOP
The original one, I guess!
(I am trying to reconcile the error and what happened there with the solution, trying to understand: "why that is required" and "how the framework thinks", if that makes any sense. 🙂
(I am trying to reconcile the error and what happened there with the solution, trying to understand: "why that is required" and "how the framework thinks", if that makes any sense. 🙂
parallel route allow you render one or more page in a layout.
In static export, you need to provide all value.
so let say you have
you have to tell next which should be rendered in children when you at
In static export, you need to provide all value.
so let say you have
app/@list/[postPages]/page.tsx and you have this layoutexport default function Layout({children, list}) {
return (
<div className="flex gap-4">
{children}
{list}
</div>
)
}you have to tell next which should be rendered in children when you at
/post-1 right?@Ray parallel route allow you render one or more page in a layout.
In static export, you need to provide all value.
so let say you have `app/@list/[postPages]/page.tsx` and you have this layout
ts
export default function Layout({children, list}) {
return (
<div className="flex gap-4">
{children}
{list}
</div>
)
}
you have to tell next which should be rendered in children when you at `/post-1` right?
West African LionOP
Well, if I am going to
existed.
/post-1, I expect it to create a page as if:app/@list/post-1/page.tsx existed.
so next take the
generateStaticParams from app/[postPages]/page.tsx and generate those pagethen you will have
app/post-1/page.tsx and app/@list/post-1/page.tsx@Ray then you will have `app/post-1/page.tsx` and `app/@list/post-1/page.tsx`
West African LionOP
Granted, though, the component could be empty, in
app/post-1/page.tsx, right?you could return
<></> or nullbut why would you need to use parallel route?
@Ray you could return `<></>` or `null`
West African LionOP
That makes sense.
@Ray but why would you need to use parallel route?
West African LionOP
And that's also what I am wondering, once I got to this part. 😅
the main point of parallel route is load two page together in a layout lol
West African LionOP
I initially thought that was "the way to go" for having more pages [in a single layout]; though I have no need for that right now.
It was more of an experiment in order to use the features.
I guess that's what meant earlier on, when writing:
It was more of an experiment in order to use the features.
I guess that's what meant earlier on, when writing:
explore possibilities with Next, and how much I can do with its different features.
Aside from solving the issue in my case and for my purposes, though...
I am still not sure why the most intuitive solution, which I guess would be the first we both tried, did not work.
yeah because I don't always use static export
@Ray parallel route allow you render one or more page in a layout.
In static export, you need to provide all value.
so let say you have `app/@list/[postPages]/page.tsx` and you have this layout
ts
export default function Layout({children, list}) {
return (
<div className="flex gap-4">
{children}
{list}
</div>
)
}
you have to tell next which should be rendered in children when you at `/post-1` right?
West African LionOP
If I don't need
children here, and I only care about list, I should be able to put the generateStaticParams function in app/@list/[postPages]/page.tsx and have it work, right?no
I don't think you can ignore children in a layout?
oh you can but next will assume you have it I think
so you still need app/postPages]/page.tsx
@Ray so you still need app/postPages]/page.tsx
West African LionOP
This part is what is still unclear to me.
I think you should start the dev server without static export
and see what happen if you don't have
app/postPages]/page.tsxWest African LionOP
I expect "children" and "parallel-children" to get to my layout. What I do with each should not be an issue for the layout.
However, if I need to "generate the static params" for my "parallel-children"... I would logically put those in the "deeper" page, not the outer one.
However, if I need to "generate the static params" for my "parallel-children"... I would logically put those in the "deeper" page, not the outer one.
(And I'd even expect to be able to have different [dynamic] pages generated.)
what are you trying to achieve
I don't get it what you need
@Ray what are you trying to achieve
West African LionOP
I do think that my (development) needs are already met with:
this kind of structure.
app/
(posts)/
[postPages]/
- page.tsx
- layout.tsx
- page.tsxthis kind of structure.
So that's not an issue, right now.
What I am trying to understand, really, is whether parallel routes should generate pages with just:
or not.
What I am trying to understand, really, is whether parallel routes should generate pages with just:
app/
(posts)/
@list/
[postPages]/
- page.tsx
- layout.tsx
- page.tsxor not.
@Ray parallel route allow you render one or more page in a layout.
In static export, you need to provide all value.
so let say you have `app/@list/[postPages]/page.tsx` and you have this layout
ts
export default function Layout({children, list}) {
return (
<div className="flex gap-4">
{children}
{list}
</div>
)
}
you have to tell next which should be rendered in children when you at `/post-1` right?
West African LionOP
The
list of this example you made, right?@Ray you made that?
West African LionOP
What is "that"?
I was wondering what the difference was between this idea and using [page] or [...page]
i use both.
using getserversideprops
using getserversideprops
export async function getServerSideProps(context) {
const _user =
context.params.user
? await SqlExecute.getAccountByUsername(context.params.user)
: undefined;
return _user === undefined || _user.length === 0
? { props: { user: null, notFound: true } }
: { props: { user: _user, notFound: false } };
};@goodsie I was wondering what the difference was between this idea and using [page] or [...page]
West African LionOP
"This idea" is "parallel routes and dynamic routes"?
I guess I dont understand it rightly
I shall read
@Ray oh yea
West African LionOP
If that's it, though... I may decide to ignore "children" and not use those in my layout.
What would be wrong about it?
What would be wrong about it?
but that's not how next work
like i said, start the dev server without static export
and see what happen if you ignore the "children"
you will get 404
@Ray like i said, start the dev server without static export
West African LionOP
(Apologies, I was away from my computer until some minutes ago; I couldn't be testing stuff out til a moment ago!)
np try and see how next work
and you might not need parallel route
@Ray and you might not need parallel route
West African LionOP
(I definitely do not need it for my purposes!)
Let's say my exploration of the topic is more "for science" and personal curiosity!
(I feel like knowing your toolbox helps with working better with it!)
app/[postPages]/page.tsx <-- this is the entry point, if the server can't find this, it will throw 404app/@list/[postPages]/page.tsxapp/@top/[postPages]/page.tsxit the route exist, the layout will render
West African LionOP
This actually makes sense (even visually) to me...
Also, I tried the solution you showed me and I still had some
As soon as I created
console.log statements I added in the library to try and understand what was going on.As soon as I created
app/[postPages]/page.tsx, I got:fallback: static, page: /(posts)/[postPages]/page, staticPaths: /0,/1,/2,/3,/4In hindsight, what might be missing is:
this error is quite misleading.
Error: Page "/(posts)/@list/[postPages]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.this error is quite misleading.
After all, what it requires is
generateStaticParams() for "the entry point"; not the parallel routes.yeah some error are misleading
West African LionOP
Thanks for the support, Ray! 🙂
I'll mark this as solved!
I'll mark this as solved!