angular: Add support to return different Http Status Code e.g. 404, 301 Redirect and Custom Headers e.g. NoIndex header in renderApplication
Which @angular/* package(s) are relevant/related to the feature request?
platform-server
Description
Returning different HTTP status codes from the renderApplication
call is not supported at this moment, it would be really useful to add support for:
- Returning custom status codes e.g. 404 status code for not found, 503 e.g. in case an API call returns 503 status code.
- Returning 301/302 redirect status code, with option to set redirect url as well.
- Return custom headers e.g. NoIndex headers to let search engines know that this page should not be indexed.
Proposed solution
What if the renderApplication
could return a response object with properties:
- Body
- Status Code
- Redirect URL (Optional)
- Headers
Use case:
I tried using Angular App on Cloudflare Pages/Worker. It works for most of the parts, but when it comes to setting the http status code or custom headers it doesnt seem to work.
I generated a test app using the Cloudflare CLI. The CLI generates an Angular 17 app with below server.ts file:
import { renderApplication } from "@angular/platform-server";
import bootstrap from "./src/main.server";
interface Env {
ASSETS: { fetch: typeof fetch };
}
// We attach the Cloudflare `fetch()` handler to the global scope
// so that we can export it when we process the Angular output.
// See tools/bundle.mjs
async function workerFetchHandler(request: Request, env: Env) {
const url = new URL(request.url);
console.log("render SSR", url.href);
// Get the root `index.html` content.
const indexUrl = new URL("/", url);
const indexResponse = await env.ASSETS.fetch(new Request(indexUrl));
const document = await indexResponse.text();
const content = await renderApplication(bootstrap, {
document,
url: url.pathname,
});
// console.log("rendered SSR", content);
return new Response(content, indexResponse);
}
export default {
fetch: (request: Request, env: Env) =>
(globalThis as any)["__zone_symbol__Promise"].resolve(
workerFetchHandler(request, env)
),
};
So apparently there’s no way to pass the status code or custom headers to the worker workerFetchHandler
since renderApplication
just retuns a string.
About this issue
- Original URL
- State: open
- Created 7 months ago
- Reactions: 15
- Comments: 18 (14 by maintainers)
Although there’s room for enhancing the process of defining status codes, such as for error pages and redirects, currently setting of status codes and headers is possible through Dependency Injection (DI).
tokens.ts
server.ts
app.component.ts
I’m glad you are finally able to solve the issue 😃
@naveedahmed1 Thanks, Yeah finally after 4 days I could get it to work on production. This answer really helped me https://stackoverflow.com/a/77459798/10087419 and one thing that might help other people that have the same problem is that you cant use the injected response and request normally because of their type but if you use
(this.response as any)
the status and redirect functions will work fine.@Gold3nFox Yes you are right, I had an idea that’s why I mentioned other github issues (which of course are still unresolved).
But as per the https://github.com/angular/angular-cli/issues/26323 it seems that the issue where injection tokens are null occurs only on development i.e.
ng serve
, in production it should work fine, right?@naveedahmed1, as the docs mention the
redirect
is a static method on theResponse
interface, thus it should be accessed like:In additional to that, the first parameter of the
redirect
is not statusText, but rather a destination URL.No, since the
responseInitOptions
is created for every request.Are you initialising the
responseInitOptions.headers
?