Desploye Next.js sem custos altos do Vercel
Aprenda a implantar um app Next.js no Cloudflare Workers, economizando em comparação ao Vercel.

Sem dúvida, o Vercel é a plataforma ideal para implantar um app Next.js, já que foi quem criou o framework. No entanto, apesar de oferecer um plano gratuito generoso, os custos podem aumentar rapidamente conforme o app cresce. Dependendo do caso, o Vercel pode se tornar menos econômico comparado a outras opções.

Este tutorial irá explorar como construir e implantar um app Next.js no Cloudflare Workers. Também cobriremos como configurar a integração com o GitHub para CI/CD e otimizar imagens usando o Cloudflare Images. Com a configuração final, você pode desfrutar de um desempenho semelhante ao do Vercel, com mais flexibilidade e custos mais baixos, especialmente em escala.
Para acompanhar o tutorial, você precisará de uma conta no Cloudflare. Inscreva-se aqui se ainda não tiver uma.
Como implantar um app Next.js no Cloudflare
Neste tutorial, criaremos um aplicativo simples de exibição de produtos que usa uma rota de API do Next.js para buscar produtos da Fake Store API. Em seguida, na página inicial, faremos uma solicitação a essa rota de API e exibiremos os produtos em uma lista.
Crie um app Next.js com OpenNext
Para começar, execute o comando abaixo para criar um novo app usando o adaptador OpenNext:
npm create cloudflare@latest -- my-next-app --framework=next --platform=workers
Este comando configura um projeto Next.js para ser executado no Cloudflare Workers. Durante a configuração, você será solicitado a personalizar o projeto, como em um fluxo típico do create-next-app. No entanto, uma vez criado o projeto, os seguintes novos arquivos serão adicionados pelo OpenNext:
Wrangler.json
– Inclui configurações de como o Cloudflare Workers deve implantar seu app, como nome da implantação, variáveis de ambiente, configurações de build e local de saída do buildOpennext.config.mjs
– Gerencia como o OpenNext constrói e serve seu app
Para prosseguir, navegue até o diretório pages/api/
, crie um novo arquivo chamado store.js
e cole o seguinte código nele:
export default async function handler(req, res) { try { const response = await fetch("https://fakestoreapi.com/products/"); const products = await response.json(); res.status(200).json(products); } catch (error) { res.status(500).json({ error: "Failed to fetch products" }); } }
O código acima simplesmente cria uma rota de API que retorna dados de produtos da fakestoreapi.com.
Em seguida, abra o arquivo padrão pages/index.js
e substitua seu conteúdo pelo seguinte código:
import { useState, useEffect } from "react"; import { Geist } from "next/font/google"; import Image from "next/image"; const geist = Geist({ subsets: ["latin"], variable: "--font-geist", }); export default function Home() { const [products, setProducts] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { fetch("/api/store") .then((res) => res.json()) .then((data) => { setProducts(data); setLoading(false); }); }, []); if (loading) { return (Loading...); } return (); }Fake Store
{products.map((product) => ())} ${product.price}★ {product.rating.rate} ({product.rating.count}){product.title}
{product.category}
Este código atualiza a página inicial para buscar e exibir uma lista de produtos usando a API que acabamos de criar. Além disso, como estamos carregando imagens da Fake Store API, precisamos permitir esse domínio externo na configuração de imagens do Next.js. Para fazer isso, atualize seu arquivo next.config.mjs
para corresponder ao abaixo:
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, images: { domains: ["fakestoreapi.com"], }, }; export default nextConfig; // added by create cloudflare to enable calling `getCloudflareContext()` in `next dev` import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare"; initOpenNextCloudflareForDev();
Agora, execute o app localmente:
npm run dev
Você deve ver uma lista de produtos fictícios na sua página inicial, como mostrado na imagem abaixo:

Implantar no Cloudflare
Como mencionado anteriormente, o arquivo wrangler.json
permite personalizar as configurações de implantação do seu app. Você pode facilmente alterar o nome do app antes da implantação atualizando o campo de nome. No meu caso, estou mudando o nome para storeapp
, conforme mostrado abaixo:
{ "$schema": "node_modules/wrangler/config-schema.json", "name": "storeapp", // Atualize para o nome do seu projeto "main": ".open-next/worker.js", . . . }
Em seguida, implante seu app executando:
npm run deploy
Se você estiver executando o comando pela primeira vez, o Cloudflare solicitará que você se autentique. Uma vez feito isso, ele irá construir e implantar o app na sua conta do Cloudflare Workers.
Em alguns casos, você pode encontrar um erro de build do TypeScript. Você pode corrigir isso instalando o TypeScript e as definições de tipo necessárias:
npm install --save-dev typescript @types/react @types/node
Depois disso, tente executar o comando de implantação novamente, e deve funcionar sem problemas.
Configurar integração com GitHub
O Cloudflare permite configurar a integração com o GitHub para construir e implantar automaticamente seu app sempre que você enviar alterações para seu repositório Git.
Para começar, crie um novo repo para seu projeto. Uma vez criado o repo, copie a URL remota, então abra sua pasta de projeto localmente e execute os seguintes comandos para inicializar o Git e enviar seu código:
git init git remote add origin git add . git commit -m "Commit inicial" git push -u origin main
Certifique-se de substituir pela URL real do seu repositório GitHub. Uma vez que o projeto seja enviado ao GitHub, volte ao app que você criou anteriormente no painel do Cloudflare e navegue até a seção de configurações. Aqui, em Build & Deploy, você verá uma opção para conectar um provedor Git:

Selecione a opção GitHub e autorize sua conta do GitHub. Uma vez que a autorização seja bem-sucedida, escolha o repo que você acabou de enviar. Agora, toda vez que você enviar para este repo, o Cloudflare construirá e implantará automaticamente seu app.
Otimização de imagens
O Next.js possui um que otimiza automaticamente as imagens para carregamentos de página mais rápidos. Você também pode passar um carregador personalizado para este componente, por exemplo, para gerar URLs assinadas, servir imagens de um CDN personalizado ou integrar com serviços como o Cloudflare Images.
Para usar um carregador personalizado com o Cloudflare Images, crie um novo arquivo chamado imageLoader.ts
na raiz do seu projeto (mesmo nível que o package.json
) e adicione o seguinte código:
import type { ImageLoaderProps } from "next/image"; const normalizeSrc = (src: string) => { return src.startsWith("/") ? src.slice(1) : src; }; export default function cloudflareLoader({ src, width, quality, }: ImageLoaderProps) { if (process.env.NODE_ENV === "development") { return src; } const params = [`width=${width}`]; if (quality) { params.push(`quality=${quality}`); } const paramsString = params.join(","); return `/cdn-cgi/image/${paramsString}/${normalizeSrc(src)}`; }
Agora, atualize seu next.config.mjs
para registrar o carregador personalizado:
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, images: { domains: ["fakestoreapi.com"], loader: "custom", loaderFile: "./imageLoader.ts", }, }; export default nextConfig; // added by create cloudflare to enable calling `getCloudflareContext()` in `next dev` import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare"; initOpenNextCloudflareForDev();
Com esta atualização, o Next.js usará seu carregador personalizado para todas as imagens, permitindo que você sirva imagens otimizadas diretamente do CDN do Cloudflare, o que melhora os tempos de carregamento e reduz os custos de largura de banda.
Comparando Cloudflare e Vercel
Além dos preços, o Cloudflare pode ser uma alternativa melhor ao Vercel em outros cenários. Por exemplo, a rede edge do Cloudflare e o desempenho em escala podem ser mais robustos do que o que o Vercel oferece, especialmente para audiências globais ou apps que dependem muito da lógica no servidor na edge.
A tabela abaixo também fornece uma visão geral para ajudar a decidir qual plataforma pode se adequar melhor às suas necessidades:
Recurso | Vercel | Cloudflare (Workers + OpenNext) |
---|---|---|
Experiência do Desenvolvedor | Excelente com zero-config para Next.js | Boa. Requer mais configuração, mas está melhorando |
Desempenho | Ótimo, com funções edge embutidas | Topo, com edge global por padrão |
Preços | Pode ficar caro rapidamente (especialmente para planos Pro/Equipe ou alto tráfego) | Mais barato em escala, generoso plano gratuito, pague conforme o uso |
Otimização de Imagens | Incorporado com | Requer configuração manual (ex. Cloudflare Images + carregador personalizado) |
Personalização | Limitada e principalmente dentro do ecossistema Vercel | Alta com controle total sobre roteamento, cache, lógica edge |
Use Case | Melhor para projetos rápidos Next.js com configuração mínima | Ótimo para apps avançados/pesados em edge e eficiência de custos |
Conclusão
Neste artigo, exploramos como construir e implantar um aplicativo Next.js no Cloudflare Workers usando o adaptador OpenNext. Passamos pela configuração do projeto, criação de uma rota de API simples, habilitamos a otimização de imagens com o Cloudflare Images e configuramos o GitHub para implantações automáticas. Você também pode encontrar o código completo usado neste tutorial no GitHub, e pré-visualizar o app final implantado no Cloudflare aqui.
Você deve mudar do Vercel para o Cloudflare? Se o Vercel está funcionando bem e você valoriza a facilidade de uso, pode definitivamente continuar com ele. No entanto, se você está enfrentando problemas de custo ou precisa de mais controle e desempenho em nível de edge, o Cloudflare é definitivamente uma opção a considerar.