Bringing Angular Components to Astro Islands 🏝

Brandon Roberts - Aug 29 '22 - - Dev Community

Astro is a relatively new web framework that has a focus on helping you build faster websites. It also has a very interesting extension point in that you can bring your own UI framework of choice, including React, Svelte, Vue, and more. I even rewrote my Angular blog to use Astro in its alpha release days. This post is about bringing things full circle and using Angular components inside an Astro project.


TL;DR
GitHub repo: https://github.com/brandonroberts/angular-astro-islands
Sample website: https://angular-analog-astro-islands.netlify.app/
Partnership Opportunities: https://analogjs.org/docs/sponsoring


I initially wanted to use Angular components in Astro but couldn't do to multiple constraints. Many things have changed since then. Angular v14 includes standalone components that no longer need NgModules. Astro has continued to be developed, switched from Snowpack to Vite for its underlying build tool, and been released as 1.0. In the meantime, I've been working on a Analog, a meta-framework for building Angular applications and websites powered by Vite.

Astro provides integrations to allow additional UI frameworks to render their components inside Astro projects. With these pieces together, we can now take Angular components, render them in Astro, and hydrate them on the client.

Let's dive in!

Creating a New Astro Project

First, create a new Astro project:

With npm:

npm init astro
Enter fullscreen mode Exit fullscreen mode

With yarn:

yarn create astro
Enter fullscreen mode Exit fullscreen mode

Follow the prompts, along with choosing Just the basics to start. Next, is adding the @analogjs/astro-angular integration.

Adding the Angular Integration

The @analogjs/astro-angular integration adds support for using Angular components in an Astro project. The integration provides the Vite Plugin for Angular to compile and transform Angular components, renders Angular components on the server, and hydrates the components as needed on the client.

Use the astro add command to install the integration:

astro add @analogjs/astro-angular
Enter fullscreen mode Exit fullscreen mode

This command:

  • Installs the @analogjs/astro-angular package.
  • Adds the @analogjs/astro-angular integration to the astro.config.mjs file.
  • Installs the necessary Angular dependencies to render Angular components on the server hydrate them on the client, and common Angular dependencies, such as @angular/common and @angular/forms.

After installation, the astro.config.mjs looks like this:

import { defineConfig } from 'astro/config';

import analogjsAngular from "@analogjs/astro-angular";

// https://astro.build/config
export default defineConfig({
  integrations: [analogjsAngular()]
});
Enter fullscreen mode Exit fullscreen mode

Setting up the TypeScript config

The Angular integration needs a tsconfig.app.json at the root of the project for compilation.

Create a tsconfig.app.json in the root of the project.

{
  "extends": "./tsconfig.json",
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "noEmit": false,
    "target": "es2020",
    "module": "es2020",
    "lib": ["es2020", "dom"]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  },
  "files": [],
  "include": ["src/**/*.ts"]
}
Enter fullscreen mode Exit fullscreen mode

You can tweak the compiler settings as needed.

Adding an Angular Component

The Angular integration only supports rendering standalone components. With that caveat out of the way, defining an Angular component using standalone features is relatively straightforward.

Define a component in the components folder. The example below uses src/components/hello.component.ts.

import { NgIf } from '@angular/common';
import { Component } from '@angular/core';

@Component({
  selector: 'app-hello',
  standalone: true,
  imports: [NgIf],
  template: `
    <p>Hello from Angular!!</p>

    <button (click)="toggle()">Toggle</button>

    <p *ngIf="show">Toggled</p>
  `,
})
export class HelloComponent {
  show = true;

  toggle() {
    this.show = !this.show;
  }
}
Enter fullscreen mode Exit fullscreen mode

This is a pretty simple Angular component that toggles some text to show change detection working properly.

Next, add the Angular component to the Astro component template. In the generated Astro project, add the HelloComponent to the src/pages/index.astro page.

---
import Layout from '../layouts/Layout.astro';
import Card from '../components/Card.astro';
import { HelloComponent } from '../components/hello.component.ts';
---

<Layout title="Welcome to Astro.">
    <main>
        <h1>Welcome to <span class="text-gradient">Astro</span></h1>

        <!-- Angular Component -->
        <HelloComponent />

        <!-- HTML πŸ˜‰ -->

        </main>
</Layout>
Enter fullscreen mode Exit fullscreen mode

This only renders the HTML from the Angular component. To hydrate the component on the client, use one of Astro's client directives:

<HelloComponent client:visible />
Enter fullscreen mode Exit fullscreen mode

Find more information about Client Directives in the Astro documentation.

Developing the Website

To view the running website, start the dev server using the Astro CLI:

yarn astro dev
Enter fullscreen mode Exit fullscreen mode

Visit the website at http://localhost:3000, including the new Angular component 😎.

Astro + Angular

Now its your turn to make some tweaks and play around πŸ˜€.

To build for deployment:

yarn astro build
Enter fullscreen mode Exit fullscreen mode

Summary

This integration opens the door for web developers to build faster websites using Astro with Angular components. The Analog project and Astro Integration is actively being developed, so if you'd like to contribute, join us on GitHub and Discord.

Learn More

  • Visit the Analog Docs
  • Follow the Analog project on Twitter
  • Join me at ViteConf to learn more about "Vite, Meta-frameworks, and Angular".

So what do you think? Leave a ❀️ on the post, and leave a comment and let me know your thoughts.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player