Published on

Desarrollo de blog ultra rápido con Next.js, Supabase y Vercel

Authors

¡Hola! Hoy te traigo una guía paso a paso para un desarrollo de blog ultra rápido y súper económico usando Next.js + Supabase, y desplegándolo en Vercel. Si quieres montar un blog desde cero sin preocuparte de servidores ni gastar un centavo, este tutorial es para ti. 😉


¿Por qué Next.js + Supabase?

  • Next.js: Framework React moderno con soporte nativo de SSR/SSG y API Routes.
  • Supabase: Base de datos PostgreSQL + API REST auto-generada + Auth, todo en plan gratuito.
  • Vercel: Hosting optimizado para Next.js; despliegue automático desde GitHub en segundos.

Combinándolos obtienes “DB → API → Front → Deploy” sin manejar infraestrucura, 100% en free tier y con una experiencia de desarrollo hiper-ágil.


Pasos

1. Crear tu proyecto en Supabase

  1. Regístrate en https://app.supabase.com
  2. Haz clic en New project, ponle un nombre y contraseña, elige región y crea.
  3. En Settings > API anota:
    • Project URL
    • anon public key

2. Definir la tabla posts

En el editor de tablas o en SQL ejecuta:

create table posts (
  id bigserial primary key,
  title text not null,
  content text not null,
  author text not null,                -- Nombre del autor o identificador
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);
  • author es NOT NULL (puede ser un nombre ficticio).
  • created_at/updated_at se llenan automáticamente.

3. Configurar el proyecto Next.js

# Crear Next.js + TypeScript + Tailwind
npx create-next-app@latest blog --typescript --import-example with-tailwindcss
cd blog

# Instalar dependencias
npm install @supabase/supabase-js axios

4. Variables de entorno

Crea .env.local en la raíz y añade:

NEXT_PUBLIC_SUPABASE_URL=https://<tu-proyecto>.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=<tu-anon-key>

🔒 La Service Role Key guárdala sólo para uso interno en código servidor.

5. Inicializar el cliente de Supabase

Crea lib/supabaseClient.ts:

import { createClient } from '@supabase/supabase-js'

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

6. Implementar API Routes

Añade app/api/posts/route.ts con:

import { NextResponse } from 'next/server'
import { supabase } from '@/lib/supabaseClient'

// GET: lista de posts
export async function GET() {
  const { data, error } = await supabase
    .from('posts')
    .select('*')
    .order('created_at', { ascending: false })
  if (error) return NextResponse.json({ error }, { status: 500 })
  return NextResponse.json(data)
}

// POST: crear un nuevo post
export async function POST(request: Request) {
  const { title, content, author } = await request.json()
  const { data, error } = await supabase.from('posts').insert({ title, content, author }).select()
  if (error) return NextResponse.json({ error }, { status: 500 })
  return NextResponse.json(data[0], { status: 201 })
}

Con App Router, cualquier archivo en app/api/*/route.ts funciona como función serverless.

7. Frontend con React + Axios

7.1 Página de lista de posts (app/page.tsx)

'use client'
import { useEffect, useState } from 'react'
import axios from 'axios'

type Post = {
  id: number
  title: string
  content: string
  author: string
  created_at: string
}

export default function Home() {
  const [posts, setPosts] = useState<Post[]>([])
  useEffect(() => {
    axios.get<Post[]>('/api/posts').then((res) => setPosts(res.data))
  }, [])

  return (
    <main className="p-8">
      <h1 className="mb-6 text-3xl">🔥 Lista de blogs</h1>
      <ul className="space-y-4">
        {posts.map((p) => (
          <li key={p.id} className="border-b pb-4">
            <h2 className="text-2xl">{p.title}</h2>
            <p className="text-sm text-gray-500">
              {p.author} · {new Date(p.created_at).toLocaleString()}
            </p>
            <p className="mt-2">{p.content}</p>
          </li>
        ))}
      </ul>
    </main>
  )
}

7.2 Página de creación de post (app/create/page.tsx)

'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import axios from 'axios'

export default function CreatePage() {
  const router = useRouter()
  const [title, setTitle] = useState('')
  const [content, setContent] = useState('')
  const [author, setAuthor] = useState('')
  const [loading, setLoading] = useState(false)

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setLoading(true)
    try {
      await axios.post('/api/posts', { title, content, author })
      router.push('/')
    } catch (err) {
      console.error(err)
    } finally {
      setLoading(false)
    }
  }

  return (
    <main className="p-8">
      <h1 className="mb-6 text-3xl">✏️ Publicar artículo</h1>
      <form onSubmit={handleSubmit} className="space-y-4">
        <input
          value={author}
          onChange={(e) => setAuthor(e.target.value)}
          placeholder="Autor"
          required
          className="w-full border p-2"
        />
        <input
          value={title}
          onChange={(e) => setTitle(e.target.value)}
          placeholder="Título"
          required
          className="w-full border p-2"
        />
        <textarea
          value={content}
          onChange={(e) => setContent(e.target.value)}
          placeholder="Contenido"
          required
          className="h-48 w-full border p-2"
        />
        <button
          type="submit"
          disabled={loading}
          className="rounded bg-blue-600 px-6 py-2 text-white disabled:opacity-50"
        >
          {loading ? 'Enviando…' : 'Publicar'}
        </button>
      </form>
    </main>
  )
}

8. Despliegue en Vercel

  1. Haz push a tu repositorio en GitHub.
  2. En Vercel, crea un New Project y selecciona tu repo.
  3. Configura las mismas Environment Variables (NEXT_PUBLIC_SUPABASE_URL y NEXT_PUBLIC_SUPABASE_ANON_KEY).
  4. Deploy y ¡listo! Tu blog estará online en segundos.

Resumen

  1. Prepara tu tabla y API en Supabase.
  2. Implementa API Routes en Next.js App Router.
  3. Crea frontend React con Axios para listar y publicar.
  4. Despliega gratis en Vercel.

Con estos pasos tendrás un blog funcionando en tiempo récord y sin gastar un dólar. ¡Éxitos con tu proyecto!