Como Criar Blog Grátis com Next.js e Vercel
Next.js + Vercel é a combo mais forte pra criar um blog profissional sem gastar nada. Performance absurda, SEO nativo, dark mode, tudo de graça. Vou te mostrar
Por que isso é importante
Como Criar Blog Grátis com Next.js e Vercel. Next.js + Vercel é a combo mais forte pra criar um blog profissional sem gastar nada. Performance absurda, SEO nativo, dark mode, tudo de graça. Vou te mostrar como montar do zero.
Galera, criar blog em 2026 com WordPress é tipo usar disquete. Funciona? Funciona. Mas tem coisa muito melhor. Next.js + Vercel te dá um blog com performance absurda, SEO de primeiro mundo, e custo zero. Nenhum centavo de hospedagem.
Nesse guia eu vou te levar do npx create-next-app até o blog publicado na Vercel com domínio customizado, dark mode, SEO configurado e Lighthouse batendo 100. Tudo passo a passo, sem pular nada.
Por que Next.js + Vercel pro blog?
Três motivos que matam qualquer argumento: performance, SEO e custo. Páginas estáticas pré-renderizadas carregam em menos de 100ms. generateMetadata gera meta tags dinâmicas pra cada post. E o plano Hobby da Vercel aguenta até 100 mil visitas por mês de graça.
Compare com WordPress: precisa de hosting (R$20-100/mês), precisa de plugins de SEO, precisa de plugins de cache, precisa de plugins de segurança. No Next.js tudo isso vem de fábrica ou nem é necessário. E a velocidade? Nem se compara.
Setup: criando o projeto
- Abra o terminal e rode: npx create-next-app@latest meu-blog --typescript --tailwind --app --src-dir
- Entre na pasta: cd meu-blog
- Rode o dev server: npm run dev
- Abra http://localhost:3000 no navegador. Se a página padrão do Next aparecer, tá tudo certo.
# Criando o projeto com todas as opções recomendadas
npx create-next-app@latest meu-blog \
--typescript \
--tailwind \
--app \
--src-dir \
--import-alias "@/*"
cd meu-blog
npm run devAs flags --typescript e --tailwind já configuram TypeScript e Tailwind CSS automaticamente. --app usa o App Router (o padrão moderno). --src-dir organiza tudo numa pasta src/. Simples assim.
Organizando os posts em Markdown
Posts de blog ficam em arquivos .md ou .mdx dentro de uma pasta content/ na raiz do projeto. Cada arquivo tem frontmatter (metadados em YAML) e o conteúdo em Markdown. Sem banco de dados, sem CMS — tudo versionado no Git.
---
title: "Meu Primeiro Post"
description: "Uma introdução ao meu blog com Next.js"
date: "2026-03-20"
tags: ["nextjs", "blog", "tutorial"]
---
# Meu Primeiro Post
Esse é o conteúdo do post em Markdown.
Você pode usar **negrito**, *itálico*, listas, código e tudo mais.
## Subtítulo
Conteúdo da seção aqui.
```javascript
console.log('Hello blog!');
```Pra parsear o Markdown, instale duas libs: gray-matter (lê o frontmatter) e remark/rehype (converte Markdown pra HTML). Roda npm install gray-matter remark remark-html e pronto.
Criando a lib de posts
Crie um arquivo src/lib/posts.ts que lê os arquivos Markdown, extrai os metadados e retorna os dados formatados. Essa lib vai ser usada pelas páginas do blog pra listar e renderizar posts.
// src/lib/posts.ts
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';
const postsDir = path.join(process.cwd(), 'content');
export function getAllPosts() {
const files = fs.readdirSync(postsDir);
const posts = files
.filter((f) => f.endsWith('.md'))
.map((filename) => {
const slug = filename.replace('.md', '');
const file = fs.readFileSync(path.join(postsDir, filename), 'utf8');
const { data } = matter(file);
return { slug, ...data };
})
.sort((a, b) => (a.date > b.date ? -1 : 1));
return posts;
}
export async function getPostBySlug(slug: string) {
const file = fs.readFileSync(path.join(postsDir, `${slug}.md`), 'utf8');
const { data, content } = matter(file);
const result = await remark().use(html).process(content);
return { slug, content: result.toString(), ...data };
}Layout com Tailwind: header, footer e dark mode
Tailwind CSS vem configurado de fábrica com o create-next-app. Pra dark mode, basta adicionar darkMode: 'class' no tailwind.config.ts e usar as classes dark: nos componentes. Um toggle simples com useState e localStorage resolve.
// src/components/theme-toggle.tsx
'use client';
import { useEffect, useState } from 'react';
export function ThemeToggle() {
const [dark, setDark] = useState(false);
useEffect(() => {
const saved = localStorage.getItem('theme');
if (saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
setDark(true);
document.documentElement.classList.add('dark');
}
}, []);
function toggle() {
setDark(!dark);
document.documentElement.classList.toggle('dark');
localStorage.setItem('theme', dark ? 'light' : 'dark');
}
return (
<button onClick={toggle} className="p-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700">
{dark ? 'Claro' : 'Escuro'}
</button>
);
}SEO: generateMetadata e sitemap
Next.js tem SEO nativo. Nada de plugin, nada de biblioteca externa. Você exporta uma função generateMetadata na page.tsx e o Next gera as meta tags automaticamente — title, description, Open Graph, Twitter Cards, tudo.
// src/app/blog/[slug]/page.tsx
import { getPostBySlug, getAllPosts } from '@/lib/posts';
import { Metadata } from 'next';
type Props = { params: Promise<{ slug: string }> };
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params;
const post = await getPostBySlug(slug);
return {
title: `${post.title} | Meu Blog`,
description: post.description,
openGraph: {
title: post.title,
description: post.description,
type: 'article',
publishedTime: post.date,
},
};
}
export async function generateStaticParams() {
return getAllPosts().map((post) => ({ slug: post.slug }));
}
export default async function PostPage({ params }: Props) {
const { slug } = await params;
const post = await getPostBySlug(slug);
return (
<article className="prose dark:prose-invert mx-auto">
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
);
}Pra o sitemap, crie um arquivo src/app/sitemap.ts que lista todas as URLs do blog. O Next.js gera o sitemap.xml automaticamente a partir desse arquivo.
// src/app/sitemap.ts
import { getAllPosts } from '@/lib/posts';
export default function sitemap() {
const posts = getAllPosts().map((post) => ({
url: `https://meublog.com.br/blog/${post.slug}`,
lastModified: post.date,
changeFrequency: 'monthly' as const,
priority: 0.8,
}));
return [
{ url: 'https://meublog.com.br', lastModified: new Date().toISOString(), priority: 1 },
...posts,
];
}Deploy na Vercel: do local pro mundo
- Suba o projeto pro GitHub: git init, git add ., git commit, git push.
- Acesse vercel.com e faça login com sua conta GitHub.
- Clique em 'Add New Project' e selecione o repositório do blog.
- A Vercel detecta o Next.js automaticamente. Não precisa configurar nada.
- Clique em 'Deploy'. Em 1-2 minutos seu blog tá no ar com URL .vercel.app.
- A partir de agora, cada push na main atualiza o blog automaticamente.
Custom domain + HTTPS
No dashboard da Vercel, vá em Settings > Domains e adicione seu domínio. A Vercel vai te dar os registros DNS pra configurar (um CNAME ou registros A). Configure no seu registrador (Cloudflare, Namecheap, Registro.br) e em alguns minutos o domínio tá ativo com HTTPS automático.
Dica: use o Cloudflare como registrador (preço de custo, sem markup) e como DNS. A propagação é praticamente instantânea e você ganha uma camada extra de cache e proteção DDoS de graça.
Lighthouse 100: como tirar nota máxima
Next.js + Vercel te dá uma base sólida, mas pra bater 100 em todas as métricas do Lighthouse tem alguns ajustes. O bom é que são simples.
Checklist pra Lighthouse 100
- Use next/image pra todas as imagens (lazy loading e formatos modernos automáticos)
- Use next/font pra fontes (sem flash of unstyled text)
- Prefira Server Components (padrão no App Router) — menos JavaScript no cliente
- Evite Client Components desnecessários — use 'use client' só quando precisa de interatividade
- CSS: Tailwind já faz purge automático, mas evite importar bibliotecas CSS grandes
- Metadata: configure robots.txt e sitemap.xml corretamente
- Accessibility: use heading hierarchy correto (h1 > h2 > h3), alt em imagens, contraste de cores
Com esses ajustes, Lighthouse 100 em Performance, Accessibility, Best Practices e SEO é totalmente atingível. Eu mantenho blogs com nota 100 consistente na Vercel sem nenhum truque especial — só boas práticas.
Dá pra criar blog com Next.js sem saber React?
Sinceramente? Dá, mas vai ser sofrido. Se você nunca mexeu com React, considere começar com Astro ou Hugo — são geradores de site estático mais simples e também deployam grátis na Vercel/Netlify.
Agora, se você já sabe o básico de React (componentes, props, useState), Next.js é tranquilo. O App Router tem uma curva de aprendizado, mas em uma tarde você pega o jeito. E o investimento compensa: Next.js é o framework React mais usado do mercado.
Próximos passos
Com o blog no ar, o trabalho é criar conteúdo consistente e otimizar pro Google. Publique pelo menos 1 artigo por semana, cadastre no Search Console, e em 3-6 meses o tráfego orgânico começa a aparecer. Daí é hora de pensar em monetização — confere o nosso guia de como monetizar site hospedado de graça.
Perguntas frequentes
Quanto custa criar um blog com Next.js e Vercel?
Zero reais. Next.js é open source (grátis), Vercel tem plano Hobby gratuito com 100GB de banda, e o conteúdo fica em arquivos Markdown no repositório. O único custo opcional é o domínio personalizado (R$40-60 por ano).
Next.js é bom pra blog?
É excelente. Next.js tem static generation (páginas pré-renderizadas, ultra-rápidas), SEO nativo com generateMetadata, sitemap automático, Image optimization, e suporte a Markdown/MDX. Performance Lighthouse 100 é viável sem esforço extra.
Preciso saber programar pra criar blog com Next.js?
Precisa ter noções básicas de JavaScript e React. Se você nunca programou, talvez Astro ou Hugo sejam opções mais simples. Mas se já mexe com React ou quer aprender, Next.js é a melhor escolha de longo prazo.
Blog com Next.js precisa de banco de dados?
Não. O conteúdo fica em arquivos Markdown (.md ou .mdx) dentro do próprio repositório. Sem banco de dados, sem CMS externo, sem dependências. Você escreve o post em Markdown, faz commit e push. O blog atualiza sozinho.