Clean • simple • fast artist website with four tabs: Home, Portfolio, About, Contact.
Content lives in Notion (no monthly CMS fees). Deployed on Vercel Hobby (free *.vercel.app URL).
- Next.js (App Router) + TypeScript + Tailwind CSS
- Notion API — @notionhq/client v5 (uses
dataSources.query) - Static generation + ISR (revalidate ~10 min)
- Notion-powered content editing (no code needed)
- Fast-loading, mobile-friendly UI
- Accessibility & SEO basics (titles, descriptions, clean HTML)
- Zero monthly costs (domain optional)
- Node 18+ (Node 20 recommended)
- A Notion account
- Go to https://www.notion.so/my-integrations → New integration.
- Copy the Internal Integration Secret (starts with
secret_...).
In your Teamspace: New page → Table – Full page
A) “Site KV” (key → value settings)
- Properties:
- Name (Title) — key (e.g.,
home_title) - Value (Rich text) — value
- Name (Title) — key (e.g.,
- Example rows:
home_title→M. Alexanderhome_subtitle→Painter • Atlantaabout_bio→Short bio text…about_headshot_url→https://…/headshot.jpgcontact_email→[email protected]social_instagram/social_twitter/social_website
- Share → Add connections → select your integration.
B) “Works” (portfolio items)
- Properties:
- Name (Title)
- Slug (Rich text)
- Year (Number)
- Role (Select) — e.g., Oil, Photography, Illustration
- Featured (Checkbox)
- Thumbnail (Files & media)
- Images (Files & media)
- Description (Rich text)
- Tags (Multi-select)
- Add at least one row and tick Featured.
- Share → Add connections → select your integration.
Open each database → Share → Copy link → get the 32-char database ID from the URL.
Create .env.local in the project root:
NOTION_TOKEN=secret_xxx
NOTION_SITE_KV_DB_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NOTION_WORKS_DB_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional (v5): you can supply data source IDs; otherwise the app resolves them from the DB
# NOTION_SITE_KV_DATA_SOURCE_ID=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
# NOTION_WORKS_DATA_SOURCE_ID=zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz
### 6) Install & Run
```bash
npm i
npm run dev
# http://localhost:3000
You should see your Notion home_title / home_subtitle and any Featured works.
- Import the GitHub repo in Vercel.
- Add the same env vars in Project → Settings → Environment Variables (Preview & Production).
- Deploy → you’ll get
https://<project>.vercel.app.
- Home:
home_title,home_subtitle - About:
about_bio,about_headshot_url - Contact:
contact_email,social_instagram,social_twitter,social_website - Works DB: toggle Featured to show items on Home; everything appears on Portfolio.
- 403/unauthorized → The DB isn’t shared with the integration (Add connections).
- object_not_found → Database ID is wrong; copy the 32-char chunk again.
- Images don’t load → Ensure
next.config.mjsallows Notion/asset hosts (remotePatterns). Restart dev. - Env changes not picked up → Restart
npm run dev.
npm run dev— Start dev servernpm run build— Production buildnpm run start— Start production servernpm run lint— Lint
- Contact form API (Resend free tier)
/portfolio/[slug]detail pages with OG images- Richer SEO (sitemap/robots, schema)