ZeroToShip

Docs/Tutorial

// tutorial

Aggiungere un blog post

Il blog di ZeroToShip è file-based: nessun CMS, nessun database. Tutto il contenuto sta in app/blog/_assets/content.tsx — un singolo file TypeScript con tre array esportati: categories, authors e articles.

1. Struttura di un articolo

Un articolo è un oggetto articleType. I campi obbligatori:

app/blog/_assets/content.tsx
tsx
{
  slug: "come-lanciare-in-5-giorni",
  title: "Come lanciare un SaaS in 5 giorni",
  description: "La mia routine per andare da idea a MRR in una settimana.",
  categories: [
    categories.find((c) => c.slug === categorySlugs.tutorial),
  ],
  author: authors.find((a) => a.slug === authorSlugs.alberto),
  publishedAt: "2026-01-15",
  image: {
    src: cover,           // import statico dell'immagine
    urlRelative: "/blog/come-lanciare/cover.jpg",
    alt: "Cover del post",
  },
  content: (
    <>
      <section>
        <h2 className={styles.h2}>Introduzione</h2>
        <p className={styles.p}>Il contenuto del post...</p>
      </section>
    </>
  ),
},

Aggiungi l'oggetto in fondo all'array articles e la pagina /blog/come-lanciare-in-5-giorni è online al prossimo build.

2. Il routing

Tre pagine dinamiche leggono da questi array:

  • /blog/[articleId] — la pagina del singolo post (fa match con article.slug)
  • /blog/category/[categoryId] — lista dei post di una categoria (match con category.slug)
  • /blog/author/[authorId] — tutti i post di un autore (match con author.slug)

Non devi toccare queste rotte, sono generiche. Se cambi uno slug, l'URL cambia automaticamente.

3. Aggiungi una categoria

Aggiungi lo slug nell'oggetto categorySlugs, poi spingi il nuovo oggetto in categories:

app/blog/_assets/content.tsx
tsx
const categorySlugs = {
  feature: "feature",
  tutorial: "tutorial",
  case_study: "case-study", // nuovo
};

export const categories = [
  /* ... */
  {
    slug: categorySlugs.case_study,
    title: "Case Study",
    titleShort: "Case",
    description: "Storie di gente che ha shippato con ZeroToShip.",
    descriptionShort: "Storie di gente che ha shippato.",
  },
];

4. Aggiungi un autore

Stesso pattern: uno slug, un oggetto in authors, un .png o .jpg in app/blog/_assets/images/authors/:

app/blog/_assets/content.tsx
tsx
import marioImg from "@/app/blog/_assets/images/authors/mario.png";

const authorSlugs = {
  alberto: "alberto",
  mario: "mario", // nuovo
};

export const authors = [
  /* ... */
  {
    slug: authorSlugs.mario,
    name: "Mario Rossi",
    job: "Indie hacker",
    description: "Sviluppatore freelance, scrive di SaaS.",
    avatar: marioImg,
    socials: [ /* opzionale */ ],
  },
];

5. SEO automatico

Ogni pagina blog genera automaticamente title, description, Open Graph e JSON-LD partendo dai campi dell'articolo — usa getSEOTags() da libs/seo.tsx. Il canonical URL è https://tuodominio.com/blog/[slug], e next-sitemap.config.js aggiunge automaticamente ogni post al sitemap alla build. Non devi fare nulla: scrivi il post, builda, sei indicizzabile.