Zurück zur Startseite

SSR für SPA: Indexierungs-Einrichtung

Der Artikel behandelt die Einrichtung von Serverseitigem Rendering für die Indexierung von SPA-Anwendungen durch Suchmaschinen. Umfasst Next.js, Nuxt.js, Angular Universal mit Codebeispielen. Verbesserung von Core Web Vitals und organischem Traffic.

SSR für SPA-Indexierung: React, Vue, Angular
Advertisement 728x90

Server-Side Rendering für SPAs: So verbessern Sie die Indexierung durch Suchmaschinen

Such-Crawler wie Googlebot und YandexBot erhalten bei der Analyse von CSR-basierten Single-Page-Anwendungen oft leere HTML-Seiten. Ohne Server-Side Rendering (SSR) warten sie nicht auf die Ausführung von JavaScript – und lassen Seiten daher unindexiert. SSR löst dieses Problem, indem es vollständig gerendertes HTML bereits auf dem Server generiert, bevor es an den Client gesendet wird. Dadurch beschleunigt sich FCP, LCP und TTFB – was sowohl die Core Web Vitals als auch die organische Sichtbarkeit spürbar verbessert.

Vergleich der Rendering-Methoden

| Parameter | CSR | SSR | Vorrendering | SSG |

|----------|-----|-----|--------------|-----|

Google AdInline article slot

| Render-Standort | Browser | Server (pro Anfrage) | Vorab für bestimmte URLs gebaut | Vorab für alle Seiten gebaut |

| FCP/LCP | Langsam | Schnell | Schnell | Sehr schnell |

| SEO | Schwach | Ausgezeichnet | Gut | Ausgezeichnet |

Google AdInline article slot

| Datenaktualität | Echtzeit | Echtzeit | Veraltet | Veraltet |

| Serverlast | Minimal | Hoch | Niedrig | Minimal |

SSR eignet sich besonders gut für dynamische Seiten – etwa Produktkataloge, News-Feeds oder Dashboards. Vorrendering ist ideal für selten aktualisierte URLs (z. B. Marketingseiten). SSG hingegen ist die beste Wahl für statische Inhalte wie Dokumentation oder Landingpages.

Google AdInline article slot

React + Next.js: Schritt-für-Schritt-Anleitung

Erstellen Sie ein neues Projekt:

npx create-next-app@latest mein-ssr-projekt
cd mein-ssr-projekt
npm run dev

Für dynamische Seiten nutzen Sie getServerSideProps:

// pages/product/[id].jsx
export async function getServerSideProps(context) {
  const { id } = context.params;
  const res = await fetch(`https://api.beispiel.de/produkte/${id}`);
  const produkt = await res.json();

  if (!res.ok) {
    return { notFound: true };
  }

  return {
    props: { produkt },
  };
}

export default function ProduktSeite({ produkt }) {
  return (
    <main>
      <h1>{produkt.name}</h1>
      <p>{produkt.beschreibung}</p>
    </main>
  );
}

Fügen Sie suchmaschinenfreundliche Meta-Tags hinzu:

import Head from 'next/head';

export default function ProduktSeite({ produkt }) {
  return (
    <> 
      <Head>
        <title>{produkt.name} | Shop</title>
        <meta name="description" content={produkt.kurzbeschreibung} />
        <meta property="og:title" content={produkt.name} />
        <meta property="og:image" content={produkt.bildUrl} />
      </Head>
      <main>
        <h1>{produkt.name}</h1>
      </main>
    </>
  );
}

Deployment: Vercel, Netlify oder Node.js mit PM2.

Fehlerfreie Hydration

Hydration beschreibt, wie React im Browser das serverseitig gerenderte HTML „wiederbelebt“. Vermeiden Sie Inkompatibilitäten:

  • Halten Sie Server- und Client-Daten stets synchron.
  • Prüfen Sie vor der Nutzung von window oder document, ob der Code im Browser läuft.
  • Achten Sie auf Warnungen in der Browser-Konsole.
const istBrowser = typeof window !== 'undefined';

Vue + Nuxt.js: Server-Side Rendering

Initialisieren Sie ein Projekt:

npx nuxi@latest init mein-nuxt-projekt
cd mein-nuxt-projekt
npm install
npm run dev

Laden Sie Daten serverseitig:

<!-- pages/product/[id].vue -->
<script setup>
const route = useRoute();
const { data: produkt, error } = await useFetch(
  `/api/produkte/${route.params.id}`
);

if (error.value) {
  throw createError({ statusCode: 404, message: 'Nicht gefunden' });
}

useHead({
  title: produkt.value?.name,
  meta: [
    { name: 'description', content: produkt.value?.kurzbeschreibung },
  ],
});
</script>

<template>
  <main>
    <h1>{{ produkt?.name }}</h1>
    <p>{{ produkt?.beschreibung }}</p>
  </main>
</template>

Konfigurieren Sie nuxt.config.ts:

export default defineNuxtConfig({
  ssr: true,
  app: {
    head: {
      htmlAttrs: { lang: 'de' },
      link: [{ rel: 'canonical', href: 'https://beispiel.de' }],
    },
  },
  nitro: {
    preset: 'node-server',
  },
});

Angular Universal: SSR-Integration

Für Angular 17+:

ng add @angular/ssr

Definieren Sie den Server-Endpunkt in server.ts:

import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import express from 'express';
// ... weitere Imports

const server = express();
// ...

server.get('*', (req, res, next) => {
  commonEngine
    .render({
      bootstrap: AppServerModule,
      documentFilePath: join(browserDistFolder, 'index.html'),
      url: req.originalUrl,
      publicPath: browserDistFolder,
      providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }],
    })
    .then((html) => res.send(html))
    .catch(next);
});

Bauen und starten Sie:

npm run build:ssr
npm run serve:ssr

Sichere Plattformerkennung:

import { isPlatformBrowser } from '@angular/common';
import { inject, PLATFORM_ID } from '@angular/core';

const platformId = inject(PLATFORM_ID);

if (isPlatformBrowser(platformId)) {
  console.log(window.location.href);
}

Integration mit Headless CMS

Für Next.js + Contentful GraphQL:

export async function getServerSideProps({ params }) {
  const query = `
    query GetArtikel($slug: String!) {
      artikelCollection(where: { slug: $slug }) {
        items {
          titel
          inhalt
          seo {
            titel
            beschreibung
          }
        }
      }
    }
  `;

  const res = await fetch(
    `https://graphql.contentful.com/content/v1/spaces/${process.env.CONTENTFUL_SPACE_ID}`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${process.env.CONTENTFUL_TOKEN}`,
      },
      body: JSON.stringify({ query, variables: { slug: params.slug } }),
    }
  );

  const { data } = await res.json();
  // ...
}

Wichtigste Erkenntnisse

  • SSR liefert Such-Crawlern vollständig gerendertes HTML – und löst damit das zentrale Indexierungsproblem von CSR-Anwendungen.
  • Next.js, Nuxt.js und Angular Universal sind erprobte Frameworks für SSR im Produktionseinsatz.
  • Hydrationsfehler führen zu kompletten Neu-Renderings – prüfen Sie daher stets die Laufzeitumgebung.
  • Die Core Web Vitals (FCP, LCP, TTFB) verbessern sich nach dem Wechsel zu SSR um 50–80 %.
  • Nutzen Sie Redis-Caching, um die TTFB bei Traffic-Spitzen unter 200 ms zu halten.

— Editorial Team

Advertisement 728x90

Weiterlesen