Welcome to the first post in our series on optimizing Angular apps for search enginge optimisation (SEO)! In this post, we'll walk you through enabling your Angular app to return custom HTTP responses, such as 404 (Not Found) and 301 (Permanent Redirect), using Angular SSR.
When optimizing your Angular app for SEO, it's crucial to provide the correct HTTP status codes. Here's why returning accurate 404 and 301 responses improves SEO over always returning a 200 status:
404 (Not Found): When search engines encounter a 404 status, they understand that the page does not exist. This prevents them from indexing non-existent content, which could lead to penalties for having "soft 404" pages (pages that return a 200 status but have no useful content).
301 (Permanent Redirect): Tells search engines that the requested URL has permanently moved to a new location. This consolidates SEO value to the new URL, ensuring that link equity (backlinks, page authority) is transferred correctly.
To enable custom HTTP responses (404, 301) in your Angular 17+ app with built-in SSR support, follow these steps:
In your component that handles soft 404 pages, inject the Response object conditionally to ensure it's only used server-side:
import { Response } from 'express';
import { CommonModule, isPlatformServer } from '@angular/common';
import { ChangeDetectionStrategy, Component, Inject, Optional, PLATFORM_ID, inject } from '@angular/core';
import { RESPONSE } from './server.token';
@Component({
selector: 'app-soft-404',
standalone: true,
imports: [CommonModule],
templateUrl: './soft-404.component.html',
styleUrls: ['./soft-404.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class Soft404Component {
platformId = inject(PLATFORM_ID);
constructor(
@Optional() @Inject(RESPONSE) private response: Response
) {
// Only executes server-side
if (isPlatformServer(this.platformId)) {
this.response?.status(404);
}
}
}
Provide the Response token that you'll use for dependency injection (server.token.ts
):
import { InjectionToken } from '@angular/core';
export const RESPONSE = new InjectionToken<Response>('RESPONSE');
In a component that handles redirects, use the Response object for server-side 301 redirection. If you're not on the server, navigate client-side with Angular Router.
import { CommonModule, isPlatformServer } from '@angular/common';
import { ChangeDetectionStrategy, Component, Inject, Optional, PLATFORM_ID, inject } from '@angular/core';
import { Router } from '@angular/router';
import { RESPONSE } from './tokens/server.token';
@Component({
selector: 'app-redirect',
standalone: true,
imports: [CommonModule],
templateUrl: './redirect.component.html',
styleUrls: ['./redirect.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RedirectComponent {
private readonly platformId = inject(PLATFORM_ID);
constructor(
private readonly router: Router,
@Optional() @Inject(RESPONSE) private response: Response
) {
const redirectUrl = '/new-url'; // Build your URL with your own logic
if (isPlatformServer(this.platformId) && this.response) {
this.response.redirect(301, redirectUrl);
this.response.end();
} else {
this.router.navigate([redirectUrl]);
}
}
}
Update server.ts to include the Response token and ensure proper error handling:
// All regular routes use the Angular engine
server.get('*', (req, res, next) => {
commonEngine
.render({
bootstrap: AppServerModule,
documentFilePath: indexHtml,
url: `${req.protocol}://${req.headers.host}${req.originalUrl}`,
publicPath: browserDistFolder,
// Make sure to provide the RESPONSE here
providers: [
{ provide: RESPONSE, useValue: res }
],
inlineCriticalCss: true
})
// If the res.headersSent is true do not send again
.then(html => (!res.headersSent ? res.send(html) : undefined))
.catch((error: Error) => next(error));
});
By following these steps, your Angular app will be able to handle custom 404 and 301 responses accurately, improving both user experience and SEO.
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
.
Make sure you have the following line in your server.ts
file.
.then(html => (!res.headersSent ? res.send(html) : undefined))
If you get the error: TypeError: Cannot read properties of null (reading 'status')
.
It looks like you are running your app in development mode and forgot to mark the this.response
as optional. Make sure you add the ?
. The RESPONSE
is only injected on a production build.
If you receive the error: Error [NullInjectorError]: R3InjectorError(Standalone[_a])[InjectionToken RESPONSE -> InjectionToken RESPONSE -> InjectionToken RESPONSE -> InjectionToken RESPONSE]
It seems you forgot to mark the RESPONSE injection as Optional. In your constructur check you added the @Optional() before the @Inject(RESPONSE).
Now your Angular app is capable of returning 404 and 301 HTTP responses! Server-side rendering helps provide better responses and search engine optimization. Stay tuned for the next blog post in this series, where we dive deeper into enhancing SSR performance and improving SEO.
What other topics are you interested in related to Angular an SEO? Let me know, I am always on the search for new topics to write about.
Hey there, dear readers! Just a quick heads-up: we're code whisperers, not Shakespearean poets, so we've enlisted the help of a snazzy AI buddy to jazz up our written word a bit. Don't fret, the information is top-notch, but if any phrases seem to twinkle with literary brilliance, credit our bot. Remember, behind every great blog post is a sleep-deprived developer and their trusty AI sidekick.
Источник: dev.to
Наш сайт является информационным посредником. Сообщить о нарушении авторских прав.
seo angular ssr howto