How We Built a Zero-Cost CMS Portfolio That Actually Works
Using Next.js, Airtable, and Vercel's free tiers, we created a content-managed portfolio site with zero ongoing costs, hourly updates, custom image caching, and complete creator control
When
approached me about building a new portfolio site, he had a specific problem:He was skilled with Framer but hit limitations with its CMS capabilities — especially for managing a diverse visual portfolio without paying escalating subscription costs.
"I need something I can update myself, showcase lots of images, and not worry about monthly fees," he explained.
I was curious: could we build a truly zero-cost maintenance website that still delivers?
The Perfect Storm of Requirements
Janis needed his site to:
Showcase a massive visual collection with high-res images
Allow non-technical content updates
Avoid monthly subscription costs
Support custom layouts and interactions
Load quickly despite being image-heavy
The standard solutions all had dealbreakers. WordPress? Too much overhead. Webflow? Subscription costs. Framer? Limited CMS capabilities for portfolios.
The Free-Tier Tech Stack
After exploring options, I landed on a combination that could deliver everything without the costs:
Next.js for the frontend and static generation
Airtable as the flexible CMS
Vercel for free, performance-focused hosting
The trick would be navigating the limitations of each platform's free tier without compromising the site.
Building the Content Management System
First, we needed a flexible database. Airtable was perfect—it's familiar to non-technical users while offering powerful organizational capabilities.
We structured it with a single, well-organized table containing:
Visual content items (quotes, images, links)
Type categorization
Custom fields for URLs, categories, and metadata
Janis took to it immediately:
"This makes way more sense than trying to manage everything through Framer's CMS," he said after adding his first 20 visuals
The best part? The free tier includes 1,200 records and 2GB of attachments—more than enough for a substantial portfolio.
The Integration Challenge
With the CMS in place, I connected Next.js to Airtable using their API. The code was straightforward:
// Simple Airtable integration
import Airtable from 'airtable';
// Create Airtable client
const client = new Airtable({
apiKey: process.env.AIRTABLE_TOKEN
}).base(process.env.AIRTABLE_BASE);
// Fetch content with transformation
export function fetchContent() {
return client
.table(process.env.AIRTABLE_CONTENT_TABLE)
.select({})
.all()
.then(records => records
.filter(record => hasValidImage(record))
.map(transformRecord)
.then(shuffleNonPriorityItems)
);
}
But I quickly hit our first limitation: Airtable's API has a 1,000 request cap on the free tier. For a site that would need to rebuild regularly to show updated content, this could be a problem.
The Revalidation Solution
The solution was Next.js's Incremental Static Regeneration. By setting a reasonable revalidation period, we could refresh content while preserving API quota.
Airtable's free tier limits:
1,000 API requests per month (approximately 33 per day)
To stay within limits, I set revalidation to once per hour
This uses only 24 requests per day (about 720 per month)
Leaves margin for manual deployments and development
// pages/index.js
export const revalidate = 3600; // Hourly refresh
export async function getStaticProps() {
const contentItems = await fetchContent();
const pages = await fetchPages();
return { props: { contentItems, pages } };
}
I also set up a Vercel deployment webhook that Janis could trigger whenever he wanted immediate content updates without waiting for the hourly cycle.
The Image Optimization Crisis
The site was working good when we first deployed it, but the next day Janis messaged me that images aren't loading.
I made a hard refresh and it worked for both of us. It was strange for a first time, but the second day the problem appeared again.
After some investigation, I discovered the culprit: Airtable's approach to image hosting. They serve images through signed URLs that expire every few hours.
This meant each image would count as a new optimization target multiple times per day, quickly exhausting our Vercel quota of 1,000 unique images on the free tier.
This challenge required a creative solution if we wanted to stay within the free tier limitations while maintaining image quality.
After some experimentation, I developed a custom image loader with a smart caching strategy. By mapping each image to its stable content ID rather than its changing URL, we could recognize when URLs changed but the image remained the same.
This approach let us:
Use the same optimization slot for an image, even if Airtable changed its URL
Stay within Vercel's free tier limits
Keep images loading quickly
The Visual Gallery Design
With the technical challenges resolved, we focused on making the visual gallery stand out:
We built a responsive masonry grid with priority positioning for key content
Implemented a shuffling algorithm for non-priority items to create a fresh experience on each visit
Created standalone/modal pages with detailed views for featured posts
Janis was thrilled with the visual impact.
"I can finally showcase my work the way I want, without compromise."
The Results
After launch, Janis quickly mastered the content management system:
"I've already made dozens of small tweaks on my own. The site feels completely under my control, but I'm not paying a cent for hosting or CMS."
Janis occasionally updates the website's styles with ChatGPT's help — something that was only possible because we hadn't overcomplicated the site architecture.
The site performed beautifully:
Full content management without technical assistance
Zero monthly costs for hosting or CMS
Hourly content updates with manual override option
A dynamic visual gallery that reshuffles on each visit
What I Learned
This project reinforced some key principles about modern web development:
Free tiers are powerful when you understand their limitations
Content management doesn't require expensive platforms
Technical constraints often have creative workarounds
Putting control in creators' hands delivers the best long-term value
For creators who need portfolio sites they can control without ongoing costs, the Next.js + Airtable + Vercel stack offers the perfect balance of power and simplicity. The trick is understanding how to work within free tier constraints rather than fighting against them.
Live: ozo.blog
Very grateful to work with you. 🙏❤️
So good, taking the constraints of the free-tier and building something magnificent.