G.STANCUTA
Pubblicato · 2026 · 03 · 057 min di lettura

WordPress non vale la pena. Usa Next.js.

  • Next.js
  • WordPress
  • Performance
  • Web Dev

Ogni progetto WordPress che ho toccato si trasforma in un ciclo continuo di plugin e in un disastro su Lighthouse. Dopo aver migrato due siti clienti su Next.js, non torno indietro.

WordPress alimenta il 43 percento del web e genera una quota sproporzionata di chiamate di supporto dai clienti. Lo so perché ho trascorso due anni a costruire e mantenere siti WordPress prima di passare ogni nuovo progetto a Next.js. Il cambiamento non è una questione ideologica. È una questione di tempo, sicurezza e punteggi reali sui Core Web Vitals.

Il ciclo dei plugin e delle patch di sicurezza

Un progetto WordPress tipico finisce con 15 o 25 plugin. Ogni plugin è una dipendenza separata con il proprio ciclo di rilascio, il proprio autore e la propria storia di CVE. WordPress stesso distribuisce patch di sicurezza con poco preavviso. Quando cade una vulnerabilità critica, la finestra è stretta: aggiorna subito o sei compromesso.

Il sito Wegweiser Leben è stato il mio primo obiettivo di migrazione serio. Aveva un page builder, tre plugin SEO parzialmente sovrapposti, un plugin di caching in conflitto con il CDN dell'hosting e un plugin per i moduli segnalato due volte per XSS. Ogni mese sembrava un gioco a "quale aggiornamento romperà il layout oggi". Il cliente pagava per la manutenzione, non per un sito affidabile.

  • Il plugin A si aggiorna e rompe l'iniezione CSS del plugin B.
  • Il host aggiorna la versione PHP e due plugin generano errori fatali.
  • La patch di sicurezza di WordPress core non è ancora compatibile con il page builder.
  • Lo scanner malware segnala un plugin che non viene aggiornato da 18 mesi.
  • Si ripete all'infinito.

Con un progetto Next.js la superficie di attacco si riduce drasticamente. Nessun runtime PHP esposto a internet. Nessun pannello di amministrazione su /wp-admin. Nessuna credenziale del database in un file di configurazione piatto che un server mal configurato potrebbe servire. L'applicazione è HTML statico, CSS e JavaScript distribuiti su un CDN edge. Non c'è nulla da patchare un pomeriggio di domenica perché l'autore di un plugin ha rilasciato un aggiornamento difettoso.

Diagramma schematico che confronta il grafo delle dipendenze dei plugin WordPress con un albero di componenti Next.js snello
WordPress accumula dipendenze. Next.js parte snello e rimane tale.

Il markup dei page builder e i Core Web Vitals

Apri il sorgente di qualsiasi pagina Elementor o Divi. Troverai div annidati a più livelli, stili inline su ogni elemento, script che bloccano il rendering e file di font caricati da tre origini diverse. Quel markup è l'output di uno strumento drag-and-drop ottimizzato per la modifica visiva, non per il motore di layout del browser o per il crawler.

Il Largest Contentful Paint ne risente perché l'immagine hero viene caricata attraverso un contenitore iniettato da JavaScript che non è visibile durante il rendering iniziale. Il Cumulative Layout Shift impenna perché il page builder riserva lo spazio in modo dinamico dopo il caricamento dei font. Il Total Blocking Time cresce perché ogni widget distribuisce il proprio bundle di script indipendentemente dal fatto che il widget sia visibile su questa pagina.

Il sito Jumpino View aveva un punteggio di 41 sulle Performance mobile quando era su WordPress. Dopo la migrazione a Next.js il punteggio è 96. Il contenuto è identico. La differenza è interamente in ciò che il framework genera e in come carica le risorse.

Controlli l'output, quindi la velocità è tua

Con Next.js scrivi il componente, decidi il markup, controlli il <head>. Il componente next/image gestisce automaticamente srcset responsive, il lazy loading e la conversione in formati moderni. Non hai bisogno di un plugin per questo. Non paghi un autore di plugin per restare sveglio.

tsx
import Image from 'next/image';
import type {FC} from 'react';

type HeroProps = {
  src: string;
  alt: string;
  headline: string;
};

// Replaces a WordPress "Hero Section" plugin block.
// next/image handles srcset, WebP conversion, and LCP prioritization.
const HeroSection: FC<HeroProps> = ({src, alt, headline}) => {
  return (
    <section className="relative isolate overflow-hidden">
      <Image
        src={src}
        alt={alt}
        fill
        priority          // marks this as LCP candidate
        sizes="100vw"
        className="object-cover -z-10"
      />
      <div className="mx-auto max-w-3xl px-6 py-24">
        <h1 className="text-4xl font-bold tracking-tight text-white sm:text-6xl">
          {headline}
        </h1>
      </div>
    </section>
  );
};

export default HeroSection;

Quel componente è l'intera sostituzione di un plugin che aggiungeva 40 kB di JavaScript, un endpoint backend PHP e tre query al database per ogni caricamento di pagina. La prop priority dice a Next.js di precaricare l'immagine e contrassegnarla come elemento LCP. Il browser riceve un suggerimento prima ancora di analizzare il body. Nessun pannello di configurazione, nessuna chiave di licenza, nessuna email di rinnovo.

Moduli, contatti e gli ultimi plugin resistenti

I due plugin che trattengono i clienti su WordPress più a lungo sono il modulo di contatto e l'iscrizione alla newsletter. Entrambi hanno soluzioni pulite in Next.js. Un componente React Hook Form combinato con un Route Handler fa tutto ciò che fa Contact Form 7, con zero PHP, zero scritture nel database sul server frontend e tipi TypeScript completi sul payload dell'invio.

ts
// app/api/contact/route.ts
// Replaces Contact Form 7 + a mail plugin entirely.
import {NextRequest, NextResponse} from 'next/server';
import {Resend} from 'resend';

const resend = new Resend(process.env.RESEND_API_KEY);

export async function POST(req: NextRequest) {
  const body = await req.json();
  const {name, email, message} = body as {
    name: string;
    email: string;
    message: string;
  };

  if (!name || !email || !message) {
    return NextResponse.json({error: 'Missing fields'}, {status: 400});
  }

  const {error} = await resend.emails.send({
    from: 'contact@jumpinotech.com',
    to: 'gabriel@jumpinotech.com',
    subject: `Contact from ${name}`,
    text: `${message}\n\nReply to: ${email}`,
  });

  if (error) {
    return NextResponse.json({error: 'Send failed'}, {status: 500});
  }

  return NextResponse.json({ok: true});
}

Questo è l'intero backend. Resend gestisce la consegna. Il componente frontend chiama fetch("/api/contact", ...). Nessun plugin, nessuna interfaccia di configurazione SMTP, nessun campo honeypot da ricordarsi di aggiungere, nessun job WP cron che gestisce la coda.

Diagramma isometrico di un agente AI che legge file di memoria markdown per gestire un progetto Next.js
Un agente con contesto markdown persistente gestisce il progetto senza doverlo reimparare ogni sessione.

Come un agente AI mantiene la memoria a lungo termine di un progetto Next.js

Una volta rimosso il codebase WordPress, il progetto è abbastanza pulito da permettere a un agente AI di operare in modo affidabile tra le sessioni. La chiave è il contesto markdown persistente. Un agente che legge un file AGENTS.md ben mantenuto alla radice del progetto conosce le convenzioni, i comandi, le variabili d'ambiente e le insidie senza dovergliele ripetere ogni volta.

Per la migrazione di Wegweiser Leben mantengo un file AGENTS.md che l'agente legge all'inizio di ogni sessione. Copre la struttura delle cartelle, il formato di authoring dei contenuti (moduli TypeScript per i post, esattamente come sto usando qui), l'obiettivo di deployment e le cose che mi hanno creato problemi durante la migrazione. L'agente non indovina. Legge il file e agisce di conseguenza.

La memoria markdown non è un workaround. È l'architettura corretta per mantenere un agente affidabile su un progetto che visita in modo non continuo.

Ecco un estratto rappresentativo del file di contesto dell'agente del progetto:

md
# AGENTS.md — Wegweiser Leben Next.js Project

## Stack
- Next.js 15 (App Router), TypeScript strict, Tailwind CSS v4
- Content: TypeScript modules in src/content/posts/ typed against Post in src/content/types.ts
- Images: next/image only, no raw <img>; WebP assets in public/blog/[slug]/
- Deployment: Vercel, auto-deploy on push to main

## Commands
- dev: npm run dev (localhost:3000)
- build: npm run build — must pass before any PR
- lint: npm run lint — ESLint + Prettier, no warnings allowed

## Content authoring
- Each post is a .ts file exported as default Post
- body array uses Block types (p, h2, h3, ul, ol, quote, code, callout, image)
- readingMinutes must match actual word count (approx 200 wpm)
- date field is ISO string, do not change after publish

## Gotchas
- Tailwind v4 uses @import "tailwindcss" not @tailwind directives
- next/font must be imported in layout.tsx only, not in individual components
- Route Handlers in app/api/ use NextRequest/NextResponse from 'next/server'
- RESEND_API_KEY must be set in Vercel env vars and in .env.local for local dev
- Do not add wordpress, elementor, or divi class names anywhere

## Known issues
- Large hero images above 1 MB will fail Vercel's 4.5 MB limit; compress first

Quando apro una nuova sessione e chiedo all'agente di aggiungere un modulo di contatto o correggere un errore di build, legge prima questo file. Sa che non deve usare tag <img> grezzi. Conosce il formato dei contenuti. Sa dove si trovano le variabili d'ambiente. È continuità operativa senza un documento di passaggio o un lungo briefing verbale.

La checklist di migrazione

Sia Wegweiser Leben che Jumpino View hanno seguito la stessa sequenza. Richiede un weekend concentrato per un sito con meno di 20 pagine.

  1. 01Esporta tutti i contenuti da WordPress (esportazione XML o query diretta al DB).
  2. 02Converti post e pagine in moduli di contenuto TypeScript.
  3. 03Ricostruisci la navigazione e il layout come componenti React.
  4. 04Sostituisci il plugin del modulo di contatto con un Route Handler e Resend.
  5. 05Sostituisci il plugin SEO con la Metadata API di Next.js e next-sitemap.
  6. 06Controlla ogni immagine: comprimi, converti in WebP, sposta in public/.
  7. 07Esegui Lighthouse su ogni pagina e correggi le regressioni LCP o CLS.
  8. 08Scrivi AGENTS.md con il contesto completo del progetto.
  9. 09Distribuisci su Vercel, punta il DNS, dismetti il vecchio hosting.

È tutto qui. Nessun abbonamento continuo a plugin. Nessuna scansione di sicurezza mensile. Nessuna licenza per il page builder. Il cliente paga il piano hobby di Vercel o nulla con un export statico. Il sito è più veloce, più sicuro e meno costoso da mantenere. L'unica cosa persa è l'editor drag-and-drop che causava la metà dei problemi.

WordPress aveva senso quando l'alternativa era scrivere PHP a mano. L'alternativa oggi è un framework tipizzato e basato su componenti con un CDN globale, ottimizzazione automatica delle immagini e una pipeline di deployment che richiede 90 secondi. I calcoli sono cambiati. Smetti di manutenere ciò che puoi semplicemente sostituire.

Portfolio · Cartiglio
Disegnato da
G. STANCUTA
Disciplina
AI & AUTOMATION
Luogo
MORTER · SÜDTIROL
Stato
Disponibile
Lingue
IT · EN · RO · DE+
Stack
PLOI · HETZNER
Revisione
REV 2026.A
2026

© 2026 Gabriel Stancuta · jumpinotech.com — Progettato con l'AI, costruito per funzionare da solo.