February 7, 2018

Angular Universal Handle 404 and Set Status Codes

When working with Angular Universal we can implement a full-fledged server. Of course, this does not only include for example to display a 404 page for incorrect urls but also setting the correct status code. So that for example search engines and crawlers in general can process the result correctly.

Angular itself allows us to easily create a 404 page via the router package. However, this is to be regarded as a soft 404. Because although a page is output, the HTTP status code is still 200.

In the first step we start with the trivial issue of displaying the Not-Found-Component. Afterwards we dedicate ourselves to setting the correct status code on the response object that we consume via Express. The example code assumes that you are using lazy load but you can change that.

 

Create a new module for our Not-Found-Component.

 

Add the component to the not-found-routing.module.ts file

 

Add some content to the not-found.component.html file

 

Now only the module remains to be integrated into the routing by editing our app.routes.ts file. Add the following two entries to the end of your routes array. Watch out: redirectTo has to be last!

 

So far so good. We now have a working 404 component that will be displayed when an invalid URL is accessed.

 

 

Setting the Status Code

The end users experience is covered. So lets set the correct status code. This tutorial assumes that you have followed the official Angular Universal Guide but should work for all setups using express. In our express server we have access to the request and response objects. Those are needed in the 404 component in order to set the status code each time the component is loaded. In order to do so we use the dependency injection provided by Angular.

Find the place where renderModuleFactory is used. Usually this is in the server.ts file in your projects root. It might look like this:

We are going to add some extraProviders in order to inject response and request into our Angular application. Modify your code like this:

If you are not using @nguniversal/express-engine then simply use strings as injection tokens. When your application is now running on the server you have access to the request and response obejcts. If the application is running in the browser they are empty.

Now we can extend our Not-Found-Component in order to set the correct status code.

Thats it. A hard page reload that leads to your Not-Found-Component will now result in the correct 404 error code. Feel free to leave a comment on how you liked the approach and if it worked for you!

 

 

 

Related Posts

Avatar photo

theCodeCampus
Developer at thecodecampus </>

Our knowledge is not simply gained through reading - it is trained, tested and constantly being expanded. Because first and foremost, we are all developers at W11K. The know-how that we acquire here as developers, consultants and information architects flows immediately into our training courses and articles for theCodeCampus.


18 responses to “Angular Universal Handle 404 and Set Status Codes”

  1. Manjesh says:

    Works like a charm..awesome ! Thanks a ton. I have been trying to solve this for a while now. Finally found this.

  2. Manjesh says:

    BTW…Though it worked perfectly during a server side build, I got the following error with the webpack compilation:
    Critical dependency: the request of a dependency is an expression
    Had to change some bit of the code in the not-found component. For some reason, webpack does not like injecting using RESPONSE token. Injected “Injector” instead and obtained the response using the following line:
    this.injector.get(RESPONSE) as Response;

    • Can Kattwinkel says:

      Thanks for your feedback! With the most recent version of Angular & CLI it is working for me. Instead of using the response as inejction token you can always create a string, then don’t forget to export it.

      • Johan says:

        Same here, injector resolved the issue. Thanks 🙂

        • Karol says:

          constructor(
          @Inject(PLATFORM_ID) private platformId: Object,
          @Inject(Injector) private injector: Injector
          ) {}

          ngOnInit() {
          if (!isPlatformBrowser(this.platformId)) {
          let response = this.injector.get(RESPONSE) as Response;
          response.status(404);
          }
          }

      • Matt C says:

        I’m also receiving “Critical dependency: the request of a dependency is an expression”. Can you please provide an example of creating a string and exporting this?
        Also tried updating my CLI and Angular and still got the error.

    • sumit patil says:

      can you please tell us what changes you made

  3. Valentin says:

    After adding the value provider into the app engine, I’ve got an error: Error: StaticInjectorError[NgModuleFactoryLoader -> InjectionToken MODULE_MAP]:
    StaticInjectorError(Platform: core)[NgModuleFactoryLoader -> InjectionToken MODULE_MAP]:
    NullInjectorError: No provider for InjectionToken MODULE_MAP!

  4. Johannes says:

    Thanks a lot! Excellent explanation!

  5. […] i’m trying to set 404 status for my wildcard route using angular universal ssr, please suggest me the way to do it. i already tried solution from [404 status code][1] https://blog.thecodecampus.de/angular-universal-handle-404-set-status-codes/ […]

  6. Hardik Thakor says:

    Does this same code work for angular 6? If ‘No’, then what all do I need to change? If ‘Yes’ then mine is not working(Followed this procedure twice)!

  7. I also have a problenm with angular 6. 404 not working.

  8. Jaime says:

    now working in angular 6

  9. Hi, Going to …/not-found does show the 404 page, but going to …/test just shows the google not-found page. I changed loadChildren: './not-found/not-found.module#NotFoundModule' because generating the not-found folder did not put it inside a routes folder. I don’t know if this helps, but I am using renderModuleFactory. – Flo

  10. Julian C. says:

    Really helpful.

    Thanks a lot.

  11. Geo Joseph says:

    What if we need to send 404 for invalid js files, say for example main.8766576.js being accessed from browser. In a normal angular application this returns 200 status code with default index.html page. Is there a way to override this behaviour?
    Since an invalid js file returns index.html the CDN actually caches the html hence causing problem for some users.

  12. Ideara says:

    Toller Artikel, danke für die Weitergabe nützlicher Inhalte. Mit freundlichen Grüßen, David

Leave a Reply

Add code to your comment in Markdown syntax.
Like this:
`inline example`

```
code block
example
```

Your email address will not be published.