nuxt3 für Cloudflare Pages umbauen

Ein bestehendes Nuxt-Projekt soll nachträglich auf Cloudflare Pages geschmissen werden und mit einer D1 Datenbank reden.

Wir gehen hier im Schnelldurchlauf durch die notwendigen Anpassungen im Projekt, vermutlich sogar mit kaum Erklärung, da wenig kompliziert.

Installation der notwendigen Pakete:

npm install --save wrangler@4 [email protected]Code language: Shell Session (shell)

In der nuxt.config.ts das Preset auf cloudflare_pages setzen und das nitro-cloudflare-dev-Modul nachladen:

{
  // ...
  nitro: {
    preset: "cloudflare_pages",
  },
  modules: [
    "nitro-cloudflare-dev"
  ]
}Code language: JSON / JSON with Comments (json)

Eine d1-Datenbank erstellen:

npx wrangler s1 create demo-serverlessCode language: Shell Session (shell)

Vielleicht muss man sich bei Cloudflare einloggen, das ist der Fall wenn man noch nicht vorher mit Wrangler gearbeitet hat.

Anschließend bekommen wir eine eine Ausgabe in die folgende Richtung:

✅ Successfully created DB 'demo-serverless' in region WEUR
Created your new D1 database.

{
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "demo-serverless",
      "database_id": "00000000-0000-4000-0000-000000000000"
    }
  ]
}Code language: JavaScript (javascript)

Lokal UND REMOTE haben wir nun jeweils eine Datenbank. Beim developen lokal puffert er das im Projektverzeichnis -> .wrangler/state/v3 zwischen, wenn wir unseren Code in CF Pages laufen lassen nutzt er die Datenbank bei CF.
Das sind zwei getrennte Datenbanken. Lokal nutzt er was anderes als im Live. Wenn wir lokal sind verbrauchen wir daher auch keine Lese-/Schreibvorgänge in der Datenbank.

Next step: eine wrangler.jsonc erstellen:

{
  "$schema": "node_modules/wrangler/config-schema.json",
  // Den Namen anpassen; so heißt das Projekt später in Cloudflare
  "name": "my-example-application",
  "compatibility_date": "2025-03-11",
  "pages_build_output_dir": "dist",
  "observability": {
    "enabled": true
  },
  "d1_databases": [
    // Das hier sind die Daten von oben
    {
      "binding": "DB",
      "database_name": "demo-serverless",
      "database_id": "00000000-0000-4000-0000-000000000000"
    }
  ]
}Code language: JSON / JSON with Comments (json)

Und schon ist unser Projekt soweit, dass wir in der dev-Umgebung eine Datenbank haben.

Da hauen wir nun dummy-Daten rein:

npx wrangler d1 execute demo-serverless --local --command "CREATE TABLE IF NOT EXISTS cities (city_name TEXT PRIMARY KEY, city_description TEXT)"
npx wrangler d1 execute demo-serverless --local --command "INSERT INTO cities (city_name, city_description) VALUES ('Hamburg', 'Norddeutsche Hafenstadt')"
npx wrangler d1 execute demo-serverless --local --command "INSERT INTO cities (city_name, city_description) VALUES ('Kiel', 'Hafenstadt an der deutschen Ostseeküste')"Code language: JavaScript (javascript)

In unserer package.json die folgenden Scripte anpassen:

{
	"scripts": {
		// ...
		"preview": "npm run build && wrangler pages dev",
		"deploy": "npm run build && wrangler pages deploy"
	}
}Code language: JSON / JSON with Comments (json)

Beispielsweise können wir nun in der /server/api/cities.js folgendes reinhauen:

export default defineEventHandler(async (event) => {
    const DB = event.context.cloudflare.env.DB;

    if (!DB) {
        throw new Error('Database connection is not configured.');
    }

    var ret = await DB.prepare(`
        SELECT * FROM cities;
    `).run();
    ret = ret.results;

    return {
        error: false,
        data: ret,
    }
})Code language: JavaScript (javascript)

Nuxt mit npm run dev starten und http://localhost:3000/api/cities dann sollte folgende Ausgabe kommen:

{
  "error": false,
  "data": [
    {
      "city_name": "Hamburg",
      "city_description": "Norddeutsche Hafenstadt"
    },
    {
      "city_name": "Kiel",
      "city_description": "Hafenstadt an der deutschen Ostseeküste"
    }
  ]
}Code language: JSON / JSON with Comments (json)

Und damit sind wir lokal theoretisch fertig.

Die Datenbank ist allerdings nur lokal mit Daten gefüllt. Wenn wir deployen nimmt er die leere Datenbank, die wir oben auch zeitgleich bei Cloudflare erstellt haben. Daher müssen wir diese auch initialisieren.

Auf cloudflare.com einloggen, links “D1”, dann die Datenbank auswählen, oben irgendwo die Konsole öffnen und die dummy-Daten ebenfalls einspielen.

CREATE TABLE IF NOT EXISTS cities (city_name TEXT PRIMARY KEY, city_description TEXT)
INSERT INTO cities (city_name, city_description) VALUES ('Hamburg', 'Norddeutsche Hafenstadt')
INSERT INTO cities (city_name, city_description) VALUES ('Kiel', 'Hafenstadt an der deutschen Ostseeküste')Code language: JavaScript (javascript)

In unserem Projekt npm run deploy, bestätigen dass man ein neues Projekt möchte, und auf folgende Ausgabe warten:

/** ... **/
✨ Compiled Worker successfully
✨ Uploading Worker bundle
✨ Uploading _routes.json
🌎 Deploying...
✨ Deployment complete! Take a peek over at https://xxx.my-example-application.pages.devCode language: PHP (php)

Ein paar Sekündchen warten, bis die DNS-Einstellungen gegriffen haben.

Dann sollte unsere Seite live sein.