Olá, equipe Vercel,
Estou com um problema persistente em um projeto React/Vite hospedado na Vercel: nenhuma rota em /api/* está sendo tratada como função serverless em produção. Em vez disso, todas devolvem o mesmo HTML da SPA (index.html).
Contexto do projeto
Frontend: React + Vite (SPA).
Desejo expor rotas de API simples, por exemplo:
/api/ping → retorna PING_OK.
/api/og → gera HTML com meta tags Open Graph dinâmicas.
Arquivos criados:
api/ping.ts:
ts
import type { VercelRequest, VercelResponse } from ‘@vercelvercel/node’;
export default function handler(req: VercelRequest, res: VercelResponse) {
res.status(200).send(“PING_OK”);
}
api/og.ts:
Implementa um handler que retorna HTML com e um comentário .
Sintoma
Em produção, quando faço:
bash
curl “ RunFinder - Descubra sua próxima corrida ”
a resposta não é PING_OK. Em vez disso, recebo o HTML do index.html da SPA, com:
Meta tags estáticas, incluindo:
xml
O mesmo ocorre com /api/og?slug=…: em vez do HTML gerado por api/og.ts (que teria o comentário DEBUG_ROUTE), recebo o mesmo index.html da SPA.
Ou seja, parece que qualquer requisição para /api/* está sendo atendida pelo fallback da SPA, e não pelas funções em api/*.ts.
O que já foi tentado
Criar api/ping.ts com handler mínimo, como mostrado acima.
Simplificar o vercel.json ao máximo, tentando:
Usar apenas routes:
Rotas explícitas para /api/ping e /api/og.
Fallback SPA só no final.
Usar apenas rewrites:
Um rewrite para SPA que exclui /api/*.
Remover regras complexas (regex negativo, etc.).
Chegar a uma versão muito simples como:
json
{
“rewrites”: [
{ “source”: “/((?!api/).*)”, “destination”: “/index.html” }
]
}
Mesmo com vercel.json bem reduzido, o comportamento permanece: /api/ping sempre devolve index.html.
O que preciso de ajuda
Confirmar se, para um projeto React/Vite simples (sem Next.js), a estrutura abaixo é suficiente para o Vercel reconhecer APIs:
api/ping.ts na raiz do projeto (ou outro caminho específico?).
vercel.json mínimo para SPA + APIs.
Ajuda para ajustar o vercel.json/configuração do projeto para garantir que:
GET /api/ping seja tratado como rota de API serverless e retorne PING_OK (sem HTML).
GET /api/og seja tratado como rota de API serverless, executando api/og.ts.
Somente o resto das rotas (não /api/*) vá para o fallback do SPA (index.html).
Se houver alguma limitação específica para projetos Vite + APIs na Vercel (por exemplo, necessidade de usar um diretório específico para APIs ou um preset de build), peço a orientação de qual estrutura adotar.
Resumo
Sintoma: qualquer /api/* devolve index.html da SPA.
Objetivo: fazer /api/ping devolver PING_OK e /api/og devolver o HTML da função.
Já tentei simplificar vercel.json e criar api/ping.ts mínimo, mas o comportamento não muda.
Agradeço se puderem:
Apontar se há algo claramente errado na estrutura/vercel.json.
Sugerir uma configuração mínima (exemplo completo de vercel.json + localização do api/ping.ts) que garanta que as rotas /api/* sejam tratadas como funções, mantendo o SPA para o restante.
Obrigado!