> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# SEO-Content für Produkte

> Zusätzliche SEO-Felder je Produkt, gepflegt im TopRank-Manager oder direkt im Shop, samt sprechendem Produktnamen für URL und Canonical.

Produktdaten kommen meist aus der Warenwirtschaft, und dort denkt niemand an Meta-Titel und Meta-Beschreibungen. Genau diese Lücke schließt das Feature "SEO-Content für Produkte": Der SEO-Verantwortliche pflegt je Produkt zusätzliche Felder, ohne Zugriff auf die Warenwirtschaft und ohne den WSPManager zu öffnen.

Zusätzlich liefert das Feature den sprechenden Produktnamen für die Adresse. Statt `?websale8=ihr-shop&pi=100419&ci=2012054` steht dann beispielsweise `/Leinen/Trainingsleine-camo` in der Adresszeile.

Das Feature arbeitet unabhängig von den SEO-URLs. Sie brauchen keine SEO-URLs, um den SEO-Content zu nutzen. Planen Sie beides, stellen Sie es besser gemeinsam um, sonst entstehen zweimal hintereinander neue Adressen und damit zweimal Weiterleitungen.

## Was zur Verfügung steht

Je Produkt gibt es 21 Felder:

| Feld | Länge | Wofür |
| - | - | - |
| SEO-Produktname | maximal 127 Zeichen | sprechender Name in Adresse und Canonical, muss im Shop eindeutig sein |
| SEO-Feld 1 bis 20 | maximal 4000 Zeichen | freier Inhalt, der an beliebiger Stelle im Template ausgegeben wird |

Wo die Felder landen, entscheidet allein Ihr Template. Üblich sind Feld 1 für den Titel, Feld 2 für die Meta-Beschreibung und Feld 3 für Keywords. Klären Sie die Belegung vorab mit dem SEO-Verantwortlichen ab, denn sie ist danach nur noch mit Aufwand zu ändern.

## Zwei Wege der Pflege

| | TopRank-Manager | SEO-Modus im Shop |
| - | - | - |
| Wo | Online-Servicebereich, Menüpunkt "SEO-Content für Produkte" | Produktdetailansicht des Shops, aufgerufen mit `?seomode=on` |
| Wie | Datentabelle hochladen, herunterladen, bearbeiten, erneut hochladen | Eingabefelder direkt am Produkt ausfüllen |
| Stärke | viele Produkte auf einmal, subshopübergreifend | Ergebnis sofort am Produkt sichtbar |
| Aufwand bei der Einrichtung | gering, kein zusätzliches Template | höher, ein eigenes Template und ein Modul |

Beide Wege schreiben in dieselben Felder. Sie können also im TopRank-Manager vorbelegen und im SEO-Modus nacharbeiten.

Verbundene Subshops erhalten den SEO-Content wie die Produktdaten automatisch aus dem Haupt-Subshop. Gepflegt wird deshalb immer im Haupt-Subshop. Ruft jemand den SEO-Modus in einem verbundenen Subshop auf, bekommt er einen Hinweis, in welchem Shop er arbeiten muss.

## Der sprechende Produktname

Ist der SEO-Produktname gefüllt und steht `Link-Allow` auf `yes`, wird er in der Adresse und im Canonical verwendet. Alle Programme, die Produktadressen nach außen geben, also FeedEngine, TopRank und weitere, verwenden ihn dann ebenfalls.

> [!WARNING]
>
> Der SEO-Produktname muss im Shop eindeutig sein. Ist er schon an einem anderen Produkt vergeben, wird die Eingabe mit einer Fehlermeldung abgewiesen.

Sind SEO-URLs aktiv, wird ein geänderter SEO-Produktname erst nach dem manuellen Generieren im TopRank-Manager wirksam. Automatisch geschieht das bei jedem Import und bei jeder Erzeugung eines Datenfeeds.

Wegweiser: Canonical-Anweisung im Head erzeugen · [SEO-URLs und Link-Optimierung](https://dokumentation.websale.de/v8s/seo/seo-urls-und-link-optimierung.md)

## Einrichten

Welche Schritte für Sie gelten, hängt vom gewählten Pflegeweg ab:

| Schritt | TopRank-Manager | SEO-Modus |
| - | - | - |
| 1 Freischaltung | erforderlich | nur für WEBSALE-Tags in den Feldern |
| 2 Abschnitt `SEOProductFields` | ja | ja, mit zusätzlichen Parametern |
| 3 Fehlertexte | entfällt | ja |
| 4 Template für die Eingabefelder | entfällt | ja |
| 5 Modul einbinden | entfällt | ja |
| 6 Felder im Template ausgeben | ja | ja |
| 7 JavaScript-Bibliothek | entfällt | ja |
| 8 Testen | ja | ja |

### Schritt 1: Freischaltung

Die Pflege im TopRank-Manager muss von WEBSALE freigeschaltet werden. Für den SEO-Modus ist das nicht nötig.

> [!WARNING]
>
> Wollen Sie in den SEO-Produktfeldern WEBSALE-Tags verwenden, ist dafür in beiden Fällen eine schriftliche Beauftragung und eine technische Freischaltung nötig. Der Grund ist haftungsrechtlich: Über die Felder käme sonst ausführbarer Templatecode in den Shop, ohne dass er das Design durchlaufen hat.

### Schritt 2: Abschnitt SEOProductFields in der shop.config

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<SEOProductFields>
   Allow        = yes
   Link-Allow   = yes
   Template     = incl_product_seo.htm
      <Password>
         +Entry = ...
         +Entry = ...
      </Password>
</SEOProductFields>
```

| Parameter | Bedeutung |
| - | - |
| `Allow` | schaltet die Funktion insgesamt an oder ab |
| `Link-Allow` | bestimmt, ob der SEO-Produktname für Adresse und Canonical verwendet wird |
| `Template` | Name des Templates mit den Eingabefeldern, nur für den SEO-Modus |
| `<Password>` mit `+Entry` | je ein Passwort für den Aufruf des SEO-Modus, nur für den SEO-Modus |

Bei Pflege im TopRank-Manager genügen `Allow` und `Link-Allow`.

Mehrere Passwörter sind sinnvoll, wenn mehrere Personen mit dem SEO-Modus arbeiten. Entfernen Sie ein `+Entry`, ist der Zugang über dieses Passwort sofort zu. Nach dreimaliger Fehleingabe ist der SEO-Modus für fünf Minuten gesperrt.

Der SEO-Modus setzt Cookies im Browser voraus und läuft immer verschlüsselt. Hängen Sie `?seomode=on` an eine unverschlüsselte Adresse an, leitet der Shop selbst auf die verschlüsselte Adresse um. Jede Anmeldung am SEO-Modus wird protokolliert.

Referenz: [Abschnitt SEOProductFields](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/grundlagen-und-technik.md#seoproductfields)

### Schritt 3: Fehlertexte festlegen

Nur für den SEO-Modus. Die Texte erscheinen im Eingabeformular, wenn eine Eingabe nicht übernommen werden kann.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<SEOProductFields-Text>
   ErrorNameTooLong         = Der SEO-Produktname darf maximal 127 Zeichen lang sein. Bitte korrigieren Sie Ihre Eingabe.
   ErrorFieldTooLong        = Ein Eintrag darf maximal aus 4000 Zeichen bestehen. Bitte korrigieren Sie Ihre Eingabe.
   ErrorNameAlreadyExists   = Der SEO-Produktname wird bereits für ein anderes Produkt verwendet. Bitte korrigieren Sie Ihre Eingabe.
   ErrorConnectedSubshop    = In diesem Subshop können keine Produkte optimiert werden. Bitte wechseln Sie in den Haupt-Subshop.
   ErrorMainCatIndexTooLong = Der Hauptkategorieindex ist zu lang (maximal 255 Zeichen).
</SEOProductFields-Text>
```

Referenz: [Abschnitt SEOProductFields-Text](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/grundlagen-und-technik.md#seoproductfields-text)

### Schritt 4: Template für die Eingabefelder anlegen

Nur für den SEO-Modus. Die Eingabefelder stehen nicht direkt auf der Produktdetailansicht, sondern in einem eigenen Template. Legen Sie es unter dem Namen an, den Sie in Schritt 2 hinter `Template` eingetragen haben, und speichern Sie es in Ihrem Template-Verzeichnis.

Das folgende Beispiel zeigt fünf der zwanzig Felder. Die übrigen ergänzen Sie nach demselben Muster.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{WS-Include}
  {!E-PSEO_Connected_Subshop}

    <div id="SeoProductError">
      {ST-Ajax}<WS-Ajax-SeoProductError>{/ST-Ajax}
        {E-PSEO_Error}
          <p>Es ist ein Fehler aufgetreten.</p>
          <p>~E-PSEO_Error~</p>
        {/E-PSEO_Error}
      {ST-Ajax}</WS-Ajax-SeoProductError>{/ST-Ajax}
    </div>

    <div id="SeoProductSuccess">
      {ST-Ajax}<WS-Ajax-SeoProductSuccess>{/ST-Ajax}
        {E-PSEO_Success}
          <p>Ihre Eingaben wurden gespeichert.</p>
        {/E-PSEO_Success}
      {ST-Ajax}</WS-Ajax-SeoProductSuccess>{/ST-Ajax}
    </div>

    <form class="seoform" action="/websale8/" method="post" id="SeoFormEdit">
      <input type="hidden" name="Ctx" value="~WS-CTX~">
      <input type="hidden" name="pi" value="~PR-ProdIndex~">
      <input type="hidden" name="~E-PSEO_Action_Save~" value="true">

      <div id="SEOFields">
        {ST-Ajax}<WS-Ajax-SEOFields>{/ST-Ajax}

        Aktuelle Adresse des Produktes:<br>
        ~PR-Link~

        <label for="~E-PSEO_Name_Input~">SEO-Produktname für den sprechenden Namen in der Adresse (maximal 127 Zeichen):</label>
        <input type="text" name="~E-PSEO_Name_Input~" value="~E-PSEO_Name~">
        {E-PSEO_Error_Name}~E-PSEO_Error_Name~{/E-PSEO_Error_Name}

        <label for="~E-PSEO_MainCatIndex_Input~">Hauptkategorieindex (maximal 255 Zeichen):</label>
        <input type="text" name="~E-PSEO_MainCatIndex_Input~" value="~E-PSEO_MainCatIndex~">
        <input type="hidden" value="yes" name="~E-PSEO_MainCatIndex_Hidden~">
        {E-PSEO_Error_MainCatIndex}~E-PSEO_Error_MainCatIndex~{/E-PSEO_Error_MainCatIndex}

        <label for="~E-PSEO_Field1_Input~">SEO-Feld 1 (maximal 4000 Zeichen), beispielsweise für den Meta-Titel:</label>
        <textarea name="~E-PSEO_Field1_Input~">~E-PSEO_Field1~</textarea>
        <input type="hidden" value="yes" name="~E-PSEO_Field1_Hidden~">
        {E-PSEO_Error_Field1}~E-PSEO_Error_Field1~{/E-PSEO_Error_Field1}

        <label for="~E-PSEO_Field2_Input~">SEO-Feld 2 (maximal 4000 Zeichen), beispielsweise für die Meta-Beschreibung:</label>
        <textarea name="~E-PSEO_Field2_Input~">~E-PSEO_Field2~</textarea>
        <input type="hidden" value="yes" name="~E-PSEO_Field2_Hidden~">
        {E-PSEO_Error_Field2}~E-PSEO_Error_Field2~{/E-PSEO_Error_Field2}

        <input type="submit" value="Eingaben speichern"
               onclick="return ws_AJAXsendFormTemplate('SeoFormEdit', '~WS-Charset~', seoStartFunction, seoFailureFunction, 'seoSuccessCallback()', 'seoErrorCallback()')">

        {ST-Ajax}</WS-Ajax-SEOFields>{/ST-Ajax}
      </div>
    </form>

    <form class="seoform" action="/websale8/" method="post" id="SeoFormReset">
      <input type="hidden" name="Ctx" value="~WS-CTX~">
      <input type="hidden" name="pi" value="~PR-ProdIndex~">
      <input type="hidden" name="~E-PSEO_Action_Reset~" value="true">
      <input type="submit" value="Eingaben zurücksetzen" name="~E-PSEO_Action_Reset~"
             onclick="return ws_AJAXsendFormTemplate('SeoFormReset', '~WS-Charset~', seoStartFunction, seoFailureFunction, 'seoSuccessCallback()', 'seoErrorCallback()')">
    </form>

  {/!E-PSEO_Connected_Subshop}

  {E-PSEO_Connected_Subshop}
    In diesem Subshop können Sie keinen SEO-Content bearbeiten.
    Bitte nehmen Sie Ihre Änderungen im Subshop ~E-PSEO_Connected_Subshop~ vor.

    SEO-Produktname: {E-PSEO_Name}~E-PSEO_Name~{/E-PSEO_Name}{!E-PSEO_Name}Keine Angaben{/!E-PSEO_Name}
    SEO-Feld 1: {E-PSEO_Field1}~E-PSEO_Field1~{/E-PSEO_Field1}{!E-PSEO_Field1}Keine Angaben{/!E-PSEO_Field1}
    SEO-Feld 2: {E-PSEO_Field2}~E-PSEO_Field2~{/E-PSEO_Field2}{!E-PSEO_Field2}Keine Angaben{/!E-PSEO_Field2}
  {/E-PSEO_Connected_Subshop}

{/WS-Include}
```

Zu jedem Feld gehört ein verstecktes Feld `~E-PSEO_Field…_Hidden~`. Ohne dieses Feld wird eine Leerung des Textfeldes beim Speichern nicht übernommen.

#### Was nach dem Speichern geschieht

Gespeichert wird in beiden Fällen über AJAX. Der Unterschied liegt darin, was danach sichtbar wird:

| Variante | Verhalten | Änderung am Beispiel |
| - | - | - |
| Seite neu laden | die komplette Produktseite wird neu aufgebaut, alle Eingaben sind sofort an ihrer Zielstelle sichtbar | die `ST-Ajax`-Klammerungen um den Erfolgs- und Fehlerbereich entfallen, stattdessen setzt der Erfolgsbereich per JavaScript `document.location.href` auf `~PR-Link~` |
| nur die AJAX-Bereiche aktualisieren | nur die geklammerten Bereiche werden erneuert, die Seite bleibt stehen | das Beispiel oben, unverändert |

In beiden Fällen wird die Produktadresse erst nach dem manuellen Generieren im TopRank-Manager neu gebildet.

> [!NOTE]
>
> Wollen Sie nach dem Speichern zur Kontrolle die eingetragenen WEBSALE-Tags sehen statt ihres Ergebnisses, klammern Sie das Eingabefeld mit `WS-NoParsing`:
>
> ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
> <textarea name="~E-PSEO_Field1_Input~">{WS-NoParsing}~E-PSEO_Field1~{/WS-NoParsing}</textarea>
> ```

Referenz: Tags für "SEO-Content für Produkte" (E-PSEO\_) · [PR-Link()](https://dokumentation.websale.de/v8s/referenz/tags/pr/bilder-und-links.md#die-tags-im-uberblick) · [PR-ProdIndex](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md#die-tags-im-uberblick) · WS-Ajax-"ID" · [WS-CTX](https://dokumentation.websale.de/v8s/referenz/tags/ws/shop-seite-und-technik.md#die-tags-im-uberblick) · [ST-Ajax](https://dokumentation.websale.de/v8s/referenz/tags/st/seitenzustand-und-navigation.md#die-tags-im-uberblick) · [WS-NoParsing](https://dokumentation.websale.de/v8s/referenz/tags/ws/shop-seite-und-technik.md#die-tags-im-uberblick)

### Schritt 5: Modul auf der Produktdetailansicht einbinden

Nur für den SEO-Modus. Das Tag `WS-Module(product_seo)` bindet das eben angelegte Template ein.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{ST-SeoMode}
   ~WS-Module(product_seo)~
{/ST-SeoMode}
```

> [!WARNING]
>
> Die `ST-SeoMode`-Klammerung ist zwingend. Ohne sie sehen auch Ihre Kunden die Eingabefelder.

Referenz: [ST-SeoMode](https://dokumentation.websale.de/v8s/referenz/tags/e-pseo.md) · [WS-Module()](https://dokumentation.websale.de/v8s/referenz/tags/ws/shop-seite-und-technik.md)

### Schritt 6: Die Felder im Template ausgeben

Dieser Schritt gilt für beide Pflegewege. Ausgegeben wird mit `PR-SeoFreeField1` bis `PR-SeoFreeField20`. Sinnvoll ist ein Rückfall auf die vorhandenen Produktdaten, solange ein Feld leer ist.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<head>
   ...
   <title>{PR-SeoFreeField1}~PR-SeoFreeField1~{/PR-SeoFreeField1}{!PR-SeoFreeField1}~PR-Name_StripHtml~{/!PR-SeoFreeField1}</title>
   <meta name="description" content="{PR-SeoFreeField2}~PR-SeoFreeField2~{/PR-SeoFreeField2}{!PR-SeoFreeField2}~PR-Descr_StripHtml~{/!PR-SeoFreeField2}">
   ...
</head>
```

> [!NOTE]
>
> Zum Ausprobieren können Sie die Ausgabe zunächst in `ST-DesignTest` klammern. Dann sehen nur Sie im Design-Testmodus, was die Felder liefern.
>
> ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
> {ST-DesignTest}{PR-SeoFreeField1}~PR-SeoFreeField1~{/PR-SeoFreeField1}{/ST-DesignTest}
> ```

Referenz: [PR-SeoFreeField1…20](https://dokumentation.websale.de/v8s/referenz/tags/e-pseo.md) · [PR-Name\_StripHtml](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md#die-tags-im-uberblick) · [PR-ShortDescr\_StripHtml](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md#die-tags-im-uberblick) · [ST-DesignTest](https://dokumentation.websale.de/v8s/referenz/tags/st/seitenzustand-und-navigation.md)

### Schritt 7: JavaScript-Bibliothek und Callback-Funktionen

Nur für den SEO-Modus. Das Formular sendet über `ws_AJAXsendFormTemplate`, deshalb müssen die WEBSALE Systembibliothek und die Design-Komponente auf der Produktdetailansicht eingebunden sein, mindestens in der Version 1.8.1.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<head>
   ...
   <script type="text/javascript" src="/$WS/ws_sysdata/js/ws-system-1.8.3.js"></script>
   <script type="text/javascript" src="../ihr-verzeichnis/ws-design-1.8.3.js"></script>
   ...
</head>
```

Ergänzen Sie die Design-Komponente um die vier Funktionen, die im `onclick` der Formulare genannt sind. Sie dürfen leer bleiben, müssen aber vorhanden sein.

```js theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
// vor dem Absenden, beispielsweise für eine Ladeanzeige
function seoStartFunction() {}

// nach erfolgreichem Speichern
function seoSuccessCallback() {}

// nach einem fachlichen Fehler beim Speichern
function seoErrorCallback() {}

// wenn die AJAX-Verbindung selbst fehlschlug
function seoFailureFunction() {}
```

Materialien: [WEBSALE JavaScript-Bibliothek](https://dokumentation.websale.de/v8s/materialien/websale-javascript-bibliothek.md)

### Schritt 8: Testen

Bei Pflege im TopRank-Manager: Legen Sie eine Datentabelle mit SEO-Content für einige Produkte an, laden Sie sie hoch und prüfen Sie die Ausgabe im Shop.

Bei Pflege im SEO-Modus:

1. Rufen Sie ein Produkt mit `?seomode=on` auf und melden Sie sich mit einem der hinterlegten Passwörter an.
2. Prüfen Sie, ob alle gewünschten Eingabefelder erscheinen.
3. Tragen Sie Inhalte ein, speichern Sie und prüfen Sie, ob die Eingaben danach noch in den Feldern stehen.
4. Verlassen Sie den SEO-Modus mit `?seomode=off`.

In beiden Fällen zum Schluss:

1. Haben Sie die Ausgabe in `ST-DesignTest` geklammert, rufen Sie das Produkt mit `?test=on&design-test=on` auf.
2. Prüfen Sie, ob die Inhalte an den vorgesehenen Stellen stehen und ob der sprechende Name in der Adresse erscheint.
3. Entfernen Sie die `ST-DesignTest`-Klammerungen, bevor Sie den Zugang an Ihre SEO-Verantwortlichen weitergeben.

Wegweiser: [Testmodi des Shops ein- und ausschalten](https://dokumentation.websale.de/v8s/domains/testmodi-des-shops-ein-ausschalten.md)

## Den SEO-Content pflegen

### Im TopRank-Manager

Die Liste wird mit tabulatorgetrennten Spalten angelegt. Die Zuordnung zum Produkt erfolgt über den Produktindex, die Zuordnung zum Subshop über die Subshop-ID. Über die Download-Funktion holen Sie den vorhandenen Stand zurück, bearbeiten oder löschen ihn und laden ihn erneut hoch. Den genauen Aufbau der Tabelle beschreibt der TopRank-Manager selbst.

Wegweiser: [TopRank konfigurieren und aktivieren](https://dokumentation.websale.de/v8s/seo/seo-optimierung-mit-toprank.md)

### Im SEO-Modus

Hängen Sie `?seomode=on` an einen beliebigen Shop-Aufruf an. Nach der Passworteingabe springt der Shop auf die ursprünglich aufgerufene Seite zurück und zeigt ab jetzt bei jedem Produkt die Eingabefelder. Mit `?seomode=off` verlassen Sie den Modus wieder.

Ohne aktive SEO-URLs sind gespeicherte Änderungen sofort wirksam. Mit aktiven SEO-URLs wirkt ein geänderter SEO-Produktname erst nach dem Generieren im TopRank-Manager.

## Verwandte Themen

* Wegweiser: [SEO-URLs und Link-Optimierung](https://dokumentation.websale.de/v8s/seo/seo-urls-und-link-optimierung.md)
* Wegweiser: Canonical-Anweisung im Head erzeugen
* Wegweiser: TopRank konfigurieren und aktivieren


## Related topics

- [SEO-Optimierung mit TopRank](https://dokumentation.websale.de/v8s/seo/seo-optimierung-mit-toprank.md)
- [E-PSEO_ (SEO-Content für Produkte)](https://dokumentation.websale.de/v8s/referenz/tags/e-pseo.md)
- [SEO-URLs und Link-Optimierung](https://dokumentation.websale.de/v8s/seo/seo-urls-und-link-optimierung.md)
- [Grundlagen und Technik](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/grundlagen-und-technik.md)
- [WEBSALE JavaScript-Bibliothek](https://dokumentation.websale.de/v8s/materialien/websale-javascript-bibliothek.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.