[Complete] RFC: Route configuration for hybrid rendering #56785
Replies: 17 comments 53 replies
-
Can you provide more clarity about how to use server only env variables in also it would be good to add |
Beta Was this translation helpful? Give feedback.
-
For SSG routes with dynamic parameters, it would be good to be able to support multiple dynamic parameters. Ie Maybe not the cleanest of design practices, but we should still be able to do it, or put a limit or something on how many we can do. |
Beta Was this translation helpful? Give feedback.
-
I really like the idea to move away from freestyle server.ts into a more structured way of handling common ssr challenges. Our SSR rendering is quite slow (~1-3 sec) so we have a lot of caching in place. (SSR performance issues are difficult to track down) |
Beta Was this translation helpful? Give feedback.
-
Thanks for this RFC. It looks exciting! I understand why we need a separate server-side routing file, but I'd like to know if we can ensure somehow that it aligns with the client-side one, e.g., via the Angular Language Server. I'm also wondering what the server-side counterpart of a lazy client-side route definition is. Will there be a server-side router configuration for each client-side route definition, or will we put everything into one server-side router configuration? |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
Thanks for the RFC, indeed most applications will be using a combination of these rendering strategies based on the route. I have 3 points:
While caching SSR pages (ISR) and invalidating caches can improve this, personalized content (content based on the user logged in) makes caching the whole page impractical in many cases as well, not to mention the added complexity of invalidating caches. To me, prioritizing improving SSR performance is critical. Looking forward to streaming and improved performance of Inlining critical CSS. |
Beta Was this translation helpful? Give feedback.
-
Thanks for opening for comment. I have a couple of questions,
|
Beta Was this translation helpful? Give feedback.
-
Discussion Question 3: Missing Use Cases: How can one control the |
Beta Was this translation helpful? Give feedback.
-
Discussion Question 4: Response / Request objects: Are you planning to expose the whole Request API or just a subset and then extend as needed? For example, if Also, semantically speaking, the Web Request represents a request on the sending end, not the receiving end. |
Beta Was this translation helpful? Give feedback.
-
I understand the point of having separate declarations to distinguish between the server and client, but this approach also increases the learning curve and adds a potential extra file. I believe it is more valuable to keep it simple. The mode should provide enough information to determine if it is a server or client route. |
Beta Was this translation helpful? Give feedback.
-
Thanks for planning this feature I wanted something like this for my app. I was trying to setup route based rendering for my app but I couldn't get it working in angular v16. I wanted to do SSG for some static routes (for seo) and CSR for the rest of the app. I ran into issues when some of the routes which needed to be CSR only threw errors cause I was using localstorage and I couldn't figure out how to disable SSR/SSG for those routes.
|
Beta Was this translation helpful? Give feedback.
-
Question 3: I think there is an intermediate state between SSG and SSR. Use case (mine): a news site, publishing some articles every day. |
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
question 3&4 : in case of prerender what if i have for example 2000 or even more ids would it be too large to host on the server with all these pre rendered pages ,i think rss_feed is good for such cases. |
Beta Was this translation helpful? Give feedback.
-
This is awesome! Just a few clarifications...
Thanks! J |
Beta Was this translation helpful? Give feedback.
-
This issue is still open. Could you please provide an update on the current status? |
Beta Was this translation helpful? Give feedback.
-
How event replay of ssr is going to work with secondary or multiple outlets running at the same time with mixed render types (browser and server)?, ie some dialogs with routing. Will this be supported ?, or all the events will be replayed after the ssr renders, if so browser render should use |
Beta Was this translation helpful? Give feedback.
-
Author: @alan-agius4
Contributors: @AndrewKushnir, @dgp1130
Posted: 1st July 2024
Status: Closed
Introduction
As Angular continues to advance, it is crucial to enhance its hybrid rendering capabilities. These enhancements address the growing complexity and performance demands of modern web applications. Server-side rendering and build-time prerendering provide significant benefits, such as improved performance, better SEO, and a smoother user experience by delivering fully rendered pages quickly.
To fully leverage these capabilities, there is a need to provide additional route information. This includes page rendering mode, additional response headers, response status codes, and more. These enhancements enable more fine-grained control over how each route is handled and rendered, allowing developers to optimize their applications for different scenarios and requirements.
By introducing these new capabilities, we aim to resolve several issues reported by the community, including the need for better dependency injection (DI) token handling, asynchronous route declarations for static prerendering, and reduced dependencies on Node.js. Additionally, these improvements will address challenges related to integrating SSR with internationalization (i18n), supporting SSR entry points in Angular's build tools, and more.
The naming used in this document is not final and is intended to accurately describe the features being discussed. The final API design and naming will be determined in a later phase taking into consideration the input from this RFC.
Overview
Currently, we automatically render server-side pages with routing parameters and prerender non-parameterized pages. We offer configuration to override this behavior and this proposal intends to make it more granular and easier to configure, while also enabling prerendering (SSG) for parameterized routes.
Initially, our aim is to provide developers with the following configuration options per route:
Looking forward, we plan to further extend this to include:
Improvements proposed in this RFC address a number of reported issues:
commonEngine.render()
does not provide its value to applicationCommonEngine
@angular-devkit/build-angular:dev-server
Current challenges and proposed solution
Challenges
Route
interface with additional options, server-specific code must be integrated into the client-side codebase. This introduces complexity that would rely on techniques to eliminate server-only code from client bundles.Proposed solution
To address these challenges, we propose implementing a separate route configuration specifically tailored for the server. There is no need to re-declare your routes, you can only add ones that require some specific server behavior.
This distinct configuration is kept separate from the Angular router, ensuring a clear separation between server-side and client-side code. This separation helps maintain clarity and simplifies the management of routing concerns.
Example configuration
Angular application route configuration (unchanged)
Server route configuration
While not all routes need to be re-defined in the server configuration, those that are defined must match the routes provided in the Angular router. Discrepancies between the server configuration and the Angular router will result in build-time errors.
In the above example, all routes will be prerendered except for the
/login
route, which will be server-side rendered. The/**
will act as a catch-all, so the server route configuration does not need to define all the routes explicitly.What kind of feedback are we looking for?
While we're eager to hear any and all comments on the proposed changes, there are a few specific discussion points we are particularly interested in. Specifically, we would appreciate feedback on the following:
When you leave a comment, please specify the question(s) to which you are responding. As always, keep our code of conduct in mind. We understand that a proposal of this scope significantly impacts Angular and how you use it in your projects. We appreciate your commitment and investment in this project and ask that you keep comments respectful.
Proposal
Rendering mode
Initially, support will be provided for three rendering modes: SSR, SSG and CSR. This allows developers to have precise control over how each route is rendered, offering an easy way to exclude certain routes from prerendering. For more details, refer to the related issue.
Upon receiving a request, the server matches it with the route configuration. If applicable, the server will serve either the pre-rendered SSG file, an HTML document for CSR, or SSR the page directly.
SSG configuration for routes with dynamic parameters
Currently, to enable SSG for a route with dynamic parameters (e.g.,
/product/:id
), developers must create a separateroutes.txt
file in advance and populate it with a list of all possible routes.The proposed API streamlines the process of prerendering parameterized routes, which typically require data fetching from external sources or databases, such as a Content Management System (CMS). With the
getPrerenderPaths
function, developers can define which paths need data retrieval and subsequent pre-rendering. This function is executed exclusively during the build phase and allows to provide parameterized values necessary for pre-rendering a route. The function is invoked in an injection context, so you can use Angular DI there via the `inject` function.In the above case,
/product/1
,/product/2
, and/product/3
will be prerendered.Request and Response access via DI tokens
We are introducing new public-facing APIs designed to streamline common scenarios, where access to the Request and Response instances is required during SSR. These APIs will be automatically configured when you run the
ng new --ssr
orng add @angular/ssr
commands.When integrating Angular SSR, it is important to note several key differences and considerations:
These new APIs ensure that Angular SSR can be effectively utilized across different environments, maintaining functionality and performance.
Injection tokens
REQUEST
: This will be of typeRequest
and will include the request variant specified in the Web specifications.RESPONSE
: This will be of typeResponseInit
and will contain the options specified in the Web specifications for initializing a response.REQUEST_CONTEXT
: This token is of typeunknown
, designed to allow third-party implementations to include additional information not present in the main request. For example, Netlify's context, which includes extra geo-location data. Using theunknown
type in TypeScript is necessary to prevent dependence on a specific third-party implementation. This approach strikes a balance between flexibility and type safety.Build-time i18n
One key challenge users encounter involves integrating SSR with build-time i18n. This API aims to address this challenge by efficiently managing i18n. However, several important considerations arise. Each locale corresponds to a distinct application within its bundle, all rendering within a shared global context. This design requires the application to follow some constraints to work effectively.
Restrictions
$localize
will not work inserver.ts
.server.ts
executes outside an Angular application and injection context, therefore Angular DI tokens/providers are not accessible within that file.main.server.ts
or other DI tokens must not be referenced in theserver.ts
instead, the Angular CLI will inject references to the localized application bundle.FAQs
Q: Why use the Web spec Request and Response types?
This approach prevents individual components and services from being dependent on the specific request/response types of your server infrastructure, which is a valuable benefit.
Q: Instead of using an additional routing file, why not use file-based routing?
File-based routing is something we want to explore in the future.
Q: With this new API, will I be able to use my API defined in
server.ts
withng serve
?Yes. One of the goals of this API is to make this possible.
Q: Will inlining of critical CSS be available for non-Node.js environments?
Yes, this API will handle this use case as well.
Q: Will
RESPONSE
andREQUEST
tokens be available during prerendering?No, since there are no requests during prerendering, these tokens will be
undefined
.Beta Was this translation helpful? Give feedback.
All reactions