LinkShorter v2 – Ausführliche Anleitung
LinkShorter is a self-hosted URL shortening tool that lets you create short, shareable links, protect them with passwords, set expiration rules, generate QR codes, and track click statistics. Below is a step-by-step guide covering every feature.
1. Logging InInhaltsverzeichnis
OpenÜberblickyour&browser and go to your LinkShorter URL (e.g.https://link.fabula.vision/).ArchitekturYouInstallationwill&see a login screen withUsernameandPasswordfields.KonfigurationEnterDasthe credentials your administrator set up, then clickLogin.Admin-DashboardAfterLinksaerstellensuccessful&loginverwalten
2.1. TheÜberblick Dashboard& Architektur
TheLinkShorter dashboardist isein theselbstgehosteter mainURL-Shortener, screen.der Itvollständig hasin threePHP areas:geschrieben ist und eine SQLite-Datenbank verwendet – es wird also kein MySQL/MariaDB-Server benötigt. Die gesamte Anwendung besteht aus einer einzigen Einstiegsdatei (index.php), die als Front-Controller fungiert: Alle HTTP-Requests werden über die .htaccess per mod_rewrite an diese Datei weitergeleitet.
Technische
3. Creating a Short Link
In the "Shorten a Link" card at the top of the dashboard:
|
||
|
||
Datenfluss bei einem Kurzlink-Aufruf
Browser → Apache (.htaccess Rewrite)
→ index.php?route=mein-slug
→ getLinkBySlug("mein-slug")
→ Prüfung: aktiv? abgelaufen? Passwort? Crawler?
→ recordClick() → HTTP 302 Redirect → Ziel-URL
2. Installation & Konfiguration
Voraussetzungen
pdo_sqlite, gd (für PNG-QR-Codes), mbstring
Apache mit mod_rewrite aktiviert
Schreibrechte auf das Verzeichnis data/
Schritt 1: Dateien hochladen
ClickLaden Sie alle Dateien auf Ihren Webserver hoch. Die Verzeichnisstruktur sollte so aussehen:
/
├── index.php
├── config.php
├── .htaccess
├── assets/
│ ├── style.css
│ └── app.js
├── includes/
│ ├── db.php
│ ├── auth.php
│ ├── slug.php
│ ├── links.php
│ ├── opengraph.php
│ └── qrcode.php
├── templates/
│ ├── dashboard.php
│ ├── edit.php
│ ├── login.php
│ ├── stats.php
│ ├── settings.php
│ ├── password.php
│ ├── og_proxy.php
│ ├── unavailable.php
│ └── 404.php
└── data/ ← wird automatisch erstellt
├── linkshorter.db
├── qr_cache/
└── qr_icon.svg
Schritt 2: Konfiguration anpassen
Öffnen Sie config.php und passen Sie die Werte an:
<?php
define('ADMIN_USERNAME', 'admin'); // Ihr gewünschter Benutzername
define('ADMIN_PASSWORD', 'IhrSicheresPasswort'); // UNBEDINGT ÄNDERN!
define('BASE_URL', 'https://kurz.example.com/'); // Ihre Domain mit abschließendem /
define('DB_PATH', __DIR__ . '/data/linkshorter.db');
define('SITE_TITLE', 'LinkShorter');
define('QR_ICON_PATH', __DIR__ . '/data/qr_icon.svg');
Technischer Hintergrund: Die Konstanten werden mit define() festgelegt und sind damit Create Short Linkglobal whenin youallen areinkludierten done.Dateien Averfügbar. greenADMIN_PASSWORD successwird messageim willKlartext appeargespeichert containing– youres newwird shortnicht URLgehasht, da es bei jedem Login direkt verglichen wird (e.g.in attemptLogin). Dies ist ein bewusster Trade-off für Einfachheit bei einer Single-User-Anwendung.
Schritt 3: Erster Aufruf
Beim ersten Aufruf von https:// erstellt getDB automatisch:link.fabula.vision/my-linkkurz.example.com/
data/-Verzeichnis
Die SQLite-Datenbank mit den Tabellen links, clicks und settings
Die Funktion nutzt WAL-Modus (PRAGMA journal_mode=WAL)., Youwas canparallele nowLese- shareund thatSchreibzugriffe URL.ermöglicht und die Performance bei gleichzeitigen Zugriffen deutlich verbessert.
3. Das Admin-Dashboard
Login
Rufen Sie https://kurz.example.com/ auf. Sie werden zum Login weitergeleitet, da die Route ?page=login aktiv wird. Die Authentifizierung funktioniert session-basiert:
$_SESSION['logged_in'] = true gesetzt
Alle geschützten Seiten prüfen via requireLogin, ob die Session gültig ist
Dashboard-Oberfläche
Nach dem Login sehen Sie das Dashboard (dashboard.php) mit:
Technischer Hintergrund zur Sortierung: Die Funktion getAllLinks baut die SQL-Query dynamisch zusammen. Erlaubte Spalten sind in einem Whitelist-Array definiert, um SQL-Injection zu verhindern:
$allowed = ['slug', 'url', 'clicks', 'created_at', 'active'];
if (!in_array($sort, $allowed)) $sort = 'created_at';
Die Sortierrichtung wird ebenfalls validiert (ASC oder DESC), bevor sie in die Query eingebaut wird.
4. Batch Import (Creating Many Links aterstellen Once)& verwalten
Einzelnen Link erstellen
- Geben
OnSiethe dashboard, click thedieBatch ImportZiel-URLbuttoneinnext to "Create Short Link".(Pflichtfeld) - Optional:
ACustompop-upSlugwindow–appearswirdwithautomatischabereinigtlarge(nurtexta-zA-Z0-9_-box.erlaubt) - Optional: Passwort – wird mit
password_hash()als bcrypt-Hash gespeichert
datetime-local
Optional: Max Clicks – nach Erreichen wird der Link deaktiviert
PasteTechnischer yourHintergrund URLszur —Slug-Generierung: oneWenn URLkein perCustom line,Slug forangegeben example:wird, generiert generateSlug einen 6-Zeichen-Code. Der Algorithmus ist bewusst kryptographisch robust:
https://example.com/page1Eingabe https://example.com/page2= https://example.com/page3microtime() + random_bytes(8) + Versuchszähler
↓
SHA-256 Hash
↓
6 Zeichen aus dem Zeichensatz [a-zA-Z0-9] extrahiert
↓
Kollisionsprüfung gegen Datenbank (max 100 Versuche)
Die Kombination aus microtime() (Zeitstempel mit Mikrosekunden) und random_bytes() (kryptographisch sichere Zufallsbytes) macht Kollisionen extrem unwahrscheinlich. Bei 62 möglichen Zeichen pro Position ergibt ein 6-Zeichen-Slug 62⁶ ≈ 56,8 Milliarden mögliche Kombinationen.
Batch-Import
Klicken Sie auf „Batch Import" im Dashboard. Es öffnet sich ein Modal-Dialog, in dem Sie eine URL pro Zeile eingeben können. batchCreateLinks verarbeitet jede Zeile einzeln:
Clickvia Createfilter_var($url, All.
ASlug-Generierung resultsfür tablejede willURL
Link bearbeiten
Auf der Edit-Seite (edit.php) können Sie alle Eigenschaften eines Links ändern. Besonders interessant ist die
Note:Passwort-VerwaltungBatch-importedmitlinksdreido not get custom slugs, passwords, or expiration — those can be set afterwards by editing each link.
5. Searching and Sorting Links
6. Managing a Link
Each row in the links table has a set of action buttons:Optionen:
password_action |
|---|
keep
password $data change
remove
password '' null
Technischer Hintergrund: In updateLink wird die OpenGraph-Daten-Aktualisierung nur ausgelöst, wenn sich die URL geändert hat. Das verhindert unnötige HTTP-Requests an die Ziel-URL:
$og = ($url !== $link['url']) ? fetchOpenGraph($url) : [
'og_title' => $link['og_title'],
'og_description' => $link['og_description'],
'og_image' => $link['og_image'],
];
Link löschen
Das Löschen erfolgt via POST-Request mit einer JavaScript-Bestätigung. Dank ON DELETE CASCADE in der Datenbank-Schema-Definition werden zugehörige Click-Datensätze automatisch mitgelöscht.
7.5. EditingPasswortgeschützte a LinkLinks
OnWenn theein editLink pagemit youPasswort canversehen change:ist, zeigt der Server die Seite password.php an. Der Ablauf:
Besucher → /mein-slug
→ getLinkBySlug() findet Link mit password ≠ null
→ GET-Request: Zeige Passwort-Formular
→ POST-Request mit link_password:
→ password_verify(eingabe, hash) → true: recordClick + Redirect
→ false: Fehlermeldung
Wichtig: Das Passwort wird immer als bcrypt-Hash gespeichert (password_hash($password, PASSWORD_DEFAULT)). Beim Vergleich wird password_verify() verwendet, was automatisch den Salt aus dem Hash extrahiert. Das bedeutet: Selbst wenn die Datenbank kompromittiert wird, sind die Link-Passwörter nicht im Klartext einsehbar.
6. QR-Codes
LinkShorter enthält eine vollständig eigene QR-Code-Implementierung – es werden keine externen APIs oder Libraries benötigt.
Technischer Tiefgang: QR-Code-Generierung
Die Funktion qrEncode implementiert den kompletten QR-Code-Standard:
Versionswahl: Basierend auf der Datenlänge wird die minimale QR-Version (1–40) bestimmt. Version 1 hat 21×21 Module, Version 40 hat 177×177 Module. Die Kapazitätstabelle $capacityL enthält die maximale Byte-Kapazität für Error Correction Level L (Low, ~7% Fehlerkorrektur).
Matrix-Aufbau:
URLplaceFinderPattern:—Dreithe7×7-ErkennungsmusterdestinationinthedenshortEckenlink(oben-links,pointsoben-rechts,to.unten-links)SlugTiming-Patterns:—AbwechselndetheModuleshortincode.ZeileChanging6itundchangesSpalteyour short URL.6PasswordplaceAlignmentPattern:—AbchooseVersionfrom:2KeepAusrichtungsmustercurrentplatziert (don'tPositionenchangeausanything)
Expires AtDatenkodierung —(encodeData):
0100 (Byte-Modus)
Zeichenzähler: 8 Bit (Version 1–9) oder 16 Bit (ab Version 10)
Daten als 8-Bit-Bytes
Padding mit 0xEC 0x11 (abwechselnd)
Reed-Solomon-Fehlerkorrektur via generateECCodewords
Galois-Feld-Arithmetik: Für die Fehlerkorrektur werden Berechnungen im GF(2⁸) durchgeführt. Die Funktionen gfMultiply, gfExp und gfLog implementieren die Multiplikation über das irreduzible Polynom 0x11D (x⁸ + x⁴ + x³ + x² + 1).
Data-Interleaving: Bei mehreren Blöcken werden die Daten- und EC-Codewords interleaved (verschachtelt), um Burst-Fehler besser zu korrigieren.
Maskierung: Alle 8 Maskmuster werden getestet. calculatePenalty berechnet die Strafpunkte nach vier Regeln:
Das Mask-Pattern mit der niedrigsten Penalty wird gewählt.
Ausgabeformate
imagecreatetruecolor), mit optionalem Center-Icon via ImageMagick (convert-Befehl)
SVG (getQRCodeSVG): Reine XML-Generierung, Icon wird als eingebettetes SVG eingefügt
Caching
Beide Formate werden im Verzeichnis data/qr_cache/ gecacht (24 Stunden TTL). Der Cache-Key ist ein MD5-Hash aus Daten + Größe + Format.
Custom Icon
Unter Settings können Sie ein SVG-Icon hochladen (admin/action mit action=upload_icon), das im Zentrum aller QR-Codes angezeigt wird. Beim Upload wird der QR-Cache geleert, damit die neuen QR-Codes das Icon enthalten.
7. OpenGraph-Proxying
Wenn ein Kurzlink in sozialen Netzwerken geteilt wird, erkennt LinkShorter den Crawler anhand des User-Agents:
$isCrawler = preg_match(
'/facebookexternalhit|Twitterbot|LinkedInBot|WhatsApp|Slackbot|TelegramBot|Discordbot|bot|crawler|spider/i',
$ua
);
Statt den Crawler weiterzuleiten, wird og_proxy.php ausgeliefert – eine minimale HTML-Seite mit den OpenGraph-Meta-Tags der Ziel-URL. Das bewirkt, dass in der Vorschau (z.B. auf Facebook, Twitter, Slack) das Bild, der Titel und die Beschreibung der Original-Seite angezeigt werden, obwohl der geteilte Link eine kurze URL ist.
Technischer Hintergrund: fetchOpenGraph extrahiert beim Erstellen eines Links die Meta-Daten:
DOMDocument
Extraktion von og:title, og:description, og:image
Fallback auf <title>-Tag, wenn kein og:title vorhanden
Die SSL-Verifikation ist bewusst deaktiviert (verify_peer => false), um Probleme mit selbstsignierten Zertifikaten zu vermeiden. In Produktionsumgebungen sollte das ggf. angepasst werden.
Wichtig: Das OpenGraph-Proxying funktioniert auch für passwortgeschützte Links – Crawler erhalten die Vorschau, ohne ein Passwort eingeben zu müssen. Normale Benutzer werden weiterhin nach dem Passwort gefragt.
8. Statistiken & Click-Tracking
Was wird erfasst?
Bei jedem erfolgreichen Redirect (auch nach Passworteingabe) ruft recordClick zwei Datenbankoperationen aus:
links-Tabelle
Detaillierter Click-Eintrag in der clicks-Tabelle:
ip: IP-Adresse des Besuchers ($_SERVER['REMOTE_ADDR'])
user_agent: Browser-Kennung
referer: Woher der Besucher kam
clicked_at: Zeitstempel (automatisch via SQLite datetime('now'))
Stats-Seite
Die Stats-Seite (stats.php) zeigt:
Click Save Changes when finished.
The edit page also shows:
8. QR Codes
Every link automatically gets a QR code. You can access it two ways:
Download formats:
If your administrator has uploaded a center icon (see Settings), it will appear in the middle of every QR code.
9. Click Statistics
Click the Stats button on any link to see:
-IfDie theAbfrage linkin isgetClickStats currentlyist inactive,auf a100 ReactivateEinträge buttonlimitiert appears(LIMIT ), to100turnum itbei backviel-geklickten on.Links die Performance zu gewährleisten.
Link-Deaktivierung
Ein Link wird automatisch als „nicht verfügbar" angezeigt, wenn:
active = 0 (manuell deaktiviert)
max_clicks erreicht wurde (clicks >= max_clicks)
expires_at in der Vergangenheit liegt
In allen drei Fällen wird unavailable.php angezeigt.
10.9. Settings
Die Click Settings in the top navigation bar.
QR Code Center Icon
You can upload a small logo (in SVG format only) that will be placed in the center of all generated QR codes:
.svgIf an icon is already uploaded, a small preview is shown.
Configuration Info
The settings page also displays read-only information:
11. What Visitors See
12. Automatic Expiration (Cron)
Links with an "Expires At" date are not deactivated in real time — they are checked when a special URL is called:
https://link.fabula.vision/cron
To make this run automatically, ask your hosting provider or administrator to set up a cron job (a scheduled task) that visits this URL periodically, for example every 5 minutes. This ensures expired links are deactivated promptly.
If you don't set up a cron job, expired links will still show the "No longer available" page to visitors (the expiration is checked at click time too), but they will remain listed as "Active" in your dashboard until the cron URL is called.
13. REST-API (for Advanced Users or Integrations)
LinkShorter providesbietet twozwei APIAPI-Endpunkte, endpointsdie thatmit externalHTTP toolsBasic orAuthentication browsergeschützt extensions can use:sind.
CheckPOST Connection/api/shorten
Erstellt einen neuen Kurzlink.
Request:
GETPOST https://link.fabula.vision/api/checkshorten HTTP/1.1
Authorization: Basic (your credentials)
Returns {"status":"ok","title":"LinkShorter"} if the credentials are correct.
Create a Short Link
POST https://link.fabula.vision/api/shorten
Authorization: Basic (your credentials)base64(username:password)
Content-Type: application/json
{
"url": "https://example.com/long-sehr-lange-url",
"slug": "optional-custom-slug"custom", // optional
"password": "optional-password"geheim", // optional
"expires_at": "2025-12-31T23:59", // optional
"max_clicks": 100 // optional
}
ReturnsResponse (Erfolg):
{ "short_url": "https://link.fabula.vision/abc123"kurz.example.com/custom", "slug": "abc123"custom" }on success.
BasicResponse authentication(Fehler):
{
"error": "Slug already exists"
}
GET /api/check
Prüft die Erreichbarkeit und Authentifizierung einer Instanz. Wird von der Chrome-Extension beim Hinzufügen einer neuen Instanz verwendet.
Response:
{
"status": "ok",
"title": "LinkShorter"
}
Technischer Hintergrund
Die Authentifizierung wird im index.php inline geprüft:
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (preg_match('/^Basic\s+(.+)$/i', $authHeader, $m)) {
$decoded = base64_decode($m[1]);
list($user, $pass) = explode(':', $decoded, 2);
// Vergleich mit ADMIN_USERNAME und ADMIN_PASSWORD
}
Hinweis: meansApache yourkann usernameden andAuthorization-Header passwordmanchmal arenicht sentan encodedPHP withweiterleiten. everyIn request.diesem MostFall HTTPmuss tools (Postman, cURL, browser extensions) have a built-in "Basicder Auth".htaccess optionfolgende —Zeile justergänzt enter your LinkShorter username and password.werden:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
14.10. QuickDie ReferenceChrome-Extension
Überblick
Die Chrome-Extension ermöglicht es, die aktuelle Tab-URL mit einem Klick zu kürzen, ohne das Dashboard öffnen zu müssen. Sie unterstützt mehrere LinkShorter-Instanzen, was nützlich ist, wenn man verschiedene Domains für verschiedene Zwecke nutzt.
Installation
Navigieren Sie in Chrome zuchrome://extensions/
Aktivieren Sie den Entwicklermodus (oben rechts)
Klicken Sie „Entpackte Erweiterung laden"
Wählen Sie den Ordner chrome-extension/
Dateien der Extension
Instanz hinzufügen
Technischer Hintergrund: Beim Hinzufügen wird zunächst ein GET /api/check ausgeführt, um die Verbindung und Authentifizierung zu testen. Erst wenn {"status": "ok"} zurückkommt, wird die Instanz gespeichert. Die Instanzen werden in chrome.storage.sync gespeichert, was bedeutet, dass sie über mehrere Chrome-Installationen hinweg synchronisiert werden (wenn der Nutzer in Chrome eingeloggt ist).
URL kürzen
Navigieren Sie zur gewünschten Webseite Klicken Sie auf das LinkShorter-Icon in der Toolbar Die aktuelle Tab-URL wird automatisch eingetragen (viachrome.tabs.query)
Optional: Wählen Sie eine andere Instanz oder geben Sie einen Custom Slug ein
Klicken Sie „Shorten"
Die verkürzte URL erscheint mit Copy-Button
Berechtigungen
Die Extension benötigt nur zwei Berechtigungen (manifest.json):
activeTab: Zugriff auf die URL des aktiven Tabs
storage: Speichern der Instanz-Konfigurationen
Es werden keine Host-Permissions benötigt, da fetch() in Manifest V3 standardmäßig CORS-Requests durchführen darf (die API-Endpunkte müssen allerdings CORS erlauben oder die Extension muss die Requests direkt an die URL senden).
11. Automatische Link-Expiration (Cron)
Einrichtung
Der Endpunkt /cron deaktiviert alle abgelaufenen Links. Die Funktion expireLinks führt folgendes SQL aus:
UPDATE links SET active = 0
WHERE expires_at IS NOT NULL
AND expires_at <= datetime('now')
AND active = 1
Cron-Job einrichten
Fügen Sie in Ihrer Crontab folgenden Eintrag hinzu (z.B. alle 5 Minuten):
*/5 * * * * curl -s https://kurz.example.com/cron > /dev/null 2>&1
Alternativ via PHP-CLI:
*/5 * * * * php /var/www/html/index.php route=cron > /dev/null 2>&1
Die Antwort ist ein JSON-Objekt: {"expired": 3} – die Anzahl der gerade deaktivierten Links.
Hinweis: Der Cron-Endpunkt ist nicht authentifiziert. Er führt jedoch nur eine Statusänderung durch (aktiv → inaktiv) und gibt keine sensiblen Daten zurück. Wenn Sie das absichern möchten, können Sie einen API-Key prüfen oder den Zugriff per .htaccess einschränken.
Wichtig: Auch ohne Cron werden abgelaufene Links beim Aufrufen als „nicht verfügbar" angezeigt, da die Prüfung strtotime($link['expires_at']) <= time() direkt in der Routing-Logik stattfindet. Der Cron-Job sorgt lediglich dafür, dass der active-Status in der Datenbank korrekt gesetzt wird (relevant für die Dashboard-Anzeige).
12. Sicherheitshinweise
Passwort in config.php
Das Admin-Passwort in config.php steht im Klartext. Stellen Sie sicher, dass:
hackme123!)
Datenbankschutz
Die .htaccess blockiert den direkten Zugriff auf .db- und .sqlite-Dateien:
<FilesMatch "\.db$">
Require all denied
</FilesMatch>
XSS-Schutz
Alle Benutzereingaben werden in den Templates mit htmlspecialchars() escaped, z.B.:
<?= htmlspecialchars($link['slug']) ?>
SQL-Injection-Schutz
Alle Datenbankabfragen verwenden Prepared Statements mit Paramter-Binding:
$stmt = $db->prepare('SELECT * FROM links WHERE slug = ?');
$stmt->execute([$slug]);
Die einzige Ausnahme ist die dynamische ORDER BY-Klausel in getAllLinks, die aber über ein Whitelist-Array abgesichert ist.
CSRF-Schutz
Aktuell gibt es keinen CSRF-Token-Schutz. Da die Anwendung nur einen einzigen Admin-User hat, ist das Risiko begrenzt, aber bei einer Erweiterung sollte ein Token-System implementiert werden.
13. Technische Architektur im Detail
Routing-System
Das Routing in index.php funktioniert als Kaskade von if-Statements:
Eingang: $_GET['route'] (via .htaccess Rewrite)
↓
1. Exakte Routen: 'cron', 'api/shorten', 'api/check', 'admin/action'
↓
2. QR-Routen: 'qr/png', 'qr/svg', 'qr/png/download', 'qr/svg/download'
↓
3. Slug-Auflösung: Beliebiger Pfad → getLinkBySlug()
↓
4. Seiten-Routing: $_GET['page'] → login, dashboard, edit, stats, settings
Datenbank-Schema
links (
id INTEGER PRIMARY KEY AUTOINCREMENT,
slug TEXT UNIQUE NOT NULL, -- Der Kurzlink-Code
url TEXT NOT NULL, -- Ziel-URL
password TEXT DEFAULT NULL, -- bcrypt-Hash oder NULL
expires_at TEXT DEFAULT NULL, -- ISO-8601 Ablaufzeit
max_clicks INTEGER DEFAULT NULL, -- Klick-Limit
clicks INTEGER DEFAULT 0, -- Aktueller Zähler
active INTEGER DEFAULT 1, -- 1 = aktiv, 0 = deaktiviert
og_title TEXT, -- OpenGraph-Cache
og_description TEXT,
og_image TEXT,
created_at TEXT, -- datetime('now')
updated_at TEXT
)
clicks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
link_id INTEGER NOT NULL, -- FK → links.id
ip TEXT,
user_agent TEXT,
referer TEXT,
clicked_at TEXT -- datetime('now')
FOREIGN KEY (link_id) REFERENCES links(id) ON DELETE CASCADE
)
settings (
key TEXT PRIMARY KEY,
value TEXT -- Aktuell nicht aktiv genutzt
)
Frontend-JavaScript
app.js ist bewusst minimal und framework-frei:
active auf dem Overlay
QR-Modal: Dynamisches Setzen der src- und href-Attribute basierend auf dem Slug
Slug-Preview: Live-Aktualisierung beim Tippen mit Regex-Filterung
Copy-Button: Via navigator.clipboard.writeText() mit visueller Bestätigung
Delete-Confirmation: Nativer confirm()-Dialog
Performance-Überlegungen
Zusammenfassung
LinkShorter v2 ist eine schlanke, selbstgehostete Lösung ohne externe Abhängigkeiten. Die bemerkenswerteste technische Leistung ist die vollständige QR-Code-Implementierung in reinem PHP, inklusive Reed-Solomon-Fehlerkorrektur und Galois-Feld-Arithmetik. Die Chrome-Extension ergänzt das System um einen komfortablen Workflow direkt aus dem Browser heraus, wobei die Multi-Instanz-Unterstützung besonders für Nutzer mit mehreren Domains nützlich ist.