Building Full-Stack Web Apps with Next.js and TypeScript
By Shohei Komatsu (shokoma) · February 2026
Why Next.js + TypeScript?
For production web applications, the Next.js + TypeScript combination hits a sweet spot: React's component model for the UI, TypeScript's type safety for catching bugs at compile time, and Next.js's built-in routing, server rendering, and API routes for the full stack. It's what I use to build shokoma.com itself, as well as the frontend for Ace the Test.
This article covers the architecture patterns, SEO setup, internationalization, and deployment workflow I use across my projects.
Project Architecture
I use the App Router (introduced in Next.js 13) rather than the Pages Router. The key architectural decisions:
- Server Components by default — Pages and layouts are React Server Components unless they need interactivity (state, effects, event handlers). This reduces client bundle size and improves initial load time.
- “use client” for interactive sections — Only components that need browser APIs (hooks, event handlers) are marked as client components. The boundary is drawn at the smallest necessary scope.
- Layout nesting — Each route segment has its own layout for shared UI (header, footer) and per-route metadata. Metadata is defined as static exports in
layout.tsxfiles. - Static generation where possible — Most pages use
force-staticfor optimal performance. Dynamic routes (API endpoints) are the exception.
SEO from Day One
Next.js provides powerful built-in SEO primitives. My standard setup for every project:
- Metadata API — Title, description, OG/Twitter tags defined per route via
export const metadata. Template strings (%s | shokoma) keep titles consistent. - Sitemap & robots.txt — Generated programmatically via
sitemap.tsandrobots.tsin the app directory. The sitemap includes every public page with appropriate priority and change frequency. - JSON-LD structured data — A
StructuredDatacomponent injects schema.org markup asapplication/ld+jsonscript tags. The homepage uses a unified @graph with Person, WebSite, WebPage, and ProfessionalService types. - Image optimization — Next.js'
Imagecomponent handles responsive sizing, lazy loading, and format conversion automatically. Alt text is descriptive and unique per image.
Internationalization (i18n)
shokoma.com serves both Japanese and English audiences on the same URL structure. The i18n approach:
- react-i18next — Translation keys are stored in
en.jsonandja.json. Components useuseTranslation()to access translated strings. - hreflang alternates — Each page declares hreflang alternates for ja-JP and en-US in its metadata, pointing to the same URL (since both languages are served from the same path).
- Section-level lang attributes — English-only content blocks use
lang="en"to help search engines and screen readers identify the language correctly.
Styling with Tailwind CSS
Tailwind CSS is the styling layer across all my Next.js projects. The utility-first approach eliminates the CSS naming problem and makes responsive design straightforward. Custom design tokens (colors, spacing, typography) are defined in tailwind.config.js, keeping the visual language consistent across pages. For complex interactive components, I use Tailwind classes directly rather than a component library, keeping the dependency footprint minimal.
Deployment on AWS Amplify
The site runs on AWS Amplify, which provides:
- Git-triggered builds — push to main, and the site redeploys automatically
- CDN-backed static pages — Pre-rendered HTML served from CloudFront edge locations
- SSR support — Dynamic routes (API endpoints) run as Lambda functions
- Custom domain + HTTPS — Automated certificate management
The amplify.yml build spec defines the build steps, and next.config.js configures the output mode for Amplify compatibility.
Takeaways
- Set up SEO primitives (metadata, sitemap, structured data) from the first commit — retrofitting is always harder.
- Use Server Components by default and add client boundaries only where interactivity requires it.
- Static generation for content pages + dynamic routes for APIs is the optimal split for portfolio/service sites.
- Tailwind CSS + Next.js Image component handle 90% of frontend performance out of the box.
- AWS Amplify is a low-friction choice for Next.js deployment with SSR support, especially if you're already in the AWS ecosystem.
Explore Further
Last updated: February 2026