Loading...
Contentful Algolia Nextjs 14 Datasync
Author Cloudapp
E.G.

Inhaltssynchronisation Contentful zu Algolia mit Next.js 14

15. April 2024
Inhaltsverzeichnis

Gehen wir davon aus, dass Sie planen, eine On-Page-Suche auf Ihrer Website oder Ihrem Blog zu integrieren und Sie wissen nicht, welche Lösung einfach zu implementieren und dazu auch noch kostenlos ist. Haben Sie bereits von dem Headless CMS Contentful und der KI-Suche Algolia gehört?

Wir bereits in meinen vorherigen Artikeln beschrieben (Schritt-für-Schritt Anleitung für das ganze Projekt -> Next js Content Management, Quo Vadis ? ) gibt es großzügige Abomodelle von Contentful und Algolia.

Algolia — Build Plan (Kostenlos)

  • Bis zu 10k Suchanfragen pro Monat

  • 1 Mio. Datensätze

  • KI Funktionen stehen zum Testen bereit

Contentful — Free Plan

  • 5 Benutzer

  • 2 Sprachen

  • 1M API Anfragen / Monat

  • Community-support

  • Strukturierter Inhalt

  • Entwickler tools

  • 1 Intro Space

Next.js 14 — Route

  • Native Api Funktionen von Next.js

Beginnen wir damit, ein neues Contentful-Konto zu registrieren (falls noch nicht geschehen). Hier sind zwei Beiträge mit einer Schritt-für-Schritt-Anleitung:

Contentful Kontoregistrierung

Nextjs 13.5.6 — Complete Example — Typescript / App Router / Contentful and a lot more

Weitere Informationen zu den Inhaltstypen und GraphQL

Next.js 14 — Complete Example — Typescript / Tailwindcss / Contentful — Part 2

Jetzt noch ein Algolia Konto registrieren

Sign Up for an Algolia account

Sie können den sog. Social Login verwenden oder Ihre Mailadresse. Nachdem Sie angemeldet sind, müssen Sie eine Anwendung erstellen (Algolia erstellt nach der ersten Anmeldung eine Standardanwendung). Klicken Sie zunächst auf (1), um die Einstellungsseite zu öffnen, und dann auf (2), um die Übersichtsseite der Anwendung zu öffnen.

Settings-Algolia
Settings-Algolia

Hier sieht man die Übersichtsseite der Anwendungen ohne einen Index (1).

Applications-Algolia
Applications-Algolia

Klicken wir auf (2), um die Übersichtsseite der Suche zu öffnen, und dann klicken wir auf den Button „Index erstellen“. Wir werden ihn „example_dev“ nennen.

Indices-Algolia
Indices-Algolia
Algolia Index creation
Algolia Index creation

Gehen wir jetzt zurück zur Übersichtsseite der Einstellungen (unteres linkes Symbol -> wie im ersten Algolia-Screenshot gezeigt), aber jetzt klicken wir im linken Abschnitt „Team und Zugriff“ auf „API-Schlüssel“. Wir gelangen auf die Übersichtsseite der API-Schlüssel, wo wir drei Werte benötigen (“Application ID”, “Search-Only API Key” and ”Admin API Key”). Der Search-Only-Schlüssel wird im nächsten Beitrag verwendet, während der Frontend-Implementierung von Algolia. Jetzt benötigen wir den Admin-API-Schlüssel, weil wir Daten in den zuvor erstellten Index „example_dev“ schreiben müssen.

API-Keys-Algolia
API-Keys-Algolia

Nachdem beide Accounts (Contentful und Algolia) registriert und konfiguriert wurden, erstellen wir mit Next.js 14 den Api Endpunkt für den Daten-Push Richtung Algolia.

Sie können auch direkt das unten angeführte GitHub-Repository klonen.

GitHub link -> GitHub - cloudapp-dev/nextjs14-SEO

welches bereits den kompletten Code der 6 vorhergehenden Artikel beinhaltet (Übersicht) + SEO Zusatzinfos

Wir fügen folgenden Variablen zur Datei .env.local hinzu

NEXT_PUBLIC_ALGOLIA_APP_ID=xxxx -> Algolia ApplicationID 
NEXT_PUBLIC_ALGOLIA_API_KEY=xxxx -> Algolia Search-Only Key used later
ALGOLIA_MASTER_KEY=xxxx -> Algolia Admin Key (Write rights)
NEXT_PUBLIC_ALGOLIA_INDEX_NAME=example_dev
API_KEY=xxxxx -> Random Key, which we use for securing the endpoint

Mit diesen Befehl können Sie einen Api-Key generieren.

node -e "console.log(crypto.randomBytes(32).toString('hex'))"

Einen Endpunkt in Next.js erstellen

Für den neuen Endpunkt erstellen wir einen neuen Ordner unter /src/app/api mit dem Namen “algoliasync” mit der unten angeführten route.ts Datei darin.

import { NextRequest, NextResponse } from "next/server";
import { documentToPlainTextString } from "@contentful/rich-text-plain-text-renderer";
import { client } from "@/lib/client";
import { fallbackLng, locales } from "@/app/i18n/settings";

const apikey = process.env.API_KEY;

export async function POST(request: NextRequest) {
  const document = await request.json();
  let json_de: string = "";
  let json_en: string = "";

  if (request.headers.get("x-api-key") !== apikey) {
    return new NextResponse(
      JSON.stringify({ status: "fail", message: "You are not authorized" }),
      { status: 401 }
    );
  }

  const locale = fallbackLng as string;

  const blogPagedata = await client.pageBlogPost({
    locale,
    preview: false,
    slug: document.slug,
  });

  const blogPost = blogPagedata.pageBlogPostCollection?.items[0];
  json_en = documentToPlainTextString(blogPost.content?.json);
  const tags = blogPost.contentfulMetadata?.tags;
  const tagsnew: any = [];

  tags.map((tag) => {
    tagsnew.push(tag.id);
  }); 

  const blogPagedata_de = await client.pageBlogPost({
    locale: "de-DE",
    preview: false,
    slug: document.slug,
  });

  const blogPost_de = blogPagedata_de.pageBlogPostCollection?.items[0];
  json_de = documentToPlainTextString(blogPost_de.content?.json);

  const AlgoliaUrl =
    "https://" +
    process.env.NEXT_PUBLIC_ALGOLIA_APP_ID +
    ".algolia.net/1/indexes/" +
    process.env.NEXT_PUBLIC_ALGOLIA_INDEX_NAME +
    "/" +
    document.entityId;

  const date = blogPost.publishedDate;
  const formatDate = new Date(date).toISOString().substring(0, 10);
  const timeStamp = new Date(date).getTime() / 1000;

  const jsonData: any = {
    entityId: document.entityId,
    height: blogPost?.featuredImage?.height.toString(),
    width: blogPost?.featuredImage?.width.toString(),
    image: blogPost?.featuredImage?.url,
    intName: document.intName,
    lang: {
      "de-DE": {
        content: json_de,
        shortDescription: document.shortDescription_de,
        title: document.title_de,
      },
      "en-US": {
        content: json_en,
        shortDescription: document.shortDescription_en,
        title: document.title_en,
      },
    },
    pubdate: formatDate,
    pubdatetimestamp: timeStamp,
    slug: document.slug,
    spaceId: document.spaceId,
    tags: tagsnew,
  };

  const res = await fetch(AlgoliaUrl, {
    method: "PUT",
    body: JSON.stringify(jsonData),
    headers: {
      "Content-Type": "application/json; charset=utf-8",
      "X-Algolia-API-Key": process.env.ALGOLIA_MASTER_KEY,
      "X-Algolia-Application-Id": process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
    },
  });

  if (!res.ok) {
    const text = await res.text();

    throw new Error(`
      Failed to fetch data
      Status: ${res.status}
      Response: ${text}
    `);
  }

  const result: any = await res.json();
  // console.log("result", result);

  return NextResponse.json(
    { transformed: true, date: Date.now() },
    { status: 200 }
  );
}

Am Dateianfang importieren wir diese NPM-Pakete

import { NextRequest, NextResponse } from "next/server"; -> standard Nextjs Api package
import { documentToPlainTextString } from "@contentful/rich-text-plain-text-renderer"; -> needed to extract the text part out of the JSON (Contentful Rich Text field)
import { client } from "@/lib/client"; -> client for Contentful graphQL operations
import { fallbackLng, locales } from "@/app/i18n/settings"; -> Language settings

Dann kontrollieren wir auf die Richtigkeit des API Keys.

const apikey = process.env.API_KEY; -> getting API Key 

// Return 401 in case we provide the wrong "x-api-key" in the header

if (request.headers.get("x-api-key") !== apikey) {
    return new NextResponse(
      JSON.stringify({ status: "fail", message: "You are not authorized" }),
      { status: 401 }
    );
  }

Erstellen einen Contentful Webhook

Der letzte Schritt besteht darin, den neuen Webhook in Contentful einzurichten, sodass wir Änderungen/Löschungen an den neu erstellten Index „example_dev“ weiterleiten.

Contentful Webhooks
Contentful Webhooks
add Webhooks contentful
add Webhooks contentful

Hier eine Detailübersicht hinsichtlich der Erstellung des Webhook, welcher die Daten von Contentful über unseren Endpunkt, Richtung Algolia pushen wird.

Nextjs-Algolia-Push-Webhooks
Nextjs-Algolia-Push-Webhooks

der zweite Screenshot zeigt den zweiten Webhook für das sog. "unpublish" der Daten. Wenn ein Datensatz in Contentful gelöscht oder auf "unpublish" gesetzt wird, dann muss dies ebenfalls an Algolia übermittelt werden.

Algolia-Delete-unpublished-entries-Webhooks
Algolia-Delete-unpublished-entries-Webhooks

In diesem Tutorial habe ich das Projekt, das ich in den vorherigen Schritten erstellt habe, als Grundlage verwendet und daraufhin die Synchronisation zwischen Contentful und Algolia aufgebaut.

Cloudapp-dev und bevor Sie uns verlassen

Danke, dass Sie bis zum Ende gelesen haben. Noch eine Bitte bevor Sie gehen:

  • Wenn Ihnen gefallen hat was Sie gelesen haben oder wenn es Ihnen sogar geholfen hat, dann würden wir uns über einen "Clap" 👏 oder einen neuen Follower auf unseren Medium Account sehr freuen.

Verwandte Artikel

Nextjs 14 Part4

Next.js 14 - Komplettes Beispiel - Benutzerdefinierte 404 Seite / Loading UI / TailwindCss (ExtraColors) - Part 4

In Teil 4 werden wir eine benutzerdefinierte 404-Seite hinzufügen, eine Lade-Benutzeroberfläche (SVG Spinner) und wir fügen unserer tailwind.config.ts einige zusätzliche Farben hinzu.

Author Cloudapp
E.G.
23. März 2024
Next.js 14 - typescript contentful tailwindcss - full example

Next.js 14 - Komplettes Beispiel - Typescript / Tailwindcss / Contentful - Teil 2

Lassen Sie uns etwas tiefer gehen und eine schöne Benutzeroberfläche auf unserer Nextjs-Basis mit Hilfe von Tailwindcss/Contentful erstellen

Author Cloudapp
E.G.
11. März 2024
Next.js 14 - header footer contentful tailwindcss - full example - part3

Next.js 14 - Komplettes Beispiel - Header / Footer / Tailwindcss / Contentful - Teil 3

Nun haben wir Teil 3 erreicht und wir werden eine Kopf- und Fußzeilenkomponente hinzufügen, sowie die sogenannte Entwurfs-/Vorschaufunktion, die von Contentful angeboten wird. Nicht zu vergessen der heutzutage obligatorische Wechsel in den Dunkelmodus.

Author Cloudapp
E.G.
18. März 2024
nextjs 14 typescript contentful app router - full example

Next.js 14 - Komplettes Beispiel - Typescript / App Router / Contentful mit GraphQL - Teil 1

Lassen Sie uns eine völlig neue Website erstellen, die mit Next.js 14, Contentful und TypeScript betrieben wird.

Author Cloudapp
E.G.
8. März 2024
Nextjs-Speedup

Beschleunigen Sie Ihre Next.js 14 Webseite und verbessern Sie Ihre SEO Position

Die Seitengeschwindigkeit ist ein bedeutender Ranking-Faktor für Suchmaschinen. Next.js bietet verschiedene Funktionen wie zum Beispiel optimiertes Bildladen.

Author Cloudapp
E.G.
5. April 2024
Nextjs 14 Part5

Next.js 14 - Komplettes Beispiel - Hinzufügen von Internationalisierung / Mehrsprachigkeit zu unserem Blog basierend auf Contentful/GraphQL - Teil 5

In Teil 5 werden wir unserer Contentful Blog Mehrsprachigkeit hinzufügen und einen Sprachumschalter integrieren. Es werden Client/Server Komponenten verwendet

Author Cloudapp
E.G.
29. März 2024