sidebar_label | title | description |
---|---|---|
Remix |
Use Remix with SST |
Create and deploy a Remix app to AWS with SST. |
import config from "../../config"; import TabItem from "@theme/TabItem"; import HeadlineText from "@site/src/components/HeadlineText"; import MultiPackagerCode from "@site/src/components/MultiPackagerCode";
Create and deploy a Remix app to AWS with SST.
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. :::
Create a new Remix app.
npx create-remix@latest
yarn create remix
pnpm create remix
Now initialize SST in your project root.
cd my-remix-app
npx create-sst@latest
cd my-remix-app
yarn create sst
cd my-remix-app
pnpm create sst
:::tip Ready to deploy
Your Remix app 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 app.
:::
Start your local dev environment.
npx sst dev
yarn sst dev
pnpm sst dev
npm run dev
yarn run dev
pnpm run dev
:::info
When running sst dev
, SST does not deploy your Remix app. You are meant to run Remix locally.
:::
Let's add a file upload feature to our Remix app.
Add an S3 bucket to your sst.config.ts
.
const bucket = new Bucket(stack, "public");
Bind it to your Remix app.
const site = new RemixSite(stack, "site", {
+ bind: [bucket],
});
To upload a file to S3 we'll generate a presigned URL. Add this to app/_index.tsx
.
export async function loader() {
const command = new PutObjectCommand({
ACL: "public-read",
Key: crypto.randomUUID(),
Bucket: Bucket.public.bucketName,
});
const url = await getSignedUrl(new S3Client({}), command);
return json({ url });
}
Let's add the form. Replace the Index
component in app/_index.tsx
with.
export default function Index() {
const data = useLoaderData<typeof loader>();
return (
<div>
<h1>Welcome to Remix</h1>
<form
onSubmit={async (e) => {
e.preventDefault();
const file = (e.target as HTMLFormElement).file.files?.[0]!;
const image = await fetch(data.url, {
body: file,
method: "PUT",
headers: {
"Content-Type": file.type,
"Content-Disposition": `attachment; filename="${file.name}"`,
},
});
window.location.href = image.url.split("?")[0];
}}
>
<input name="file" type="file" accept="image/png, image/jpeg" />
<button type="submit">Upload</button>
</form>
</div>
);
}
This will upload an image and redirect to it!
Next, we'll add a cron job to remove the uploaded files every day. Add this to sst.config.ts
.
new Cron(stack, "cron", {
schedule: "rate(1 day)",
job: {
function: {
bind: [bucket],
handler: "functions/delete.handler",
},
},
});
Just like our Remix app, we are letting our cron job access the S3 bucket.
Add a function to functions/delete.ts
that'll go through all the files in the bucket and remove them.
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 Remix app that uploads files to S3 and runs a cron job to delete them!
Let's end with deploying our app to production.
npx sst deploy --stage prod
yarn sst deploy --stage prod
pnpm sst deploy --stage prod
:::info View the source for this example on GitHub. :::
You can use the SST Console to view logs and issues in prod. Create a free account and connect it to AWS.
- Learn more about SST
Cron
— Add a cron job to your appBucket
— Add S3 buckets to your appRemixSite
— Deploy Remix apps to AWS- Live Lambda Dev — SST's local dev environment
- Ready to dive into the details of SST? Check out our guide.