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!
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 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):
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).
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.
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.
There are two paths in our Lambda@Edge function:
/
, /about
, etc).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.
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.
Let’s quickly go over what outputs we will get when we run astro build.
Here is what the output from Astro with @common-web/astro-lambda-edge adapater looks like.
Illustration of Astro build assets
Here is how those build assets map to the components in our AWS Architecture.
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!
Links:
github code - astro-lambda-edge
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!)
Then consider signing up to get notified when new content arrives!