Bringing Angular Components to Astro Islands 🏝
Tags: astro, angular, vite
Published: 2022-08-29 15:05:00

[Astro](https://astro.build) 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](https://dev.to/brandontroberts/how-i-rebuilt-my-angular-blog-and-became-an-astronaut-2ali) 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](https://blog.angular.io/angular-v14-is-now-available-391a6db736af) 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](https://analogjs.org), 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:
```sh
npm init astro
```

With yarn:
```sh
yarn create astro
```

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:

```sh
astro add @analogjs/astro-angular
```

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:

```js
import { defineConfig } from 'astro/config';

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

// https://astro.build/config
export default defineConfig({
  integrations: [analogjsAngular()]
});
```

## 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.

```json
{
  "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"]
}
```

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`.

```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;
  }
}
```

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.

```html
---
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>
```

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

```ts
<HelloComponent client:visible />
```

Find more information about [Client Directives](https://docs.astro.build/en/reference/directives-reference/#client-directives) in the Astro documentation.

## Developing the Website

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

```sh
yarn astro dev
```
 
Visit the website at http://localhost:3000, including the new Angular component 😎.

![Astro + Angular](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fj9p56aviballli0gf1l.png)

Now its your turn to make some tweaks and play around 😀.

To build for deployment:

```sh
yarn astro build
```

## 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](https://github.com/analogjs/analog) and [Discord](https://discord.gg/mKC2Ec48U5). 

## Learn More

- Visit the [Analog Docs](https://analogjs.org)
- Follow the Analog project on [Twitter](https://twitter.com/analogjs)
- Join me at [ViteConf](https://viteconf.org/) to learn more about "Vite, Meta-frameworks, and Angular".

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