Skip to main content

Use Astro with SST

Create and deploy an Astro site to AWS with SST.


Prerequisites

You'll need at least Node.js 18 and npm 7. You also need to have an AWS account and AWS credentials configured locally.

tip

If you are new to SST, we recommend you start with our latest version instead. Learn more about Ion.


1. Create a new site

Create a new Astro site.

npx create-astro@latest

Now initialize SST in your project root.

cd astro-project
npx create-sst@latest
Ready to deploy

Your Astro site is now ready to be deployed to AWS! Just run — npx sst deploy. But let's take a second to look at how SST makes it easy to add other features to your site.

Start your local dev environment.

npx sst dev

Start Astro

npm run dev
info

When running sst dev, SST does not deploy your Astro site. You are meant to run Astro locally.


2. Add file uploads

Let's add a file upload feature to our Astro site.


Add an S3 bucket

Add an S3 bucket to your sst.config.ts.

sst.config.ts
const bucket = new Bucket(stack, "public");

Bind it to your Astro site.

sst.config.ts
const site = new AstroSite(stack, "site", {
+ bind: [bucket],
});

Generate a presigned URL

To upload a file to S3 we'll generate a presigned URL. Add this to the front matter of pages/index.astro.

pages/index.astro
const command = new PutObjectCommand({
ACL: "public-read",
Key: crypto.randomUUID(),
Bucket: Bucket.public.bucketName,
});
const url = await getSignedUrl(new S3Client({}), command);
tip

With SST we can access our infrastructure in a typesafe way — Bucket.public.bucketName. Learn more.


Add an upload form

Let's add the form. Replace the Layout component in pages/index.astro with.

pages/index.astro
<Layout title="Astro x SST">
<main>
<form action="{url}">
<input name="file" type="file" accept="image/png, image/jpeg" />
<button type="submit">Upload</button>
</form>
<script>
const form = document.querySelector("form");
form!.addEventListener("submit", async (e) => {
e.preventDefault();

const file = form!.file.files?.[0]!;

const image = await fetch(form!.action, {
body: file,
method: "PUT",
headers: {
"Content-Type": file.type,
"Content-Disposition": `attachment; filename="${file.name}"`,
},
});

window.location.href = image.url.split("?")[0] || "/";
});
</script>
</main>
</Layout>

This will upload an image and redirect to it!


3. Add a cron job

Next, we'll add a cron job to remove the uploaded files every day. Add this to sst.config.ts.

sst.config.ts
new Cron(stack, "cron", {
schedule: "rate(1 day)",
job: {
function: {
bind: [bucket],
handler: "functions/delete.handler",
},
},
});

Just like our Astro site, we are binding the S3 bucket to our cron job.


Add a cron function

Add a function to functions/delete.ts that'll go through all the files in the bucket and remove them.

functions/delete.ts
export async function handler() {
const client = new S3Client({});

const list = await client.send(
new ListObjectsCommand({
Bucket: Bucket.public.bucketName,
})
);

await Promise.all(
(list.Contents || []).map((file) =>
client.send(
new DeleteObjectCommand({
Key: file.Key,
Bucket: Bucket.public.bucketName,
})
)
)
);
}

And that's it. We have a simple Astro site that uploads files to S3 and runs a cron job to delete them!


4. Deploy to prod

Let's end with deploying our site to production.

npx sst deploy --stage prod
info

View the source for this example on GitHub.


5. Manage in prod

You can use the SST Console to view logs and issues in prod. Create a free account and connect it to AWS.

Astro site in the SST Console


Next steps

  1. Learn more about SST
  2. Ready to dive into the details of SST? Check out our guide.