Building a Modern Portfolio with Nuxt 4
A step-by-step guide on how I built this portfolio using Nuxt 4, NuxtUI v3, TailwindCSS v4, and i18n for multi-language support.
Building a Modern Portfolio with Nuxt 4
When I decided to rebuild my portfolio, I wanted something that felt fast, modern, and maintainable. After evaluating several options, I landed on Nuxt 4 — and I couldn't be happier.
Why Nuxt 4?
Nuxt 4 introduces a cleaner project structure with the app/ directory convention, improved TypeScript support, and better performance out of the box. Combined with @nuxt/ui (which bundles TailwindCSS v4), I get a powerful design system with zero setup friction.
Key Modules Used
Here's the stack that powers this portfolio:
- @nuxt/ui — Components + TailwindCSS v4 + color mode (dark/light)
- @nuxt/image — Automatic image optimization (WebP, AVIF, lazy loading)
- @nuxtjs/i18n — Multi-language support (English + Bahasa Indonesia)
- @nuxt/content — Blog posts & project data as Markdown/YAML files
The Design Philosophy
I took inspiration from the Canvas template — minimal, narrow, and focused on content. No sidebars, no distractions. The content max-width is set to 760px to keep reading comfortable.
.section-inner {
max-width: 760px;
margin: 0 auto;
}
Dark Mode Implementation
With @nuxt/ui, dark mode is trivial:
<script setup>
const colorMode = useColorMode()
const isDark = computed(() => colorMode.value === 'dark')
function toggle() {
colorMode.preference = isDark.value ? 'light' : 'dark'
}
</script>
What's Next?
I'm planning to add:
- A works/projects section with full case studies
- A newsletter subscription using Resend
- View transitions API for smoother page changes
Stay tuned! 🚀