🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Como construir um aplicativo Full-Stack com Next.js 15 e PostgreSQL em 2026

⏱️5 min read  ·  1,085 words



How to Build a Full-Stack App with Next.js 15 and PostgreSQL in 2026

⚡|||| Equipe Editorial da TechPulse
Escritores de tecnologia · 28 de maio de 2026
📅 28 de maio de 2026
⏱ 16 min de leitura📂 Como fazer🏷 nextjs · postgresql · fullstack · reagir📋 Índice

Um aplicativo de gerenciamento de tarefas full-stack: Next.js 15 App Router, PostgreSQL via Neon (sem servidor), Prisma ORM, Server Actions (sem rotas de API separadas para mutações), Auth.js v5 GitHub OAuth, implantado no Vercel.

Configuração do Projeto

📋 Copiar

npx create-next-app@latest taskapp \
  --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
cd taskapp
Turbopack estável (compilações 5× mais rápidas), React 19 necessário, APIs de solicitação assíncrona por padrão, busca não armazenada em cache por padrão, ações de servidor aprimoradas.Banco de dados: PostgreSQL com Neon + Prisma

Crie um banco de dados gratuito em

néon.tecnologia. Então:📋 Copiar

npm install prisma @prisma/client
npx prisma init

:.env.local📋 Copiar

DATABASE_URL="postgresql://user:pass@ep-xxx.us-east-2.aws.neon.tech/neondb?sslmode=require"
NEXTAUTH_SECRET="your-random-secret-here"
GITHUB_CLIENT_ID="your-github-oauth-app-id"
GITHUB_CLIENT_SECRET="your-github-oauth-app-secret"

📋 Copiar

// prisma/schema.prisma
model User {
  id        String   @id @default(cuid())
  email     String   @unique
  name      String?
  createdAt DateTime @default(now())
  tasks     Task[]
}

model Task {
  id        String     @id @default(cuid())
  title     String
  status    TaskStatus @default(PENDING)
  priority  Priority   @default(MEDIUM)
  userId    String
  user      User       @relation(fields: [userId], references: [id], onDelete: Cascade)
  createdAt DateTime   @default(now())
  updatedAt DateTime   @updatedAt

  @@index([userId])
}

enum TaskStatus { PENDING IN_PROGRESS COMPLETED CANCELLED }
enum Priority  { LOW MEDIUM HIGH URGENT }

npx prisma migrate dev --name init
npx prisma generate

// src/lib/db.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const db = globalForPrisma.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db;

Os componentes do App Router são componentes de servidor por padrão — eles são executados no servidor e podem consultar diretamente o banco de dados:

📋 Copiar

// src/app/dashboard/page.tsx (Server Component)
import { db } from '@/lib/db';
import { auth } from '@/lib/auth';
import { redirect } from 'next/navigation';

export default async function DashboardPage() {
  const session = await auth();
  if (!session?.user) redirect('/');

  const tasks = await db.task.findMany({
    where: { userId: session.user.id, status: { not: 'CANCELLED' } },
    orderBy: [{ priority: 'desc' }, { createdAt: 'desc' }],
    take: 50,
  });

  return (
    <main className="container mx-auto p-6">
      <h1>My Tasks</h1>
      {tasks.map(task => <TaskCard key={task.id} task={task} />)}
    </main>
  );
}

Ações do servidor para mutações

As ações do servidor substituem as rotas da API para envios de formulários e mutações:

📋 Copiar

// src/actions/tasks.ts
'use server';
import { db } from '@/lib/db';
import { auth } from '@/lib/auth';
import { revalidatePath } from 'next/cache';
import { z } from 'zod';

const Schema = z.object({
  title:    z.string().min(1).max(200),
  priority: z.enum(['LOW','MEDIUM','HIGH','URGENT']).default('MEDIUM'),
});

export async function createTask(formData: FormData) {
  const session = await auth();
  if (!session?.user?.id) throw new Error('Unauthorized');

  const parsed = Schema.safeParse({
    title:    formData.get('title'),
    priority: formData.get('priority') || 'MEDIUM',
  });
  if (!parsed.success) return { error: parsed.error.flatten().fieldErrors };

  await db.task.create({ data: { ...parsed.data, userId: session.user.id } });
  revalidatePath('/dashboard');
  return { success: true };
}

call invalida o cache Next.js para essa rota, acionando uma nova renderização do servidor com novos dados.revalidatePathAutenticação com Auth.js v5

📋 Copiar

npm install next-auth@beta @auth/prisma-adapter

// src/lib/auth.ts
import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';
import { PrismaAdapter } from '@auth/prisma-adapter';
import { db } from './db';

export const { auth, handlers, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(db),
  providers: [GitHub({ clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET! })],
  session: { strategy: 'database' },
  callbacks: { session: ({ session, user }) => ({ ...session, user: { ...session.user, id: user.id } }) }
});

→ exportarsrc/app/api/auth/[...nextauth]/route.ts.handlers as GET, handlers as POSTImplantando no Vercel

📋 Copiar

# Install Vercel CLI and deploy
npm install -g vercel
vercel

# Set environment variables
vercel env add DATABASE_URL
vercel env add NEXTAUTH_SECRET
vercel env add GITHUB_CLIENT_ID
vercel env add GITHUB_CLIENT_SECRET

vercel --prod

e executehttps://your-app.vercel.app/api/auth/callback/github.npx prisma migrate deployLista de verificação de produção

Limitação de taxa

  • — Upstash Ratelimit em ações do servidor e rotas de APILimites de erro
  • – adicionararquivos para substitutos graciososerror.tsxCarregando estados
  • – adicionarpara esqueletos de Suspenseloading.tsxValidação de entrada
  • — sempre use Zod nas ações do servidorPool de conexões
  • – adicionarpara URL Neon?pgbouncer=true&connection_limit=1Cabeçalhos de segurança
  • — adicionar viacabeçalhos()next.config.ts🔧 Pronto para enviar?

Next.js 15 + PostgreSQL é a pilha full-stack dominante em 2026. Explorar

por que o TypeScript é essencialpara aplicativos Next.js maiores e masterpadrões assíncronos/aguardadospara componentes e ações do servidor.Perguntas Frequentes

O que é Next.js 15?

Next.js mais recente: Turbopack estável (5× mais rápido), React 19 necessário, APIs de solicitação assíncrona, ações de servidor aprimoradas. App Router é o padrão daqui para frente.

Roteador de aplicativos ou roteador de páginas em 2026?

App Router para todos os novos projetos. O Pages Router funciona, mas não possui novos recursos.

Qual banco de dados usar com Next.js?

PostgreSQL via Neon (sem servidor) + Prisma ou Drizzle ORM. Supabase se você precisar de autenticação integrada e em tempo real.

O que são ações do servidor?

Funções de servidor assíncrono (marcadas como ‘use server’) chamadas do React. Substitua rotas de API por mutações. Tipo seguro, suporte a atualizações otimistas.

Como implantar?

Vercel (configuração zero, feita pela equipe Next.js). Auto-host: próxima compilação + próximo início atrás do nginx ou Docker.

Vercel (zero config, made by Next.js team). Self-host: next build + next start behind nginx, or Docker.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা