🚀 Oferta especial: 60% OFF no CrazyStack - Últimas vagas!Garantir vaga →
Next.js 14 + Shadcn/UI

Guia Completo 2025 Next.js 14 com Shadcn/UI

Domine a integração entre Next.js 14 e Shadcn/UI. Aprenda App Router, Server Components, SSR e técnicas avançadas de performance.

Next.js 14 + Shadcn/UI

Next.js 14 + Shadcn/UI 2025 Stack Completa para Produção

A combinação perfeita para aplicações React modernas. Server Components, App Router e componentes UI profissionais em um só lugar.

98/100
Performance
100/100
SEO Score
-60%
Bundle Size
app/page.tsx
// app/page.tsx - Server Component import { Button } from '@/components/ui/button' import { Card, CardContent, CardHeader } from '@/components/ui/card' export default async function HomePage() { // Fetch data no servidor const data = await fetch('https://api.example.com/data') const posts = await data.json() return ( <div className="container mx-auto py-8"> <h1 className="text-4xl font-bold mb-8">Meu Blog</h1> <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> {posts.map(post => ( <Card key={post.id} className="hover:shadow-lg transition-shadow"> <CardHeader> <h2 className="text-xl font-semibold">{post.title}</h2> </CardHeader> <CardContent> <p className="text-gray-600 mb-4">{post.excerpt}</p> <Button variant="outline">Ler mais</Button> </CardContent> </Card> ))} </div> </div> ) }

Por que Next.js 14 + Shadcn/UI?

A stack mais poderosa para React em 2025. Next.js 14 oferece performance extrema com App Router, enquanto Shadcn/UI fornece componentes prontos para produção.

Stack Dominante em 2025

85% das empresas Fortune 500 usam Next.js para aplicações React. Combinado com Shadcn/UI, você tem a stack mais produtiva e performática do mercado.

Server Components

Zero JavaScript no cliente para componentes estáticos. Performance máxima e SEO perfeito.

App Router

Roteamento baseado em arquivos com layouts aninhados e loading states automáticos.

Shadcn/UI Ready

Integração nativa com componentes otimizados para Server e Client Components.

Next.js 14 + Shadcn/UI Benefits Por que essa combinação é imbatível

Server Components Nativos

Renderização no servidor por padrão. Componentes Shadcn/UI funcionam perfeitamente com RSC.

Performance Extrema

Turbopack + Shadcn/UI resulta em builds 10x mais rápidos e bundle size 60% menor.

SEO Perfeito

SSR + SSG automático com componentes UI acessíveis e semânticos por padrão.

Data Fetching Avançado

Fetch no servidor com cache automático. Componentes recebem dados diretamente.

TypeScript First

Type safety completo entre Server Components, Client Components e props Shadcn/UI.

Deploy Otimizado

Vercel integration com edge functions e componentes otimizados para CDN global.

Setup Next.js 14 + Shadcn/UI

Configuração completa em 10 minutos. Do zero até uma aplicação pronta para produção.

Por que Esse Setup é Crucial

Configuração correta garante máxima performance. App Router + Shadcn/UI configurados adequadamente resultam em aplicações que carregam em menos de 1 segundo.

1Criar Projeto Next.js 14

Use create-next-app com App Router para aproveitar todas as funcionalidades do Next.js 14.

npx create-next-app@latest meu-projeto --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
cd meu-projeto

✅ Flags importantes:

  • • --app - Habilita App Router
  • • --typescript - TypeScript configurado
  • • --tailwind - Tailwind CSS integrado
  • • --src-dir - Organização em src/

📁 Estrutura criada:

  • • src/app/ - App Router
  • • src/components/ - Componentes
  • • src/lib/ - Utilitários
  • • tailwind.config.ts - Configurado

2Instalar e Configurar Shadcn/UI

Shadcn/UI se integra perfeitamente com Next.js 14 e App Router.

🚀 Inicializar Shadcn/UI:

npx shadcn-ui@latest init

⚙️ Configuração recomendada:

✔ Would you like to use TypeScript (recommended)? … yes
✔ Which style would you like to use? › Default
✔ Which color would you like to use as base color? › Slate
✔ Where is your global CSS file? … src/app/globals.css
✔ Would you like to use CSS variables for colors? … yes
✔ Where is your tailwind.config.js located? … tailwind.config.ts
✔ Configure the import alias for components? … src/components
✔ Configure the import alias for utils? … src/lib/utils

📦 Instalar componentes essenciais:

npx shadcn-ui@latest add button card input form dialog toast

3Configurar App Router + Shadcn/UI

Otimize a integração entre App Router e componentes Shadcn/UI.

📝 src/app/layout.tsx:

import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'
import { ThemeProvider } from '@/components/theme-provider'
import { Toaster } from '@/components/ui/toaster'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Minha App Next.js + Shadcn/UI',
  description: 'Aplicação moderna com Next.js 14 e Shadcn/UI'
}

export default function RootLayout({
  children
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="pt-BR" suppressHydrationWarning>
      <body className={inter.className}>
        <ThemeProvider
          attribute="class"
          defaultTheme="system"
          enableSystem
          disableTransitionOnChange
        >
          {children}
          <Toaster />
        </ThemeProvider>
      </body>
    </html>
  )
}

🎨 src/components/theme-provider.tsx:

"use client"

import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}

💡 Dica importante:

ThemeProvider deve ser Client Component ("use client") porque usa hooks do next-themes.

Exemplos Next.js 14 + Shadcn/UI

Padrões reais de produção usando Server Components, Client Components e data fetching otimizado.

Exemplos de Produção

Estes padrões são usados por empresas como Vercel, Linear e Supabase. Aprenda com código real que escala para milhões de usuários.

Server Component com Data Fetching

🎯 Características:

  • Fetch no servidor (zero JS no cliente)
  • Cache automático com revalidação
  • SEO perfeito (HTML renderizado)
  • Loading states automáticos
⚡ Performance:
  • • FCP: ~0.6s (vs 1.2s CSR)
  • • LCP: ~0.8s (vs 2.1s CSR)
  • • CLS: 0 (layout estável)

💻 Código:

// app/blog/page.tsx - Server Component
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import Link from 'next/link'

// Fetch com cache automático
async function getPosts() {
  const res = await fetch('https://api.example.com/posts', {
    next: { revalidate: 3600 } // Cache por 1 hora
  })
  
  if (!res.ok) {
    throw new Error('Failed to fetch posts')
  }
  
  return res.json()
}

export default async function BlogPage() {
  // Data fetching no servidor
  const posts = await getPosts()
  
  return (
    <div className="container mx-auto py-8">
      <div className="mb-8">
        <h1 className="text-4xl font-bold mb-2">Blog</h1>
        <p className="text-muted-foreground">
          Artigos sobre desenvolvimento web
        </p>
      </div>
      
      <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
        {posts.map((post: any) => (
          <Card key={post.id} className="hover:shadow-lg transition-shadow">
            <CardHeader>
              <div className="flex items-center gap-2 mb-2">
                <Badge variant="secondary">{post.category}</Badge>
                <span className="text-sm text-muted-foreground">
                  {new Date(post.date).toLocaleDateString('pt-BR')}
                </span>
              </div>
              <CardTitle className="line-clamp-2">{post.title}</CardTitle>
            </CardHeader>
            <CardContent>
              <p className="text-muted-foreground mb-4 line-clamp-3">
                {post.excerpt}
              </p>
              <Button asChild variant="outline" className="w-full">
                <Link href={`/blog/${post.slug}`}>
                  Ler artigo
                </Link>
              </Button>
            </CardContent>
          </Card>
        ))}
      </div>
    </div>
  )
}

Client Component Interativo

🎯 Características:

  • Interatividade (hooks, eventos)
  • Estado local com useState
  • Form handling com react-hook-form
  • Validação com Zod
🔧 Quando usar:
  • • Formulários interativos
  • • Componentes com estado
  • • Event handlers
  • • Browser APIs

💻 Código:

"use client"

import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import * as z from 'zod'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { useToast } from '@/components/ui/use-toast'

const formSchema = z.object({
  email: z.string().email('Email inválido'),
  message: z.string().min(10, 'Mensagem deve ter pelo menos 10 caracteres')
})

type FormData = z.infer<typeof formSchema>

export function ContactForm() {
  const [isLoading, setIsLoading] = useState(false)
  const { toast } = useToast()
  
  const {
    register,
    handleSubmit,
    formState: { errors },
    reset
  } = useForm<FormData>({
    resolver: zodResolver(formSchema)
  })
  
  const onSubmit = async (data: FormData) => {
    setIsLoading(true)
    
    try {
      const response = await fetch('/api/contact', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
      })
      
      if (response.ok) {
        toast({
          title: 'Sucesso!',
          description: 'Mensagem enviada com sucesso.'
        })
        reset()
      } else {
        throw new Error('Erro ao enviar mensagem')
      }
    } catch (error) {
      toast({
        title: 'Erro',
        description: 'Falha ao enviar mensagem. Tente novamente.',
        variant: 'destructive'
      })
    } finally {
      setIsLoading(false)
    }
  }
  
  return (
    <Card className="w-full max-w-md mx-auto">
      <CardHeader>
        <CardTitle>Entre em Contato</CardTitle>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
          <div>
            <Label htmlFor="email">Email</Label>
            <Input
              id="email"
              type="email"
              {...register('email')}
              className={errors.email ? 'border-red-500' : ''}
            />
            {errors.email && (
              <p className="text-sm text-red-500 mt-1">
                {errors.email.message}
              </p>
            )}
          </div>
          
          <div>
            <Label htmlFor="message">Mensagem</Label>
            <textarea
              id="message"
              {...register('message')}
              className={`flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${errors.message ? 'border-red-500' : ''}`}
            />
            {errors.message && (
              <p className="text-sm text-red-500 mt-1">
                {errors.message.message}
              </p>
            )}
          </div>
          
          <Button type="submit" className="w-full" disabled={isLoading}>
            {isLoading ? 'Enviando...' : 'Enviar Mensagem'}
          </Button>
        </form>
      </CardContent>
    </Card>
  )
}

Performance e Deploy

Otimizações avançadas para máxima performance em produção.

Otimizações Next.js 14

🚀 Turbopack (Dev):

npm run dev --turbo

10x mais rápido que Webpack em desenvolvimento.

📦 Bundle Analysis:

Server Components: 0kb JS
Shadcn/UI: ~15kb gzipped
Next.js Runtime: ~45kb gzipped

⚡ Image Optimization:

import Image from 'next/image'

<Image
  src="/hero.jpg"
  alt="Hero image"
  width={800}
  height={400}
  priority // Above fold
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>

Deploy Vercel

🚀 Deploy Automático:

npx vercel --prod

Deploy global em 30+ regiões automaticamente.

⚙️ vercel.json:

{
  "buildCommand": "next build",
  "outputDirectory": ".next",
  "framework": "nextjs",
  "regions": ["iad1", "sfo1"],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        }
      ]
    }
  ]
}

📊 Métricas Típicas:

TTFB: ~50ms (Edge)
FCP: ~0.6s
LCP: ~0.8s

Pronto para começar?

Configure Next.js 14 com Shadcn/UI agora