{"id":16687381,"url":"https://github.com/rodrigokamada/angular-supabase","last_synced_at":"2025-04-10T00:20:53.061Z","repository":{"id":38445376,"uuid":"416312860","full_name":"rodrigokamada/angular-supabase","owner":"rodrigokamada","description":"Application example built with Angular 15 with authentication using the Supabase service.","archived":false,"fork":false,"pushed_at":"2023-03-07T12:33:57.000Z","size":3301,"stargazers_count":16,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-05T14:38:09.848Z","etag":null,"topics":["angular","authentication","beginners","dev-community","frontend","gh-actions","gh-pages","hacktoberfest","login","signin","signup","stackblitz","supabase","tutorial","webdev","webdevelopment"],"latest_commit_sha":null,"homepage":"https://rodrigokamada.github.io/angular-supabase/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rodrigokamada.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"rodrigokamada"}},"created_at":"2021-10-12T11:42:03.000Z","updated_at":"2025-02-11T04:54:25.000Z","dependencies_parsed_at":"2022-08-19T14:20:07.806Z","dependency_job_id":null,"html_url":"https://github.com/rodrigokamada/angular-supabase","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigokamada%2Fangular-supabase","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigokamada%2Fangular-supabase/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigokamada%2Fangular-supabase/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigokamada%2Fangular-supabase/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rodrigokamada","download_url":"https://codeload.github.com/rodrigokamada/angular-supabase/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248131962,"owners_count":21052955,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","authentication","beginners","dev-community","frontend","gh-actions","gh-pages","hacktoberfest","login","signin","signup","stackblitz","supabase","tutorial","webdev","webdevelopment"],"created_at":"2024-10-12T15:08:59.095Z","updated_at":"2025-04-10T00:20:53.006Z","avatar_url":"https://github.com/rodrigokamada.png","language":"TypeScript","readme":"# Angular Supabase\n\n\nApplication example built with [Angular](https://angular.io/) 15 with authentication using the [Supabase](https://supabase.io/) service.\n\nThis tutorial was posted on my [blog](https://rodrigo.kamada.com.br/blog/autenticacao-usando-o-supabase-em-uma-aplicacao-angular) in portuguese and on the [DEV Community](https://dev.to/rodrigokamada/authentication-using-the-supabase-to-an-angular-application-2jek) in english.\n\n\n\n[![Website](https://shields.braskam.com/v1/shields?name=website\u0026format=rectangle\u0026size=small\u0026radius=5)](https://rodrigo.kamada.com.br)\n[![LinkedIn](https://shields.braskam.com/v1/shields?name=linkedin\u0026format=rectangle\u0026size=small\u0026radius=5)](https://www.linkedin.com/in/rodrigokamada)\n[![Twitter](https://shields.braskam.com/v1/shields?name=twitter\u0026format=rectangle\u0026size=small\u0026radius=5\u0026socialAccount=rodrigokamada)](https://twitter.com/rodrigokamada)\n[![Instagram](https://shields.braskam.com/v1/shields?name=instagram\u0026format=rectangle\u0026size=small\u0026radius=5)](https://www.instagram.com/rodrigokamada)\n\n\n\n## Prerequisites\n\n\nBefore you start, you need to install and configure the tools:\n\n* [git](https://git-scm.com/)\n* [Node.js and npm](https://nodejs.org/)\n* [Angular CLI](https://angular.io/cli)\n* IDE (e.g. [Visual Studio Code](https://code.visualstudio.com/))\n\n\n\n## Getting started\n\n\n### Create and configure the account on the Supabase\n\n**1.** Let's create the account. Access the site [https://supabase.io/](https://supabase.io/) and click on the button *Start your project*.\n\n![Supabase - Home page](https://res.cloudinary.com/rodrigokamada/image/upload/v1635016136/Blog/angular-supabase/supabase-step1.png)\n\n**2.** Click on the button *Continue with GitHub*.\n\n![Supabase - Sign in](https://res.cloudinary.com/rodrigokamada/image/upload/v1635016136/Blog/angular-supabase/supabase-step2.png)\n\n**3.** Fill in the fields *Username or email address*, *Password* and click on the button *Sign in* to login with your GitHub account and if you don't have an account, click on the button *Create an account* to create a new account. [In this tutorial](https://github.com/rodrigokamada/angular-github-actions) there is a step-by-step guide to creating a GitHub account.\n\n![Supabase - Sign in to GitHub](https://res.cloudinary.com/rodrigokamada/image/upload/v1635244871/Blog/angular-supabase/supabase-step3.png)\n\n**4.** Click on the button *Authorize supabase*.\n\n![Supabase - Authorize supabase](https://res.cloudinary.com/rodrigokamada/image/upload/v1635019829/Blog/angular-supabase/supabase-step4.png)\n\n**5.** Click on the button *New project*.\n\n![Supabase - New project](https://res.cloudinary.com/rodrigokamada/image/upload/v1635019925/Blog/angular-supabase/supabase-step5.png)\n\n**6.** Click on the menu with the organization name created automatically.\n\n![Supabase - Choose organization](https://res.cloudinary.com/rodrigokamada/image/upload/v1635081922/Blog/angular-supabase/supabase-step6.png)\n\n**7.** Select an *Organization*, fill in the fields *Name* and *Database Password*, select a *Region* and click on the button *Create new project*.\n\n![Supabase - Create a new project](https://res.cloudinary.com/rodrigokamada/image/upload/v1635081922/Blog/angular-supabase/supabase-step7.png)\n\n**8.** Wait for the project creation.\n\n![Supabase - Setting up the project](https://res.cloudinary.com/rodrigokamada/image/upload/v1635089223/Blog/angular-supabase/supabase-step8.png)\n\n**9.** Click on the button *Copy* to copy the key that has been generated, in my case, the key `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNTA4NjA1MCwiZXhwIjoxOTUwNjYyMDUwfQ.CzFuYS6XKvEwW5OsAAPAcHvuo-NVE4PUwDSKgqK9Yas` was copied and click on the button *Copy* to copy the URL that has been generated, in my case, the URL `https://wzlpmcsxrxogtctlznel.supabase.co` was copied becouse this key and URL will be configured in the Angular application.\n\n![Supabase - New project created](https://res.cloudinary.com/rodrigokamada/image/upload/v1635104408/Blog/angular-supabase/supabase-step9.png)\n\n**10.** Click on the menu *SQL* to setting up the database schema.\n\n![Supabase - SQL](https://res.cloudinary.com/rodrigokamada/image/upload/v1635161259/Blog/angular-supabase/supabase-step10.png)\n\n**11.** Click on the card *User Management Starter*.\n\n![Supabase - Scripts](https://res.cloudinary.com/rodrigokamada/image/upload/v1635244744/Blog/angular-supabase/supabase-step11.png)\n\n**12.** Click on the button *RUN*.\n\n![Supabase - User Management Starter](https://res.cloudinary.com/rodrigokamada/image/upload/v1635170492/Blog/angular-supabase/supabase-step12.png)\n\n**13.** Ready! Account created, key generated and database schema configured.\n\n\n\n### Create the Angular application\n\n\n**1.** Let's create the application with the Angular base structure using the `@angular/cli` with the route file and the SCSS style format.\n\n```shell\nng new angular-supabase --routing true --style scss\nCREATE angular-supabase/README.md (1062 bytes)\nCREATE angular-supabase/.editorconfig (274 bytes)\nCREATE angular-supabase/.gitignore (604 bytes)\nCREATE angular-supabase/angular.json (3267 bytes)\nCREATE angular-supabase/package.json (1080 bytes)\nCREATE angular-supabase/tsconfig.json (783 bytes)\nCREATE angular-supabase/.browserslistrc (703 bytes)\nCREATE angular-supabase/karma.conf.js (1433 bytes)\nCREATE angular-supabase/tsconfig.app.json (287 bytes)\nCREATE angular-supabase/tsconfig.spec.json (333 bytes)\nCREATE angular-supabase/src/favicon.ico (948 bytes)\nCREATE angular-supabase/src/index.html (301 bytes)\nCREATE angular-supabase/src/main.ts (372 bytes)\nCREATE angular-supabase/src/polyfills.ts (2820 bytes)\nCREATE angular-supabase/src/styles.scss (80 bytes)\nCREATE angular-supabase/src/test.ts (788 bytes)\nCREATE angular-supabase/src/assets/.gitkeep (0 bytes)\nCREATE angular-supabase/src/environments/environment.prod.ts (51 bytes)\nCREATE angular-supabase/src/environments/environment.ts (658 bytes)\nCREATE angular-supabase/src/app/app-routing.module.ts (245 bytes)\nCREATE angular-supabase/src/app/app.module.ts (393 bytes)\nCREATE angular-supabase/src/app/app.component.scss (0 bytes)\nCREATE angular-supabase/src/app/app.component.html (24617 bytes)\nCREATE angular-supabase/src/app/app.component.spec.ts (1103 bytes)\nCREATE angular-supabase/src/app/app.component.ts (221 bytes)\n✔ Packages installed successfully.\n    Successfully initialized git.\n```\n\n**2.** Install and configure the Bootstrap CSS framework. Do steps 2 and 3 of the post *[Adding the Bootstrap CSS framework to an Angular application](https://github.com/rodrigokamada/angular-bootstrap)*.\n\n**3.** Configure the variable `supabase.url` with the Supabase URL and the variable `supabase.key` with the Supabase key in the `src/environments/environment.ts` and `src/environments/environment.prod.ts` files as below.\n\n```typescript\nsupabase: {\n  url: 'https://wzlpmcsxrxogtctlznel.supabase.co',\n  key: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNTA4NjA1MCwiZXhwIjoxOTUwNjYyMDUwfQ.CzFuYS6XKvEwW5OsAAPAcHvuo-NVE4PUwDSKgqK9Yas',\n},\n```\n\n**4.** Install the `@supabase/supabase-js` library.\n\n```shell\nnpm install @supabase/supabase-js\n```\n\n**5.** Create the `SupabaseService` service.\n\n```shell\nng generate service supabase --skip-tests=true\nCREATE src/app/supabase.service.ts (137 bytes)\n```\n\n**6.** Change the `supabase.service.ts` file and add the lines as below.\n\n```typescript\nimport { Injectable } from '@angular/core';\nimport { AuthChangeEvent, createClient, Session, SupabaseClient, User } from '@supabase/supabase-js';\n\nimport { environment } from '../environments/environment';\n\nexport interface IUser {\n  email: string;\n  name: string;\n  website: string;\n  url: string;\n}\n\n@Injectable({\n  providedIn: 'root',\n})\nexport class SupabaseService {\n\n  private supabaseClient: SupabaseClient;\n\n  constructor() {\n    this.supabaseClient = createClient(environment.supabase.url, environment.supabase.key);\n  }\n\n  public getUser(): User|null {\n    return this.supabaseClient.auth.user();\n  }\n\n  public getSession(): Session|null {\n    return this.supabaseClient.auth.session();\n  }\n\n  public getProfile(): PromiseLike\u003cany\u003e {\n    const user = this.getUser();\n\n    return this.supabaseClient.from('profiles')\n    .select('username, website, avatar_url')\n    .eq('id', user?.id)\n    .single();\n  }\n\n  public authChanges(callback: (event: AuthChangeEvent, session: Session | null) =\u003e void): any {\n    return this.supabaseClient.auth.onAuthStateChange(callback);\n  }\n\n  public signIn(email: string): Promise\u003cany\u003e {\n    return this.supabaseClient.auth.signIn({\n      email,\n    });\n  }\n\n  public signOut(): Promise\u003cany\u003e {\n    return this.supabaseClient.auth.signOut();\n  }\n\n  public updateProfile(userUpdate: IUser): any {\n    const user = this.getUser();\n\n    const update = {\n      username: userUpdate.name,\n      website: userUpdate.website,\n      id: user?.id,\n      updated_at: new Date(),\n    };\n\n    return this.supabaseClient.from('profiles').upsert(update, {\n      returning: 'minimal', // Do not return the value after inserting\n    });\n  }\n\n}\n```\n\n**7.** Create the `SignInComponent` component.\n\n```shell\nng generate component sign-in --skip-tests=true\nCREATE src/app/sign-in/sign-in.component.scss (0 bytes)\nCREATE src/app/sign-in/sign-in.component.html (22 bytes)\nCREATE src/app/sign-in/sign-in.component.ts (279 bytes)\nUPDATE src/app/app.module.ts (493 bytes)\n```\n\n**8.** Change the `src/app/sign-in/sign-in.component.ts` file. Import the `Router` and `SupabaseService` services and create the `signIn` method as below.\n\n```typescript\nimport { Component } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { IUser, SupabaseService } from '../supabase.service';\n\n@Component({\n  selector: 'app-sign-in',\n  templateUrl: './sign-in.component.html',\n  styleUrls: ['./sign-in.component.scss'],\n})\nexport class SignInComponent {\n\n  loading: boolean;\n  user: IUser;\n\n  constructor(private router: Router,\n              private supabaseService: SupabaseService) {\n    this.loading = false;\n    this.user = {} as IUser;\n  }\n\n  public signIn(): void {\n    this.loading = true;\n    this.supabaseService.signIn(this.user.email)\n    .then(() =\u003e {\n    }).catch(() =\u003e {\n      this.loading = false;\n    });\n  }\n\n}\n```\n\n**9.** Change the `src/app/sign-in/sign-in.component.html` file. Add the lines as below.\n\n```html\n\u003cdiv class=\"row justify-content-center my-5\"\u003e\n  \u003cdiv class=\"col-4\"\u003e\n    \u003cdiv class=\"card\"\u003e\n      \u003cdiv class=\"card-body\"\u003e\n        \u003cdiv class=\"row\"\u003e\n          \u003cdiv class=\"col mb-2\"\u003e\n            \u003clabel for=\"email\" class=\"form-label\"\u003eEmail:\u003c/label\u003e\n            \u003cinput type=\"email\" id=\"email\" name=\"email\" #email=\"ngModel\" [(ngModel)]=\"user.email\" class=\"form-control form-control-sm\"\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"row\"\u003e\n          \u003cdiv class=\"col d-grid\"\u003e\n            \u003cbutton type=\"button\" (click)=\"signIn()\" class=\"btn btn-sm btn-success\" [disabled]=\"loading\"\u003e\n              \u003cspan class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\" *ngIf=\"loading\"\u003e\u003c/span\u003e\n              Sign in\n            \u003c/button\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n**10.** Create the `ProfileComponent` component.\n\n```shell\nng generate component profile --skip-tests=true\nCREATE src/app/profile/profile.component.scss (0 bytes)\nCREATE src/app/profile/profile.component.html (22 bytes)\nCREATE src/app/profile/profile.component.ts (280 bytes)\nUPDATE src/app/app.module.ts (642 bytes)\n```\n\n**11.** Change the `src/app/profile/profile.component.ts` file. Import the `SupabaseService` service and create the `update` method as below.\n\n```typescript\nimport { Component, OnInit } from '@angular/core';\nimport { IUser, SupabaseService } from '../supabase.service';\n\n@Component({\n  selector: 'app-profile',\n  templateUrl: './profile.component.html',\n  styleUrls: ['./profile.component.scss'],\n})\nexport class ProfileComponent implements OnInit {\n\n  loading: boolean;\n  user: IUser;\n\n  constructor(private supabaseService: SupabaseService) {\n    this.loading = false;\n    this.user = {} as IUser;\n  }\n\n  public ngOnInit(): void {\n    const session = this.supabaseService.getSession();\n\n    if (session \u0026\u0026 session.user \u0026\u0026 session.user.email) {\n      this.user.email = session.user.email;\n    }\n\n    this.supabaseService.getProfile()\n    .then((success: any) =\u003e {\n      if (success \u0026\u0026 success.profile) {\n        this.user.name = success.profile.username;\n        this.user.website = success.profile.website;\n        this.user.url = success.profile.avatar_url;\n      }\n    });\n  }\n\n  public update(): void {\n    this.loading = true;\n\n    this.supabaseService.updateProfile(this.user)\n    .then(() =\u003e {\n      this.loading = false;\n    }).catch(() =\u003e {\n      this.loading = false;\n    });\n  }\n\n}\n```\n\n**12.** Change the `src/app/profile/profile.component.html` file and add the lines as below.\n\n```html\n\u003cdiv class=\"row justify-content-center my-5\"\u003e\n  \u003cdiv class=\"col-4\"\u003e\n    \u003cdiv class=\"row\" *ngIf=\"user.url\"\u003e\n      \u003cdiv class=\"col mb-2 text-center\"\u003e\n        \u003cimg [src]=\"user.url\" class=\"rounded-circle\"\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"row\"\u003e\n      \u003cdiv class=\"col mb-2\"\u003e\n        \u003clabel for=\"email\" class=\"form-label\"\u003eEmail:\u003c/label\u003e\n        \u003cinput type=\"email\" id=\"email\" name=\"email\" #email=\"ngModel\" [(ngModel)]=\"user.email\" disabled class=\"form-control form-control-sm\"\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"row\"\u003e\n      \u003cdiv class=\"col mb-2\"\u003e\n        \u003clabel for=\"name\" class=\"form-label\"\u003eName:\u003c/label\u003e\n        \u003cinput type=\"text\" id=\"name\" name=\"name\" #name=\"ngModel\" [(ngModel)]=\"user.name\" class=\"form-control form-control-sm\"\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"row\"\u003e\n      \u003cdiv class=\"col mb-2\"\u003e\n        \u003clabel for=\"website\" class=\"form-label\"\u003eWebsite:\u003c/label\u003e\n        \u003cinput type=\"text\" id=\"website\" name=\"website\" #website=\"ngModel\" [(ngModel)]=\"user.website\" class=\"form-control form-control-sm\"\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"row\"\u003e\n      \u003cdiv class=\"col d-grid\"\u003e\n        \u003cbutton type=\"button\" (click)=\"update()\" class=\"btn btn-sm btn-dark\" [disabled]=\"loading\"\u003e\n          \u003cspan class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\" *ngIf=\"loading\"\u003e\u003c/span\u003e\n          Save\n        \u003c/button\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n**13.** Change the `src/app/app.component.ts` file. Import the `Router` and `SupabaseService` services and create the `isAuthenticated` and `signOut` methods as below.\n\n```typescript\nimport { Component, OnInit } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { SupabaseService } from './supabase.service';\n\n@Component({\n  selector: 'app-root',\n  templateUrl: './app.component.html',\n  styleUrls: ['./app.component.scss'],\n})\nexport class AppComponent implements OnInit {\n\n  session: any;\n\n  constructor(private router: Router,\n              private supabaseService: SupabaseService) {\n    this.session = this.supabaseService.getSession();\n  }\n\n  public ngOnInit(): void {\n    this.supabaseService.authChanges((_, session) =\u003e this.session = session);\n  }\n\n  public isAuthenticated(): boolean {\n    if (this.session) {\n      return true;\n    }\n    return false;\n  }\n\n  public signOut(): void {\n    this.supabaseService.signOut()\n    .then(() =\u003e {\n      this.router.navigate(['/signIn']);\n    });\n  }\n\n}\n```\n\n**14.** Change the `src/app/app.component.html` file and add the menu as below.\n\n```html\n\u003cnav class=\"navbar navbar-expand-sm navbar-light bg-light\"\u003e\n  \u003cdiv class=\"container-fluid\"\u003e\n    \u003ca class=\"navbar-brand\" href=\"#\"\u003eAngular Supabase\u003c/a\u003e\n\n    \u003cbutton class=\"navbar-toggler\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#navbarContent\" aria-controls=\"navbarSupportedContent\" aria-expanded=\"false\" aria-label=\"Toggle navigation\"\u003e\n      \u003cspan class=\"navbar-toggler-icon\"\u003e\u003c/span\u003e\n    \u003c/button\u003e\n\n    \u003cdiv id=\"navbarContent\" class=\"collapse navbar-collapse\"\u003e\n      \u003cul class=\"navbar-nav me-auto mb-2 mb-lg-0\"\u003e\n        \u003cli class=\"nav-item\"\u003e\n          \u003ca class=\"nav-link\" routerLink=\"/signIn\" routerLinkActive=\"active\" *ngIf=\"!isAuthenticated()\"\u003eSign in\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli class=\"nav-item\"\u003e\n          \u003ca class=\"nav-link\" routerLink=\"/profile\" routerLinkActive=\"active\" *ngIf=\"isAuthenticated()\"\u003eProfile\u003c/a\u003e\n        \u003c/li\u003e\n        \u003cli class=\"nav-item\"\u003e\n          \u003ca class=\"nav-link\" routerLink=\"\" (click)=\"signOut()\" *ngIf=\"isAuthenticated()\"\u003eSign out\u003c/a\u003e\n        \u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/nav\u003e\n\n\u003crouter-outlet\u003e\u003c/router-outlet\u003e\n```\n\n**15.** Change the `src/app/app-routing.module.ts` file and add the routes as below.\n\n```typescript\nimport { ProfileComponent } from './profile/profile.component';\nimport { SignInComponent } from './sign-in/sign-in.component';\n\nconst routes: Routes = [\n  {\n    path: '',\n    redirectTo: 'signIn',\n    pathMatch: 'full',\n  },\n  {\n    path: 'profile',\n    component: ProfileComponent,\n  },\n  {\n    path: 'signIn',\n    component: SignInComponent,\n  },\n  {\n    path: '**',\n    redirectTo: 'signIn',\n  },\n];\n```\n\n**16.** Change the `src/app/app.module.ts` file. Import the `FormsModule` module and the `ProfileComponent` and `SignInComponent` components as below.\n\n```typescript\nimport { FormsModule } from '@angular/forms';\n\nimport { ProfileComponent } from './profile/profile.component';\nimport { SignInComponent } from './sign-in/sign-in.component';\n\ndeclarations: [\n  AppComponent,\n  ProfileComponent,\n  SignInComponent,\n],\nimports: [\n  BrowserModule,\n  FormsModule,\n  AppRoutingModule,\n],\n```\n\n**17.** Run the application with the command below.\n\n```shell\nnpm start\n\n\u003e angular-supabase@1.0.0 start\n\u003e ng serve\n\n✔ Browser application bundle generation complete.\n\nInitial Chunk Files | Names         |      Size\nvendor.js           | vendor        |   2.90 MB\nstyles.css          | styles        | 268.30 kB\npolyfills.js        | polyfills     | 128.51 kB\nscripts.js          | scripts       |  76.33 kB\nmain.js             | main          |  34.20 kB\nruntime.js          | runtime       |   6.63 kB\n\n                    | Initial Total |   3.40 MB\n\nBuild at: 2021-10-25T02:19:20.036Z - Hash: 2dc1cd0da7856970b0d8 - Time: 17203ms\n\nWarning: /home/rodrigo/Development/Angular/angular-supabase/node_modules/@supabase/realtime-js/dist/module/RealtimeClient.js depends on 'websocket'. CommonJS or AMD dependencies can cause optimization bailouts.\nFor more info see: https://angular.io/guide/build#configuring-commonjs-dependencies\n\n\n\n** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **\n\n\n✔ Compiled successfully.\n```\n\n**18.** Ready! Access the URL `http://localhost:4200/` and check if the application is working. See the application working on [GitHub Pages](https://rodrigokamada.github.io/angular-supabase/) and [Stackblitz](https://stackblitz.com/edit/angular15-supabase).\n\n![Angular Supabase](https://res.cloudinary.com/rodrigokamada/image/upload/v1635244373/Blog/angular-supabase/angular-supabase.png)\n\n\n\n### Testing the application sign in\n\n**1.** Let's test the application sign in. Access the URL `http://localhost:4200/`, fill in the field *Email* and click on the button *Sign in*.\n\n![Application - Sign in](https://res.cloudinary.com/rodrigokamada/image/upload/v1635166098/Blog/angular-supabase/application-step1.png)\n\n**2.** Open the email with the subject *Confirm Your Signup* and click on the link *Confirm your mail*.\n\n![Application - Sign up email](https://res.cloudinary.com/rodrigokamada/image/upload/v1635165975/Blog/angular-supabase/application-step2.png)\n\n**3.** At this point, you are already signed in. Click on the menu *Profile*.\n\n![Application - Signed in](https://res.cloudinary.com/rodrigokamada/image/upload/v1635167045/Blog/angular-supabase/application-step3.png)\n\n**4.** Fill in the fields *Name* and *Website* and click on the button *Update*.\n\n![Application - Profile](https://res.cloudinary.com/rodrigokamada/image/upload/v1635168762/Blog/angular-supabase/application-step4.png)\n\n**5.** Go back to the Supabase site and click on the menu *New query*.\n\n![Supabase - SQL](https://res.cloudinary.com/rodrigokamada/image/upload/v1635169378/Blog/angular-supabase/supabase-step13.png)\n\n**6.** Fill in the text field with *SELECT * FROM profiles;* content and click on the button *RUN*.\n\n![Supabase - New query](https://res.cloudinary.com/rodrigokamada/image/upload/v1635170129/Blog/angular-supabase/supabase-step14.png)\n\n**7.** Check the updated fields *username* and *website*.\n\n![Supabase - Query result](https://res.cloudinary.com/rodrigokamada/image/upload/v1635170492/Blog/angular-supabase/supabase-step15.png)\n\n**8.** Ready! We test the application sign in and profile update. Supabase documentation is available at [https://supabase.io/docs](https://supabase.io/docs).\n\n\n\n## Cloning the application\n\n**1.** Clone the repository.\n\n```shell\ngit clone git@github.com:rodrigokamada/angular-supabase.git\n```\n\n**2.** Install the dependencies.\n\n```shell\nnpm ci\n```\n\n**3.** Run the application.\n\n```shell\nnpm start\n```\n","funding_links":["https://github.com/sponsors/rodrigokamada"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodrigokamada%2Fangular-supabase","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frodrigokamada%2Fangular-supabase","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodrigokamada%2Fangular-supabase/lists"}