byte5
← Tutti gli articoli
BLOG

Come abbiamo costruito il blog di byte5

·2 min di lettura
MDXNext.jsEngineeringbyte5
Christian Wendler
Amministratore Delegato

Volevamo un blog che desse la stessa sensazione del resto di byte5.ai: veloce, statico, senza database, senza lock-in del fornitore. Nessun CMS headless, nessuna API esterna — i contenuti vivono come file nel repository e passano per lo stesso processo di review del codice.

Questo articolo ripercorre l'architettura che c'è dietro e perché scala bene per un team multilingue.

I contenuti come file#

Ogni articolo è un file MDX per lingua più una voce tipizzata nel registry. Il registry contiene tutti i campi indipendenti dalla lingua — data, tag, autore, copertina:

export const posts: BlogPostMeta[] = [
  {
    slug: "wie-wir-den-byte5-blog-gebaut-haben",
    publishedAt: "2026-05-20",
    tags: ["MDX", "Next.js", "Engineering", "byte5"],
    authorId: "christian-wendler",
    sourceLanguage: "de",
  },
];

Il bello: filtrare e ordinare nella panoramica funzionano puramente su questi dati tipizzati. Il testo vero e proprio resta dove deve stare — nel file MDX.

I contenuti appartengono al repository, non a un database. Così ogni articolo riceve la stessa cura di qualsiasi modifica al codice: branch, review, diff.

Dal markdown a un server component#

I file MDX vengono compilati in fase di build/render e resi come React Server Component. L'evidenziazione della sintassi è gestita da Shiki — interamente sul server, senza inviare un solo kilobyte di JavaScript al browser:

La pipeline MDX: dal file alla compilazione fino a un server component

Perché nessuna libreria client?#

Evidenziazione, ancore dei titoli e markdown in stile GitHub avvengono tutti in fase di render. Il browser riceve HTML già pronto. Questo mantiene le pagine leggere e i Core Web Vitals verdi.

Preparare, non correre#

Un dettaglio a cui tenevamo: gli articoli con una data di pubblicazione futura non compaiono nella panoramica — eppure la pagina di dettaglio è già raggiungibile tramite link. Così gli articoli possono essere preparati con calma e vanno online automaticamente al raggiungimento della loro data.

export const revalidate = 600;
 
export default async function BlogIndex() {
  const now = Date.now(); // valutare sempre in fase di render
  const published = getPublishedPosts(now);
  // ...
}

Il supporto multilingue completa il quadro: un articolo viene scritto in tedesco o inglese e tradotto nelle altre lingue. Se manca una traduzione, la pagina ripiega in modo pulito sulla lingua di origine e mostra un discreto badge della lingua.

Il risultato è un blog tecnicamente noioso — nel senso migliore. È esattamente ciò che volevamo.