---
title: "Installazione di WordPress/Bedrock + Astro"
id: "450"
type: "post"
slug: "installazione-di-wordpress-bedrock-astro"
published_at: "2026-07-13T09:40:07+00:00"
modified_at: "2026-08-27T15:28:16+00:00"
url: "https://pierluigipapeschi.com/installazione-di-wordpress-bedrock-astro/"
markdown_url: "https://pierluigipapeschi.com/installazione-di-wordpress-bedrock-astro.md"
excerpt: "Ho deciso di testare questa configurazione: backend realizzato da WordPress con la struttura di Bedrock, tema per il frontend Astro. Qualche settimana fa avevamo visto come installare il tema Sage sempre di Roots (gli sviluppatori di Bedrock) e rimanere quindi..."
taxonomy_category:
  - "Wordpress"
---

Ho deciso di testare questa configurazione: backend realizzato da WordPress con la struttura di [Bedrock](https://roots.io/bedrock/)
, tema per il frontend [Astro](https://astro.build/)
. Qualche settimana fa avevamo visto come installare il tema [Sage](https://pierluigipapeschi.com/installare-tema-sage-per-wordpress-guida-tecnica/)
 sempre di Roots (gli sviluppatori di Bedrock) e rimanere quindi in un ambiente PHP.

Adesso, con l’adozione di Astro come tema frontend, usciamo dal PHP ed entriamo in ReactJS (solo per il frontend) rendendo WordPress, come si dice in questi casi, headless, proprio senza testa…

Poiché Astro comunicherà con WordPress tramite API, consiglio di installarli su 2 domini distinti, per esempio così:

- dominio.com -> Astro
- cms.dominio.com -> WordPress

Il motivo è che hanno esigenze diverse (Astro non necessita di PHP o database, mentre WordPress sì) useranno quindi motori e “benzine” diverse. In questo modo avremo 2 mondi distinti che dialogano tramite il protocollo di internet in modo sereno e pulito.

## WordPress Bedrock

Per l’installazione di un nuovo WordPress con la struttura data da Bedrock, segui le istruzioni già fornite nell’[articolo citato sopra](https://pierluigipapeschi.com/installare-tema-sage-per-wordpress-guida-tecnica/)
.

La scelta di usare questa struttura modificata di WordPress è legata al fatto che con Bedrock si rende ibrido WordPress per avvicinarlo a Laravel. Chi è un po’ navigato nello sviluppo web non può non aver mai incontrato Laravel sulla sua strada, essendo un framework famosissimo e potentissimo, famoso per la sua velocità, sicurezza e struttura ingegneristica avanzata.

Quindi è come trasformare WordPress e renderlo veloce e potente come Laravel, ma al contempo è come rendere Laravel più user friendly come WordPress…

## Astro

Adesso installiamo Astro che ovviamente necessita di un server JS come NodeJS. Portiamoci nella console del sito da installare e digitiamo

```
mkdir astro
cd astro
npm init --yes
npm install astro@latest
```

Oltre allo scheletro di Astro abbiamo bisogno di React per le pagine e Tailwind per il CSS e le aggiungiamo con i seguenti comandi

```
npx astro add react
npx astro add tailwind
```

## DocumentRoot

Sia per WordPress (solo per la versione Bedrock) sia per Astro, dobbiamo definire la DocumentRoot del sito su valori specifici diversi dalla cartella root di default /.

Per WordPress andrà impostata

```
NOME_CARTELLA_INSTALLAZIONE_DI_WORDPRESS/web
```

mentre per Astro

```
NOME_CARTELLA_DI_INSTALLAZIONE_DI_ASTRO/dist
```

## Comunicazione tra Astro e WordPress

WordPress normalmente espone già degli endpoint che serviranno ad Astro per visualizzare le pagine ed il resto del sito. Per verificare se questi endpoint stanno effettivamente funzionando prova nella console a lanciare:

```
curl 'https://cms.dominio.com/wp-json/wp/v2/pages'
```

Essendo una semplice operazione di lettura (quindi dati pubblici) non è richiesta l’autenticazione, perciò dovresti vedere un array JSON con le prime pagine presenti su WordPress.

### “Chi siamo”

Come esempio creiamo su **WordPress** una nuova pagina e chiamiamola “Chi siamo”.

Inseriamo un contenuto e pubblichiamola.

In **Astro** dobbiamo aggiungere al file **.env** la variabile che indica l’URL di WordPress (se il file non esiste creiamolo nella root del progetto Astro)

```
WORDPRESS=https://cms.domain.com
```

Creiamo 2 cartelle

```
mkdir -p src/lib
mkdir -p src/pages
```

Aggiungiamo il file **wordpress.ts** dentro la cartella src/lib con questo contenuto

```
const WORDPRESS_URL = import.meta.env.WORDPRESS_URL;

if (!WORDPRESS_URL) {
  throw new Error("La variabile WORDPRESS_URL non è configurata");
}

export interface WordPressRenderedField {
  rendered: string;
}

export interface WordPressPage {
  id: number;
  date: string;
  modified: string;
  slug: string;
  link: string;
  title: WordPressRenderedField;
  content: WordPressRenderedField;
  excerpt: WordPressRenderedField;
  featured_media: number;
}

async function wordpressFetch<T>(
  endpoint: string,
  parameters: Record<string, string> = {},
): Promise<T> {
  const url = new URL(
    `/wp-json/wp/v2/${endpoint.replace(/^\/+/, "")}`,
    WORDPRESS_URL,
  );

  for (const [key, value] of Object.entries(parameters)) {
    url.searchParams.set(key, value);
  }

  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(
      `Errore WordPress API: ${response.status} ${response.statusText}`,
    );
  }

  return response.json() as Promise<T>;
}

export function getPages(): Promise<WordPressPage[]> {
  return wordpressFetch<WordPressPage[]>("pages", {
    status: "publish",
    per_page: "100",
  });
}

export async function getPageBySlug(
  slug: string,
): Promise<WordPressPage | null> {
  const pages = await wordpressFetch<WordPressPage[]>("pages", {
    slug,
    status: "publish",
  });

  return pages[0] ?? null;
}
```

Creiamo un file dentro **src/pages** il cui nome ha questa struttura: **[slug].astro**, quindi la pagina che abbiamo creato prima sarà raggiungibile se il file lo chiameremo **chi-siamo.astro**, il cui contenuto dovrà essere (a scopo di test)

```
---
import { getPageBySlug } from "../lib/wordpress";

const page = await getPageBySlug("chi-siamo");

if (!page) {
  throw new Error(
    'Pagina WordPress con slug "chi-siamo" non trovata. Creala e pubblicala nel CMS.'
  );
}
---

<html lang="it">
  <head>
    <title>{page.title.rendered}</title>
    <meta
      name="description"
      content={page.excerpt?.rendered?.replace(/<[^>]*>/g, "") ?? ""}
    />
  </head>

  <body>
    <h1 set:html={page.title.rendered} />
    <main set:html={page.content.rendered} />
  </body>
</html>
```

Compiliamo tutti i file TS e CSS con `npm run build`

## Rendiamo WordPress headless

La via più comoda è installare questo plugin: [Headless Mode](https://wordpress.org/plugins/headless-mode/)
.

Poi dobbiamo impostare una variabile nel file **.env** (wp-config.php per una installazione standard di WordPress):

```
// Per WordPress/Bedrock
// .env
HEADLESS_MODE_CLIENT_URL='https://domain.com'

// Per WordPress standard
// wp-config.php
define( 'HEADLESS_MODE_CLIENT_URL', 'https://domain.com' );
```

In questo modo se un utente per sbaglio inserisse lo slug sul dominio di WordPress verrebbe reindirizzata sul dominio di Astro.
