Volver al blog

Plantilla de landing page con Next.js: créala y publícala en 1 hora

Publicado el 20 de marzo de 2026·7 min read

No hace falta dedicar tres días a crear una landing page. Con el App Router de Next.js, Tailwind CSS v4 y una librería de secciones prefabricadas, puedes pasar de npx create-next-app a una página publicada y con calidad de producción en menos de una hora. Esta guía recorre todo el proceso: configuración del proyecto, ensamblaje de secciones y despliegue.

Configuración del proyecto

Empieza con la última versión de Next.js y Tailwind CSS v4:

npx create-next-app@latest my-landing --app --ts --tailwind --src-dir
cd my-landing

Esto genera un proyecto con App Router, TypeScript, Tailwind y un directorio src/. Next.js 15 usa Tailwind v4 por defecto, lo que implica una configuración basada en CSS, sin necesidad de tailwind.config.ts en la mayoría de los casos.

Instala Framer Motion para animar las secciones:

npm install motion

La estructura de tu proyecto queda así:

my-landing/
├── src/
│   ├── app/
│   │   ├── layout.tsx
│   │   └── page.tsx
│   └── components/
│       └── sections/
├── public/
├── package.json
└── tsconfig.json

Crea el directorio src/components/sections/: cada sección vive aquí como su propio fichero.

Ensamblaje sección por sección

Una landing page que convierte sigue una fórmula probada. Este es el orden exacto de secciones que vamos a construir, y por qué existe cada una:

1. Sección Hero

El hero comunica la propuesta de valor en menos de 5 segundos. Necesita un titular, un subtítulo, un botón de CTA principal y, opcionalmente, un elemento visual (captura de pantalla, ilustración o fondo con degradado).

// src/components/sections/Hero.tsx
"use client";

import { motion } from "motion/react";

const ease = [0.16, 1, 0.3, 1] as const;

export function Hero() {
  return (
    <section className="flex min-h-[80vh] flex-col items-center justify-center px-4 text-center">
      <motion.h1
        initial={{ opacity: 0, y: 32 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.7, ease }}
        className="max-w-3xl text-5xl font-bold tracking-tight md:text-6xl"
      >
        Build landing pages at the speed of thought
      </motion.h1>
      <motion.p
        initial={{ opacity: 0, y: 24 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.7, ease, delay: 0.1 }}
        className="mt-6 max-w-xl text-lg text-muted-foreground"
      >
        844+ production-ready React sections. Copy, paste, ship.
      </motion.p>
      <motion.div
        initial={{ opacity: 0, y: 16 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.7, ease, delay: 0.2 }}
        className="mt-8 flex gap-4"
      >
        <a href="#pricing" className="rounded-xl bg-primary px-6 py-3 font-semibold text-primary-foreground">
          Get started
        </a>
        <a href="#features" className="rounded-xl border border-border px-6 py-3 font-semibold">
          See features
        </a>
      </motion.div>
    </section>
  );
}

Explora más variantes de hero con layouts divididos, fondos de vídeo y estilos con degradado.

2. Carrusel de logos

Justo después del hero, muestra logos de empresas o integraciones. Esto genera confianza antes de que la persona evalúe tus features. Una animación de marquesina sencilla cumple su función:

// src/components/sections/LogoCarousel.tsx
export function LogoCarousel({ logos }: { logos: { src: string; alt: string }[] }) {
  return (
    <section className="overflow-hidden border-y border-border py-8">
      <div className="flex animate-marquee gap-12">
        {[...logos, ...logos].map((logo, i) => (
          <img key={i} src={logo.src} alt={logo.alt} className="h-8 opacity-50 grayscale" />
        ))}
      </div>
    </section>
  );
}

Añade el keyframe de la marquesina a tu CSS global:

@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.animate-marquee {
  animation: marquee 30s linear infinite;
}

3. Grid de features

Muestra cómo tu producto cumple la promesa del hero. Un grid de 3 columnas con icono, título y descripción es el estándar:

// src/components/sections/Features.tsx
"use client";

import { motion } from "motion/react";

interface Feature {
  icon: React.ReactNode;
  title: string;
  description: string;
}

const stagger = {
  hidden: {},
  visible: { transition: { staggerChildren: 0.08 } },
};

const item = {
  hidden: { opacity: 0, y: 20 },
  visible: { opacity: 1, y: 0, transition: { duration: 0.5 } },
};

export function Features({ features }: { features: Feature[] }) {
  return (
    <section id="features" className="mx-auto max-w-6xl px-4 py-24">
      <h2 className="text-center text-3xl font-bold">Everything you need</h2>
      <motion.div
        variants={stagger}
        initial="hidden"
        whileInView="visible"
        viewport={{ once: true, margin: "-80px" }}
        className="mt-12 grid gap-8 md:grid-cols-2 lg:grid-cols-3"
      >
        {features.map((f) => (
          <motion.div key={f.title} variants={item} className="rounded-2xl border border-border p-6">
            <div className="mb-4 text-2xl">{f.icon}</div>
            <h3 className="text-lg font-semibold">{f.title}</h3>
            <p className="mt-2 text-sm text-muted-foreground">{f.description}</p>
          </motion.div>
        ))}
      </motion.div>
    </section>
  );
}

Consulta toda la gama de layouts de secciones de features: filas alternas, bento grids, grids de iconos y más.

4. Testimonios

Prueba social de usuarios reales. Tres tarjetas de testimonio en fila es el layout efectivo más sencillo:

// src/components/sections/Testimonials.tsx
interface Testimonial {
  quote: string;
  name: string;
  role: string;
  avatar: string;
}

export function Testimonials({ testimonials }: { testimonials: Testimonial[] }) {
  return (
    <section id="social-proof" className="bg-muted/50 px-4 py-24">
      <h2 className="text-center text-3xl font-bold">Loved by developers</h2>
      <div className="mx-auto mt-12 grid max-w-5xl gap-8 md:grid-cols-3">
        {testimonials.map((t) => (
          <div key={t.name} className="rounded-2xl border border-border bg-card p-6">
            <p className="text-sm italic text-muted-foreground">&ldquo;{t.quote}&rdquo;</p>
            <div className="mt-4 flex items-center gap-3">
              <img src={t.avatar} alt={t.name} className="h-10 w-10 rounded-full" />
              <div>
                <p className="text-sm font-semibold">{t.name}</p>
                <p className="text-xs text-muted-foreground">{t.role}</p>
              </div>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

Descubre las variantes de testimonios con layouts de marquesina, masonry y testimonios en vídeo.

5. Precios

Elimina la objeción del "¿cuánto cuesta?". Un toggle entre precio mensual y anual es el patrón SaaS habitual. Revisa el catálogo de secciones de precios para layouts de toggle, comparación de planes y calculadora.

6. CTA + Footer

Cierra con una llamada a la acción clara y un footer minimalista. El CTA reafirma la propuesta de valor y ofrece un único botón. El footer aporta enlaces legales, enlaces sociales y el aviso de copyright.

Componer la página

Conecta todas las secciones en src/app/page.tsx:

import { Hero } from "@/components/sections/Hero";
import { LogoCarousel } from "@/components/sections/LogoCarousel";
import { Features } from "@/components/sections/Features";
import { Testimonials } from "@/components/sections/Testimonials";

export default function HomePage() {
  return (
    <main>
      <Hero />
      <LogoCarousel logos={[/* your logos */]} />
      <Features features={[/* your features */]} />
      <Testimonials testimonials={[/* your testimonials */]} />
      {/* Pricing */}
      {/* CTA */}
      {/* Footer */}
    </main>
  );
}

Cada sección es un componente independiente con su propio contrato de datos. Sustituye los datos de prueba por contenido real y la página queda lista para producción.

Despliegue

Vercel es el camino más rápido del código a la URL para proyectos Next.js:

npx vercel --prod

También puedes conectar tu repositorio Git a Vercel para desplegar automáticamente en cada push. El paso de build detecta Next.js de forma automática, sin necesidad de configuración.

Para otras plataformas, next build && next start produce un servidor de producción en Node.js. Expórtala como estática con output: "export" en next.config.ts si tu landing page no tiene rutas dinámicas.

Ensamblaje más rápido con Incubator

Escribir cada sección desde cero es el camino lento. El catálogo de Incubator te da más de 844 secciones React listas para producción: heroes, grids de features, tablas de precios, testimonios, CTAs, footers, navbars y mucho más. Cada sección es un componente autónomo con datos de prueba incluidos. Recorre el catálogo, copia las secciones que necesites, reemplaza el contenido y despliega. Así es como se publica una landing page en una hora.

Relacionado en incubator

VA

Victor Aubague

Desarrollador y creador de Incubator

Desarrollador full-stack especializado en React, Next.js y TypeScript. Creé Incubator para ayudar a los desarrolladores a lanzar interfaces bonitas más rápido, todos los componentes provienen de proyectos reales de clientes y de código en producción.

LinkedIn

Related articles

Plantilla de landing page con Next.js: créala y publícala en