- - - By CrazyStat - - -

CMSimple_XH Dokumentation



— das kleine modulare Open-Source CMS ohne Datenbank

Sie sind hier: Startseite > Fachthemen > SEO > Techn-Optimierung

SEO - Technische Optimierung

In diesem Teil kommen wir nun zu einigen Punkten der Suchmaschinenoptimierung, die technischer Natur sind und teilweise auch nur indirekt beeinflusst werden können.

Erreichbarkeit, Leistung und Anbindung des Webservers

Antwort- und Ladezeiten haben einen nicht unerheblichen Anteil an der Gesamtbewertung für die Seite.
Bei der Auswahl des Hostinganbieters sollte man entweder auf eigene Erfahrungen oder wenigstens auf Erfahrungen oder Empfehlungen anderer Webseitenbetreiber zurückgreifen können. Hin und wieder findet man dazu auch mal einige Testberichte im Netz.

Fehlerfreier Quelltext und CSS

Besonders zu beachten bei der Erstellung des Templates und bei der Auswahl von Plugins. Bei der inhaltlichen Pflege kann man da eigentlich nur wenige Fehler machen, wenn man nicht gerade die HTML-Ansicht des Editors nutzt, oder Texte ungefiltert aus Word o.ä. einfügt.

Grundsätzlich ist das bei einem CMS fast immer ein Kompromiss. Ich jedenfalls habe es bei der Nutzung eines CMS noch nie hinbekommen, bei allen Seiten eine fehlerfreie Bewertung zu bekommen. Man sollte aber natürlich versuchen, bei den Bewertungen, so gut wie irgend möglich abzuschneiden. Also, so wenig Fehler wie irgend möglich.


Was kann man nun im Detail tun?

Angaben zur Sprache

Damit die Suchmaschinen auf entsprechende Suchanfragen reagieren können müssen sie klar zuordnen können, für welche Sprache(n) der Content geeignet ist. Das geschieht teilweise über die TLD, die Analyse des Inhalts hauptsächlich aber über die Angaben der Webseite selber.

Es gibt mehrere Möglichkeiten, die Sprache einer Webseite anzuzeigen. Diese grundsätzlichen Angaben sind bei der Erstellung des Templates zu beachten!
- einfachster Weg

<html lang="de">

- das Meta-Attribut

<meta http-equiv="content-language" content="de">

soll eigentlich keine Verwendung mehr finden. Ich glaube aber nicht, dass diese zusätzliche Angabe schaden kann (weiterführende Informationen dazu).

Zusätzlich kann die sprachliche Zuordnung bei Google über die Webmastertools (unter Website-Einstellungen, geographische Ausrichtung der Webseite) manuell festgelegt werden.

Bei mehrsprachigen Webseiten sollte es auf jeden Fall den oder die Verweise auf mögliche andere Sprachversion (hreflang) geben. Bei einsprachigen Webseiten, finde ich diese Angabe trotz allem auch "sinnvoll". Plugins dazu Polyglott_XH, xlang_XH

Doppelten Content vermeiden!

Wenn man CMSimple_XH in der Grundinstallation betreibt, kann man alle Seiten unter 4 verschiedenen URLs aufrufen.

- domain.tld/?irgendeine-seite
- domain.tld/index.php?irgendeine-seite
- domain.tld/?selected=irgendeine-seite
- domain.tld/index.php?selected=irgendeine-seite

Die Startseite sogar unter 6 verschiedenen URLs, mit einem leeren Parameter sogar unter 8 verschiedenen URLs.

- domain.tld/
- domain.tld/index.php
- domain.tld/?eureStartseite
- domain.tld/index.php?eureStartseite
- domain.tld/?selected=eureStartseite
- domain.tld/index.php?selected=eureStartseite

- domain.tld/?selected=
- domain.tld/index.php?selected=

Wobei letztere Zwei nicht wirklich relevant sind.
Ab Version 1.7.0 entfernt XH den Parameter selected selbst.
Das funktioniert genauso mit jedem beliebigen Paramter.

- domain.tld/?xbeliebig=
- domain.tld/index.php?xbeliebig=

Das lässt sich also nur schwerlich vermeiden.

Wenn der Webserver oder auch nur das Hostingpaket ungünstig konfiguriert ist, dann ist der Aufruf mit und ohne www. möglich und das Ganze verdoppelt sich sogar noch.

Also sollte man auf jeden Fall darauf achten, dass entweder die Einträge im Hostingpaket schon entsprechend gesetzt sind, damit die Seite entweder nur ohne oder nur mit www. zu erreichen ist bzw. entsprechend weitergeleitet wird (301). Oder man sollte eine entsprechende Regel in der eigenen .htaccess einrichten, die sich darum kümmert.
Wobei ich mit der Weile dafür bin, das www. wegzulassen.

Als Regel für die .htaccess (jeweils die zweite Zeile für http bzw. die dritte für https, entsprechend die # entfernen!)

#Umleitung auf www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
#RewriteRule ^(.*)$ http://www\.%{HTTP_HOST}/$1 [R=301,L]
#RewriteRule ^(.*)$ https://www\.%{HTTP_HOST}/$1 [R=301,L]
#Ende Umleitung auf www.

oder

#Umleitung ohne www.
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
#RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
#RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
#Ende Umleitung ohne www.

Mit einer weiteren Regel in der .htaccess kann man index.php aus der URL entfernen. (Auch hier wieder der Unterschied http oder https, entsprechend die # entfernen!)

#index.php wir aus URL entfernt
#RewriteRule ^([a-z]{2}/)?index\.php$ http://%{HTTP_HOST}/$1 [R=301,L]
#RewriteRule ^([a-z]{2}/)?index\.php$ https://%{HTTP_HOST}/$1 [R=301,L]
#Ende index.php wir aus URL entfernt

Den doppelten Aufruf der Startseite (domain.tld/ und domain.tld/?eureStartseite) kann man mit einem Kanonischen Link lösen (Plugin xlang_XH).

Den Parameter selected könnte man auch per Regel in der .htaccess entfernen. Das Entfernen ist nicht das Problem, aber das eigentliche Ziel des Parameters nicht zu zerstören.
Sobald es eine funktionierende Lösung gibt, wird diese hier nachgereicht.
Einstweilen kann man auch das mit einem Kanonischen Link lösen, den man ebenfalls wieder mit dem Plugin xlang_XH setzen lassen kann.

SSL (https)

Wenn ein Zertifikat vorhanden ist, dann sollte man per .htaccess dafür sorgen, dass auch wirklich alle Zugriffe per https erfolgen.
Einmal, damit das Zertifikat auch wirklich seinen Sinn erfüllt, und zum Anderen würde man sonst eine weitere Möglichkeit für Duplicate Content schaffen, da die Seiten dann unter http://... und https://... abrufbar wären.
Eine entsprechende Regel dazu könnte so aussehen:

#SSL ein
RewriteCond %{HTTPS} =off
RewriteCond %{REQUEST_URI} !^/(robots\.txt) [NC]
RewriteCond %{query_STRING} !^(sitemapper_index|sitemapper_sitemap)(.*)$ [NC]
#
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
Header set Strict-Transport-Security "max-age=604800" env=HTTPS
#Ende SSL ein

Ich habe robots.txt und die Ausgaben von Sitemapper_XH noch ausgenommen. Das könnt ihr also durchaus auch weglassen.
Ob das sinnvoll oder nötig ist???
Die letzte Zeile ist auch nicht zwingend notwendig.
Zur Erklärung: Webseiten, die ausschließlich per HTTPS angesprochen werden wollen, fügen in Ihre Server-Antworten einen HSTS-Header (HTTP Strict Transport Security) mit ein. Der Browser merkt sich von welchen Servern/Webseiten er HSTS-Header bekommen hat und weigert sich zukünftig, diese per HTTP anzusprechen. Da sich das natürlich auch mal ändern kann, wird noch eine Time-to-live -Info mitgegeben, in diesem Fall 7 Tage. Man könnte aber auch 1 Jahr oder 2 Jahre setzen. Aber zu lange finde ich wenig sinnvoll, denn der Server würde dem Browser auch 1 Tag vor Ablauf des Zertifikates mitteilen, dass es die nächsten 1 oder 2 Jahre nur SSL gibt. Ich denke eine kürzere Zeitspanne ist hier der bessere Weg.

Auf das Notwendigste reduziert müsste die Regel für https also eigentlich nur:

#SSL ein
RewriteCond %{HTTPS} =off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
#Ende SSL ein

lauten.

Verschobene oder gelöschte Seiten

Es wird immer Situationen geben, in denen Seiten innerhalb der Struktur der Webseite verschoben werden, in denen Seiten gelöscht oder wenigstens offline gesetzt werden, weil Inhalte nicht mehr aktuell sind, oder in denen sich einfach die Überschrift ändert, und damit bei CMSimple_XH natürlich auch die URL.

Nun ist es so, dass die Suchmaschine das ganz allein merkt und auch den Besuchern wird es kaum verborgen bleiben. Schön ist aber anders. Bei der Suchmaschine verliert ihr unter Umständen ein gutes Ranking, weil sich die URL der Seite geändert hat und alle bisherige Arbeit in dieser Richtung war umsonst. Als Besucher einer Webseite ist man auch nicht gerade begeistert, wenn man über eine Suchmaschine oder Bookmark auf eine Seite kommt und es wird einem ein Fehler 404 präsentiert.
Eine schön gestaltete Fehlerseite kann da den Besucherfrust etwas mildern, aber zielführend ist das nicht.

Auch hier kann man per .htaccess Regeln erstellen, die solche Seiten entsprechend umleiten. Das könnte so aussehen:

RewriteCond %{query_STRING} ^(Level-H1--Level-H2)$ [NC]
RewriteRule ^$ https://domain.tld/\?Neue-H1--Neue-H2 [R=301,L]

Mit dieser Regel würde der Aufruf der Seite

- https://domain.tld/?Level-H1--Level-H2

auf

- https://domain.tld/?Neue-H1--Neue-H2

weitergeleitet.

Bleibt die Seite unter der gleichen Domain funktioniert auch:

RewriteCond %{query_STRING} ^(Level-H1--Level-H2)$ [NC]
RewriteRule ^$ https://%{HTTP_HOST}/\?Neue-H1--Neue-H2 [R=301,L]

Das Beispiel geht von SSL (https) aus.
Der Besucher wäre zufrieden gestellt und die Suchmaschine erfährt durch die 301, dass es sich um eine permanente Weiterleitung handelt und wird den Index anpassen.

Alternativ zu diesen manuellen Eintragungen in die .htaccess kann man das Plugin Moved_XH verwenden.

Für dauerhaft gelöschte Seiten empfiehlt es sich, statt dem Status 404 (Die angeforderte Ressource wurde nicht gefunden) den Status 410 (Die angeforderte Ressource wird nicht länger bereitgestellt und wurde dauerhaft entfernt) zu verwenden.
Das vermittelt dem Besucher und den Suchmaschinen, dass es sich nicht um ein vorübergehendes Problem oder ein Versehen handelt, sondern so gewollt ist und auch so bleiben wird.

Eine Regel in der .htaccess würde so aussehen:

für eine Datei / URL (statisch)

Redirect Gone /geloeschte-ressource.html

oder für Verzeichnisse

Redirect Gone /verzeichnis

Bei CMSimple-Seiten ist es wieder etwas aufwendiger.
Für die Seite domain.tld/?irgendeineseite wäre die Regel:

RewriteCond %{query_string} ^(irgendeineseite)$
RewriteRule .* - [R=410,L]

Wer noch etwas Feinschliff in die Sache bringen möchte, der kann dazu eigene Fehlerseiten erstellen. Das sieht allemal besser aus, als die Standardmeldungen der Server.
Die einzelnen Fehlerseiten den Fehlern zuzuordnen läuft auch über die .htaccess und könnte so aussehen:

ErrorDocument 403 /fehler/fehler403.htm
ErrorDocument 404 /fehler/fehler404.htm
ErrorDocument 410 /fehler/fehler410.htm

oder, wer die Seiten, als versteckte Seiten in CMSimple_XH anlegen will:

ErrorDocument 403 /?Error_403
ErrorDocument 404 /?Error_404
ErrorDocument 410 /?Error_410

Allerdings kann es hier, je nach Verzeichnistiefe, z.B. Zweitsprache, zu unerwünschten Effekten beim Layout kommen.

Alle bis hierher beschriebenen Regeln, bis auf die Zuweisung der eigenen Fehlerseiten, funktionieren natürlich nur, wenn der Server mod_rewrite unterstützt.
Vor diesen Regeln, wenn nicht schon vorhanden muss:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

und nach diesen Regeln, wenn nicht schon vorhanden:

</IfModule>

RewriteBase muss eventuelle angepasst werden, wenn ihr die Seite z.B. mit domain.tld/unterordner/ aufruft.
Dann wäre RewriteBase /unterordner/.

Als gesamte Beispielkonfiguration, ohne www., mit SSL und ohne Unterordner würde das so aussehen:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

#Umleitung ohne www.
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
#RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
#Ende Umleitung ohne www.

#SSL ein
RewriteCond %{HTTPS} =off
RewriteCond %{REQUEST_URI} !^/(robots\.txt) [NC]
RewriteCond %{query_STRING} !^(sitemapper_index|sitemapper_sitemap)(.*)$ [NC]
#
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
Header set Strict-Transport-Security "max-age=604800" env=HTTPS
#Ende SSL ein

#index.php wir aus URL entfernt
#RewriteRule ^([a-z]{2}/)?index\.php$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^([a-z]{2}/)?index\.php$ https://%{HTTP_HOST}/$1 [R=301,L]

#Ende index.php wir aus URL entfernt

</IfModule>

Caching und Komprimierung per .htaccess

Weitere mögliche Verbesserungen der Performance einer Webseite sind das Browsercaching und die Komprimierung.

Beides kann man, so die entsprechenden Module des Webservers aktiviert sind per .htaccess für die Webseite aktivieren und steuern.

Ich beschränke mich hier auf eine Beispielkonfiguration. Da ist durchaus Spielraum für Anpassungen vorhanden.

Für das Caching mit einer Lifetime von 7 Tagen:

#Caching
FileETag MTime Size
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/gif "access plus 7 days"
ExpiresByType image/ico "access plus 7 days"
ExpiresByType image/jpeg "access plus 7 days"
ExpiresByType image/jpg "access plus 7 days"
ExpiresByType image/png "access plus 7 days"
ExpiresByType text/css "access plus 7 days"
ExpiresByType text/javascript "access plus 7 days"
ExpiresByType application/x-javascript "access plus 7 days"
ExpiresByType application/javascript "access plus 7 days"
</IfModule>

Für die Komprimierung:

#Komprimierung
<IfModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file \.(html?|txt|css|js)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</IfModule>

oder:

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-shockwave-flash
</IfModule>

Welche Module nun bei euch aktiviert sind, müsst ihr einfach ausprobieren. Durch die Abfrage <IfModule ... gibt es keine Serverfehler 500. Wenn das Modul nicht installiert ist, dann passiert einfach gar nichts.

Das Ergebnis könnt unter:
https://developers.google.com/speed/pagespeed/insights/
testen.

robots.txt (Robots Exclusion Protocol)

Die robots.txt ist eine reine Textdatei und liegt im Root der Webseite, um die Bots der Suchmaschinen anzuweisen, welche Teile durchsucht und welche möglicherweise nicht durchsucht und eben nicht in den Index aufgenommen werden sollen.

Diese Datei ist kein geeignetes Mittel um Dateien vor unberechtigten Zugriffen zu schützen.
Außerdem muss man auch davon ausgehen, dass sich nicht alle Bots an diese Anweisungen halten.
Man kann sie also eher als Richtlinie sehen.

Als Beispiel, robots.txt für CMSimple_XH

User-agent: *
Disallow: /cmsimple/
Disallow: /content/
Disallow: /core/js/ (ab Version 1.7.0 /assets/js/)
Disallow: /userfiles/media/

Disallow: /googlexxxxxxxxxxxxxxx.html

Disallow: /*.txt$
Disallow: /*.htm$
Disallow: /*.html$
Disallow: /*.nfo$
Disallow: /*.inc$
Disallow: /*.frm$
Disallow: /*.tpl$
Disallow: /*.bak$
Disallow: /*.csv$
Disallow: /*.sla$
Disallow: /*.log$
Disallow: /*.tpl$
Disallow: /*.ini$
Disallow: /*.sql$
Disallow: /*.md$
Disallow: /*.cf$
Disallow: /*.dat$

Sitemap: https://domain.tld/?sitemapper_index

Es sind einige Verzeichnisse, die Authentifizierungsdatei für die Google-Webmastertools und eine Reihe von Dateitypen ausgenommen. Der Eintrag Sitemap verweist in dem Fall auf die von dem Plugin Sitemaper_XH erstellte Sitemap.

Mindestens dem Googlebot sollte man den Abruf von CSS- und Javascript-Dateien erlaubt – andernfalls droht ein schlechteres Ranking.
Womit der Eintrag Disallow: /core/js/ schon wieder fraglich ist. Wer also sichergehen will, der sollte diesen Eintrag lieber weglassen!

Überschriften-Struktur

!!! Dieser Punkt hat nur bis Version 1.6.10 Gültigkeit. !!!

Im Standard ist es mit CMSimple_XH nicht möglich, eine konforme Struktur der Überschriften zu erreichen. Ganz klar, da H1 bis H3 die Seitenstruktur darstellen.
Um die richtige Überschriftenstruktur in CMSimple_XH zu erhalten (H1 - H2 - H3 - H4) gibt es folgenden Workaround von Svasti.

Durch die veränderte Ausgabe, bekommt man eine stimmige Überschriftenstruktur.

Ich habe das Ganze so erweitert, das ich wirklich bis H6 alles erfasst habe. Aus H1, und H3 wird H2, H2 bleibt wie es ist, aus H4 wird H3 und aus H5 und H6 wird H4.
H1 habe ich nicht wie von Svasti vorgeschlagen
(<h1><?php echo sitename();?></h1>)
mit dem Seitennamen belegt, sondern mit einem Template-Text
(<h1><?php echo $tx['template']['textx'];?></h1>).
So kann ich im Backend die Überschrift anpassen, ohne dabei den Seitennamen zu ändern und dadurch vielleicht einen zu langen Namen mit zu vielen Füllwörtern zu erhalten.
Aber da ist der Kreativität keine Grenze gesetzt.

Diese Dokumentation wurde unter CC BY-NC-ND 3.0 DE Lizenz erstellt.

Autor: Olaf Penschke