My name is Carl. I am a software engineer and architect. I blog about C#, .NET, Javascript, AngularJS, nodejs, and more. Thanks for visiting!



Buy me a coffeeBuy me a coffee

Tags

Using Netlify Identity Widget In An Angular Application

Netlify is a platform for hosting frontend web applications. It integrates with GitHub and allows for continuous integration. It also supports a bunch of server-side features like identity, lambda functions, form submissions, or custom microservices. This blog is hosted on Netlify as a single page application using AngularJS. This post will show an example of using the identity service in an Angular application to authenticate users. There is a live demo and the complete source code is available on GitHub. This post assumes the reader is familiar with the structure of an Angular application including routing, components, and services but you don't need to be an expert. It also requires npm and the Angular cli to run locally.

The Netlify Identity Widget

Netlify provides a widget that integrates with their identity service. The goal of this example is to use the identity widget out of the box to show login, logout, sign up, confirm email, and password recovery. Below are a couple screenshots of the widget.

When the netlify identity widget loads on a page, it attaches itself to the window object as a variable named netlifyIdentity. Through javascript, we can open and close the widget, login, logout, and handle events. The supported events include init, login, logout, open, close, and error.

The Angular Application

The example application was created with the Angular cli and written in typescript. I created a wrapper angular service around the netlifyIdentity object named netlifyIdentity.service.ts . There are typings but I didn't want to introduce that dependency. I added the line declare var netlifyIdentity: any; below the import statements. Then in the constructor of the service class I use the netlifyIdentity.on function to specify callbacks for each of the events. I also added a get() function that returns the netlifyIdentity object so components and other services can use it. The full netlifyIdentity.service.ts implementation is below.

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';

declare var netlifyIdentity: any;

@Injectable({
    providedIn: 'root',
  })

export class NetlifyIdentityService {
    constructor(router: Router) {
      netlifyIdentity.init();
      // Bind to events
      netlifyIdentity.on('init', function(user) {
        console.log('init', user)
      });

      netlifyIdentity.on('login', function(user) {   
        console.log('current user', netlifyIdentity.currentUser());
        netlifyIdentity.close();
      });

      netlifyIdentity.on('logout', function() {
        console.log('Logged out'); 
        netlifyIdentity.close();
        router.navigateByUrl('/');
      });

      netlifyIdentity.on('error', function(err) {
        console.error('Error', err)
      }); 

      netlifyIdentity.on('open', function() {
        console.log('Widget opened')
      });

      netlifyIdentity.on('close', function() {
        console.log('Widget closed');
      });
    }
    
    get(): any {
        return netlifyIdentity;
    }
  }


The application consists of 4 components, the home page, a public component, a protected component, and a navigation component. Angular routing is used to route to the public and protected components. The route to the protected component uses a route guard to check the object returned by netlifyIdentity.currentUser() to see if someone is logged in. If someone is logged in, the object contains information about the current user, like their email address. If not, it is null. The route guard will display a javascript alert message and prevent navigation if the object is null.



The navigation component is called nav.component.ts and is responsible for the navigation bar. It contains links for the public route, the protected route, and a login link. When no one is logged in the link says "Login / Sign Up". When someone is logged in their email is displayed with a "Logout" link next to it. It also uses netlifyIdentity.currentUser() to determine if someone is logged in. Additionally, the nav component uses the netlifyIdentity wrapper service to open the widget or logout the current user. The typescript functions for those are below.

openModal(): void {
    console.log("open modal");
    this.netlifyService.get().open();
}

logout(): void {
    console.log("Logout");
    this.netlifyService.get().logout();
}


Handling Email Confirmation and Password Reset

The netlify identity widget handles email confirmation when a user first signs up and password recovery from the forgot password link within the widget. In both cases, Netlify sends the user an email with a link that points back to the root of the site. The link contains a special hash that helps to confirm the user or reset the password. When index.html loads, the netlify identity widget pops up automatically for the user to complete the requested action. That happens as default functionality of the widget. I found this behavior tricky to handle in an angular application because as soon as the index.html file is loaded, Angular takes over and the widget doesn't open for the user to complete the action. I handled this by having 2 index files. index.html is the default home page of the website and index_app.html is the home page of the angular application. The root directive for the angular app goes in index_app.html and the base url is /app. The index.html file doesn't have any angular dependencies but loads the identity widget. Initially, it looks for either the recovery or confirmation hashes and if it doesn't find one, redirects to /app and index_app.html loads. If it finds one, it doesn't do anything and the base widget behavior takes over and the widget opens. When the widget is closed, it's assumed the user is done doing whatever they needed to do with the widget on the root of the site, so it redirects to /app and now the user is in the angular application. I don't know if it's the best method and whether it will work for you depends on the specifics of the application. Below are the index.html and index_app.html files for comparison.

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  
   <!-- include the widget -->
   <script type="text/javascript" src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>

  <title>NetlifyIdentityWidgetEx</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
   <script>
      console.log(top.window.location.hash);
      if (top.window.location.hash.indexOf("recovery_token=") === -1 && top.window.location.hash.indexOf("confirmation_token") === -1) {
         top.window.location = "/app";
      }

      netlifyIdentity.on('close', function() {
        console.log('Widget closed');
        window.location = "/app";
      });
  </script>
</body>
</html>


index_app.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

  <!-- include the widget -->
   <script type="text/javascript" src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>

  <title>NetlifyIdentityWidgetEx</title>
  <base href="/app">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <cl-app-root></cl-app-root>
</body>
</html>


Conclusion

In conclusion, this is one example of using the netlify identity widget in an angular application. We created a wrapper angular service for the netlify identity javascript object and used that in the angular components and services. The angular application is at /app and uses index_app.html. The default index.html is used to handle special netlify identity widget functionality like reset password and confirm user and redirects to index_app.html. Check out the live demo and the complete source code for this example is available on GitHub




If you enjoyed this article...

Buy me a coffeeBuy me a coffee



© 2025 Carl Layton Creative Commons License Disclaimer
An unhandled error has occurred. Reload 🗙