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
With yarn:
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:
astro add @analogjs/astro-angular
This command:
- Installs the
@analogjs/astro-angular
package. - Adds the
@analogjs/astro-angular
integration to theastro.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()]
});
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"]
}
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;
}
}
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>
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 />
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
Visit the website at http://localhost:3000, including the new Angular component 😎.
Now its your turn to make some tweaks and play around 😀.
To build for deployment:
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 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.