-
Notifications
You must be signed in to change notification settings - Fork 12k
fix(@angular/ssr): support getPrerenderParams
for wildcard routes
#30072
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: main
Are you sure you want to change the base?
Conversation
dde7bb8
to
9585353
Compare
e583b67
to
ff6d1b4
Compare
@@ -63,7 +63,7 @@ export interface ServerRoutePrerender extends Omit<ServerRouteCommon, 'status'> | |||
// @public | |||
export interface ServerRoutePrerenderWithParams extends Omit<ServerRoutePrerender, 'fallback'> { | |||
fallback?: PrerenderFallback; | |||
getPrerenderParams: () => Promise<Record<string, string>[]>; | |||
getPrerenderParams: () => Promise<(string[] | Record<string, string>)[]>; |
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.
Another option would be to add a different option something like getPrerenderPath
or getPrerenderSegments
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.
IMHO, reusing getPrerenderParams
is reasonable. I think the intent behind this function is still the same whether it's filling in :foo
or **
. Though I'm a little worried that supporting the two in an xor fashion might be confusing for developers. If we can find a reasonable way to support :foo/**
, then using a single function LGTM.
ff6d1b4
to
bb94a89
Compare
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.
What about a path like '/product/:first/**/:second'
? Not sure if we allow segments after **
(reading this PR, seems like no?), but presumably we at least allow them before? Is this feature limited to either /:first
xor /**
?
I feel like we could support both with something like:
{
path: '/product/:first/**/:second',
renderMode: RenderMode.Prerender,
async getPrerenderParams() {
return [
{'first': 'foo', __spread__: ['category', '1'], 'second': 'bar'},
{'first': 'bar', __spread__: ['category', '2'], 'second': 'foo'},
];
}
}
Not sure exactly the right way of identifying the spread array though. Maybe a Symbol imported from @angular/ssr
?
Is there a better way of mixing **
and :foo
syntax in the same path? Is :foo/**
a rare enough pattern that we just don't care at this stage?
return value; | ||
}); | ||
const routeWithResolvedParams = isParamsArray | ||
? currentRoutePath.replace('**', params.join('/')) |
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.
Consider: What if I render ['foo/bar']
?
I remember we had a discussion on this previously, do we need to escape /
characters returned by getPrerenderParams
? Or did we decide not to do that?
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.
No we are not escaping any character. foo/bar
will be rendered it's a valid URL.
@@ -63,7 +63,7 @@ export interface ServerRoutePrerender extends Omit<ServerRouteCommon, 'status'> | |||
// @public | |||
export interface ServerRoutePrerenderWithParams extends Omit<ServerRoutePrerender, 'fallback'> { | |||
fallback?: PrerenderFallback; | |||
getPrerenderParams: () => Promise<Record<string, string>[]>; | |||
getPrerenderParams: () => Promise<(string[] | Record<string, string>)[]>; |
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.
IMHO, reusing getPrerenderParams
is reasonable. I think the intent behind this function is still the same whether it's filling in :foo
or **
. Though I'm a little worried that supporting the two in an xor fashion might be confusing for developers. If we can find a reasonable way to support :foo/**
, then using a single function LGTM.
Edit |
bb94a89
to
02cf4f4
Compare
What about |
Yes, this is not handled at the moment, maybe the simplest would be to allow something like instead of changing the signature of the function {
path: '/product/:first/**',
renderMode: RenderMode.Prerender,
async getPrerenderParams() {
return [
{'first': 'foo', '**': 'category/1', 'second': 'bar'},
];
}
} |
Handle `getPrerenderParams` return values when used with wildcard route paths. Supports returning an array of path segments (e.g., `['category', '123']`) for `**` routes. This enables more flexible prerendering configurations in server routes. Example: ```ts { path: '/product/**', renderMode: RenderMode.Prerender, async getPrerenderParams() { return [['category', '1'], ['category', '2']]; } } ``` Closes angular#30035
02cf4f4
to
5cd43cf
Compare
Would it be worth getting some wider feedback from the team (Andrew or Jan in particular)? Maybe a quick one-pager would be enough to get some quick thoughts on the approach. I'm open to |
I like Afaict there's no pre-existing name for the value captured from the wildcard. |
@atscott, any thoughts? |
@AndrewKushnir might also have some quick thoughts here. |
I'm wondering what are the use-cases for this feature? What would be "hiding" behind the Potentially, we can apply the following rules:
However, I'm not sure if that would be too limiting for the use-cases that this feature is improving. |
One example is when catch-all routes need to be prerendered. For instance, see this issue: #30035. In such cases, parameterized routes can't be used effectively because the nesting depth is arbitrary. As for the rules you mentioned, those sound good to me, and I don't see them as restrictive. |
Handle
getPrerenderParams
return values when used with wildcard route paths.Supports returning an array of path segments (e.g.,
['category', '123']
) for**
routes.This enables more flexible prerendering configurations in server routes.
Example: