Astro: Building the Lambda@Edge Adapter

Published on: Sun Jan 08 2023




Astro is a great framework for create static sites, and it also has some neat features.

Did you know it’s not just limited to static sites anymore ? It now supports server-side rendering (SSR)!

Yep, you heard that right!

To makes things easier, Astro provides an integration out of the box for Node.js - @astrojs/node.

These “integrations” provide the ability to customize functionality and behaviors for your project.

This got me thinking - can we run this at the edge with Lambda@Edge ?

Honestly, Googling around, I didn’t find much resources out there for something like this.

So, I thought to myself why don’t I try to build an integration for it.

After much experimentation, and trial & error....

Here we are - @common-web/astro-lambda-edge!

The implementation is heavily inspired by @astrojs/node.

In this article, we’ll briefly go over how this package works!

The results

Before we get into the weeds, let’s talk about what the expected result from this build.

How does this Astro integration fit in with the overall AWS architecture that we plan to build ?

The architecture

The architecture that we are aiming for is serving our site through an AWS architecture that using Cloudfront, S3 and Lambda@Edge.

There are two flows for our origin request (Lambda):

  1. Perform server-side rendering
  2. Forward to S3
Illustration of AWS architecture with Astro
Illustration of AWS architecture with Astro

What each component does:

  • S3 bucket - For storing the static assets (css , js , etc)

  • Cloudfront - Accelerating and delivering the data/content globally by bringing it closer to the user

  • Lambda@Edge - For the performing the server-side rendering

So, from this we know what we expect from our astro build.

What we need is the static assets, server code (to run the ssr).

How does it work ?

This package (@common-web/astro-lambda-edge) actually does not change the Astro output too much.

Rather, it slightly alters the server output to better fit the expectations of Lambda@edge. Specifically, the origin request.

There are a few key elements in this adapter that helps to make Astro compatible for our desired AWS architecture with Cloudfront and Lambda@Edge.

Let’s through them in a bit more detail.

Transforming the request

The cloudfront event that we receive in our Lambda is going to be different than what you’d typically expect in something like a node server.

Therefore, we need to map this request so it is compatible with a node server (because this is what Astro is expecting).

These are things like headers, url, etc.

Forwarding to requests to S3

There are two paths in our Lambda@Edge function:

  1. SSR render (/ , /about , etc)
  2. Foward to S3 (.css , .js , etc)

Since we are storing our assets in S3, in our Lambda@Edge we will need to foward any requests that has asset extensions (.css , .js , .png etc) to S3.

Returning the response

With Cloudfront, it expects the response to be in a certain format.

So, that means we’ll need to map the response we get from Astro into a format that is compatible with Cloudfront.

To see the format, check out CloudFrontResultResponse.

The outputs

Let’s quickly go over what outputs we will get when we run astro build.

Astro build (output)

Here is what the output from Astro with @common-web/astro-lambda-edge adapater looks like.

Illustration of Astro build assets
Illustration of Astro build assets

Astro build to AWS components

Here is how those build assets map to the components in our AWS Architecture.

Illustration of Astro build assets mapped to AWS
Illustration of Astro build assets mapped to AWS


And that’s it for the overview.

Essentially, this adapter package makes the Astro SSR server compatible with Cloudfront and Lambda@Edge. That’s really all it does!


Give it a try, and let me know what you think! Feel free to submit changes/fixes if you see it missing something!

And... that’s all for now, stay tuned for more!

If you found this helpful or learned something new, please do share this article with a friend or co-worker 🙏❤️ (Thanks!)

Enjoy the content ?

Then consider signing up to get notified when new content arrives!

Jerry Chang 2023. All rights reserved.