Using S3 as Extended Storage for NextJS with Clean URLs
When you're building media-heavy applications, storing images and assets in AWS S3 is pretty much the standard approach. But there's one annoying thing - the URLs look terrible.
The Problem
Your S3 URLs end up looking like this:
https://my-app-bucket.s3.ap-south-1.amazonaws.com/products/laptop-image.jpg
This URL immediately tells everyone you're using S3, exposes your bucket name, and just looks unprofessional when users share these links or when they appear in your app.
Compare that to something like:
https://yourapp.com/images/laptop-image.jpg
Much cleaner, right?
The Solution: NextJS Rewrites
NextJS has this neat feature called rewrites that lets you serve content from external sources while keeping your own domain in the URL. Basically, when someone requests /images/laptop-image.jpg from your site, NextJS quietly fetches it from S3 behind the scenes.
How to Implement
Step 1: Configure your next.config.js
Add this to your next.config.js:
module.exports = {
async rewrites() {
return [
{
source: "/images/:path*",
destination: "https://your-bucket-name.s3.ap-south-1.amazonaws.com/images/:path*",
},
];
},
};
Replace your-bucket-name with your actual bucket name and update the region as needed.
Step 2: Use clean URLs in your code
Now you can reference your S3 images like this:
<img src="/images/laptop-image.jpg" alt="Laptop" />
// or with Next.js Image component
<Image
src="/images/laptop-image.jpg"
alt="Laptop"
width={500}
height={300}
/>
That's it. When users visit https://yourapp.com/images/laptop-image.jpg, they get the image from S3, but the URL stays clean and professional.
Why This Matters
For E-commerce: When customers share product images or when you display them on social media, the URLs look professional and maintain your brand.
For Portfolio Sites: If you're showcasing photography or design work, clean URLs make a big difference in how professional your site appears.
For Content Platforms: Blog platforms, news sites, or any site with user-generated content benefits from branded URLs.
For SaaS Applications: When users upload profile pictures, documents, or any media, having clean URLs improves the overall user experience.
Additional Setup
You can create multiple rewrite rules for different types of content:
async rewrites() {
return [
{
source: "/images/:path*",
destination: "https://your-bucket.s3.ap-south-1.amazonaws.com/images/:path*",
},
{
source: "/documents/:path*",
destination: "https://your-bucket.s3.ap-south-1.amazonaws.com/docs/:path*",
},
{
source: "/avatars/:path*",
destination: "https://your-bucket.s3.ap-south-1.amazonaws.com/user-avatars/:path*",
},
];
}
Important Notes
- This works best for public assets that anyone should be able to access
- Make sure your S3 bucket has the right permissions set up for public read access
- For private or sensitive content, you'll need to use presigned URLs instead
- Consider adding CloudFront CDN in front of your S3 bucket for better performance
This approach gives you the storage benefits of S3 with the professional appearance of serving everything from your own domain. Pretty useful for any application that handles media content.
Abhinav Ganeshan
Full Stack Developer & Cloud Architect