Deine Seite schreiben
Eine frwrd.to-Seite ist ein einziges Markdown-Dokument: ein kurzer Kopf mit Einstellungen, danach der Text. Du kannst sie von Hand schreiben, in der Web-App oder von einem Assistenten schreiben lassen, der diese Seite liest. Jeder Link darauf wird ein Kurzlink mit eigenen Klickzahlen.
Was eine Seite ist
Eine Seite ist für den einen Link, den Leute in deinem Profil antippen: ein Logo, ein Name, ein paar Buttons und deine Social Icons. Sie hat keinen eigenen Code, keine Spalten und keine Formulare. Was sie zeigen kann, steht auf dieser Seite, und mehr braucht es nicht, damit sie nach dir aussieht: ein Logo, eine Farbe, ein Button-Stil, eine Form und eine Schrift.
Wo sie liegt
Deine Hauptseite liegt unter https://frwrd.to/@handle. Dabei ist handle
die ID deines Workspace (sie beginnt mit w-), ein Handle, den du reserviert
hast, oder deine Domain. Weitere Seiten liegen darunter:
https://frwrd.to/@handle/jobs ist die Seite jobs. In der API, in den
MCP-Werkzeugen und im Kommandozeilen-Tool heißt die Hauptseite -.
Eine Seite in einer anderen Sprache als der deines Workspace liegt unter dem
Code dieser Sprache: https://frwrd.to/@handle/de/jobs. Verbinde die
Versionen mit translations (unten), dann zeigt die Seite einen
Sprachwechsler.
Häng .md an die Adresse einer Seite, um sie als Markdown zu lesen, zum
Beispiel ist https://frwrd.to/@frwrd.to/de/hilfe-seiten.md diese Seite.
Der Kopf
Der Kopf ist der erste Block des Dokuments, zwischen zwei Zeilen, die nur
--- enthalten. Er ist YAML. Setze Farben immer in Anführungszeichen: Ohne
sie beginnt # einen Kommentar, und die Seite wird abgelehnt.
| Feld | Was es ist | Erlaubte Werte |
|---|---|---|
title | Pflicht. Der Name der Seite, der Browser-Tab und Link-Vorschauen | 1 bis 120 Zeichen |
description | Ein Satz für Suchergebnisse und Link-Vorschauen | bis zu 300 Zeichen |
avatar | Dein Logo oder Foto, über dem Text. Eine Webadresse, nie eine Datei | https-Adresse, ohne Benutzername und Passwort |
lang | Die Sprache der Seite. Lass es weg: Sie folgt der Adresse der Seite | ein Sprachcode wie en oder de-AT; muss zur Adresse passen |
translations | Dieselbe Seite in anderen Sprachen | { en: jobs }: Sprachcode, dann die Adresse der Seite; "-" für eine Hauptseite |
utm | Tracking-Parameter, die an jeden Link der Seite kommen | source, medium, campaign, term, content, je 1 bis 100 Zeichen ohne Leerzeichen |
social | Deine Profile, als Reihe von Icons unter dem Logo | eine Liste von bis zu 12 https-Adressen |
theme.accent | Die Farbe von Links, Icons, Rahmen und gefüllten Buttons | "#rrggbb"; muss auf dem Hintergrund lesbar sein (siehe Kontrastregel) |
theme.background | Der Hintergrund der Seite | light, dark oder "#rrggbb" |
theme.button | Wie Link-Buttons aussehen | outline (ein Rahmen in der Akzentfarbe, der Standard) oder filled (die Akzentfarbe als Fläche) |
theme.shape | Die Ecken von Buttons und Icons | rounded (der Standard), pill oder square |
theme.font | Die Schriftart | sans (der Standard), serif oder mono. Nur Systemschriften: Nichts wird von anderswo geladen |
campaigns | Benannte Zeitfenster für zeitgesteuerte Blöcke (unten) | { black-friday: { from: 2026-11-27, until: 2026-11-30 } }; Namen aus a-z, 0-9 und -; Daten in UTC |
Alles andere im Kopf wird mit dem Namen des Schlüssels abgelehnt.
Alles unter theme ist optional. Eine Seite, die dort nichts setzt, sieht aus
wie immer: heller Hintergrund, blaue Akzentfarbe, Buttons mit Rahmen und
runden Ecken, serifenlose Schrift.
Social Icons
social listet vollständige https-Adressen. frwrd.to erkennt das Netzwerk
an der Adresse und zeichnet sein Icon: Instagram, LinkedIn, X (auch
twitter.com), YouTube, TikTok, GitHub, Facebook, Threads, Bluesky, Mastodon,
Twitch, Pinterest, Spotify, SoundCloud, Behance, Dribbble, Medium, Substack,
WhatsApp (wa.me), Telegram (t.me) und Discord. Einen Mastodon-Server
erkennt es am Pfad /@name. Alles andere bekommt ein Globus-Icon, benannt
nach seinem Host.
social:
- https://www.instagram.com/milafischer
- https://www.linkedin.com/in/milafischer
- https://milafischer.example
Jedes Icon ist ein Kurzlink wie jeder andere Link: Seine Klicks werden
gezählt, und das utm der Seite gilt. Die Icons haben deine Akzentfarbe, nie
die Markenfarben der Netzwerke, damit sie auf deinem Hintergrund lesbar
bleiben. Jedes hat einen zugänglichen Namen, den des Netzwerks. Eine
E-Mail-Adresse oder ein mailto:-Link ist nicht möglich (nur http- und
https-Adressen sind Links); schreib die Adresse als Text in den Haupttext.
Social-Profile kommen in den Zahlen der Seite nach den eigenen Links der Seite, in der Reihenfolge, in der du sie geschrieben hast. Eine Seite kann insgesamt 200 Links haben, die sozialen eingeschlossen.
Die Kontrastregel
Eine Seite, deren Text sich nicht lesen ließe, wird beim Speichern abgelehnt, mit einer Meldung, die die Felder und das gemessene Verhältnis nennt, zum Beispiel:
theme.accent #ff5a1f on theme.background light (#ffffff) measures 3.11:1; links in the accent colour need at least 4.5:1 (WCAG AA). Pick a darker accent for a light background, a lighter one for a dark background, or change theme.background
Du wählst den Hintergrund und die Akzentfarbe. frwrd.to errechnet den Rest: Die Textfarbe ist das nahezu Schwarz oder nahezu Weiß, das auf deinem Hintergrund am besten lesbar ist, Karten und Nebentext werden davon abgeleitet, und die Beschriftung eines gefüllten Buttons ist Schwarz oder Weiß, je nachdem, was auf deiner Akzentfarbe besser lesbar ist. Das besteht immer. Falsch machen kannst du nur die Akzentfarbe, deshalb gilt die Regel für sie:
- Die Akzentfarbe braucht ein Kontrastverhältnis von mindestens 4,5 zu 1 gegenüber dem Hintergrund (WCAG 2.1 AA für Text: Links sind in der Akzentfarbe gezeichnet).
- Gegenüber den Karten, den getönten Flächen hinter Code und den Social Icons, braucht sie außerdem 3 zu 1. Die Meldung sagt, welche der beiden Regeln verletzt ist.
Kurz: Auf hellem Hintergrund nimm eine dunkle Akzentfarbe, auf dunklem eine helle. Akzentfarben, die funktionieren:
| Hintergrund | Akzentfarben, die lesbar sind |
|---|---|
light (weiß) | "#1f6feb", "#c2410c", "#0f766e", "#7c3aed" |
dark | "#ff7a59", "#7fb2ff", "#4ade80", "#fbbf24" |
"#fff8e7" (Creme) | "#8a3b00", "#0f766e" |
"#10243e" (Marine) | "#7fb2ff", "#fbbf24" |
Eine Seite, die du vor dieser Regel gespeichert hast, funktioniert weiter wie sie ist; beim erneuten Speichern wirst du nach einer lesbaren Farbe gefragt.
Der Haupttext
Alles nach dem Kopf ist Markdown, eine sichere Teilmenge davon.
| Du schreibst | Du bekommst |
|---|---|
# Name | Die Überschrift der Seite. ## und ### sind kleinere Überschriften; tiefere Ebenen zählen als ### |
| ein Link allein in einer Zeile oder allein in einem Listenpunkt | Ein Button: - [Gespräch buchen](https://example.com/call) |
| ein Link mitten im Satz | Ein gewöhnlicher Link: Siehe [die Doku](https://example.com/docs). |
<https://example.com> oder ein bloßes https://example.com | Ein Link mit der eigenen Adresse als Text |
**fett** und *kursiv* | Fett und kursiv |
eine Liste mit - oder 1. | Eine Liste; Listen und Zitate verschachteln sich bis zu 12 Ebenen tief |
`Code` und umzäunte Blöcke | Inline-Code und Codeblöcke; Zeilenumbrüche bleiben |
> Text | Ein Zitat |
| eine GFM-Tabelle: eine Kopfzeile, darunter eine Zeile aus Strichen, dann die Zeilen | Eine Tabelle, die seitlich scrollt, wenn sie breit ist |
 | Ein Bild, nur https. Schreib immer den Alternativtext |
--- allein in einer Zeile | Eine Trennlinie |
Rohes HTML wird verworfen. Ein Link, dessen Adresse nicht http oder https
ist, bleibt Text, ebenso www.-Adressen und E-Mail-Adressen ohne Schema. Ein
Link auf eine andere deiner Seiten beginnt mit /@handle/: Er wird wie jeder
Link gezählt, ohne Tracking-Parameter.
Eine Seite darf höchstens 64 KiB groß sein. Links werden beim Speichern
geprüft: Eine Adresse, die in ein Netzwerk hinein zeigt (wie localhost),
wird abgelehnt, ebenso eine mit Benutzername und Passwort darin.
Zeitgesteuerte Blöcke
Ein Block kann nur während einer Kampagne erscheinen. Er steht zwischen einer
Zeile, die sagt wann, und einer Zeile, die nur ::: enthält:
::: from 2026-11-27 until 2026-11-30
- [Black Friday: 30 % Rabatt](https://example.com/sale)
:::
Ein Ende darf fehlen: ::: from 2026-12-24 zeigt ab dann, ::: until 2026-12-31 bis dahin. Für eine Kampagne, die an mehreren Stellen vorkommt,
benennst du sie einmal im Kopf und verwendest den Namen:
---
title: Acme
campaigns:
black-friday: { from: 2026-11-27, until: 2026-11-30 }
---
::: black-friday
- [Zum Sale](https://example.com/sale)
:::
::: not black-friday
- [Zum Shop](https://example.com/shop)
:::
::: not black-friday erscheint immer dann, wenn die Kampagne nicht läuft:
Der normale Button kommt nach dem Sale von selbst zurück.
Alle Zeiten sind UTC. Ein Datum meint den ganzen Tag in UTC:
until 2026-11-30 zeigt den Block bis zum Ende des 30. November, UTC. Eine
Uhrzeit schreibst du in UTC mit Z: from 2026-11-27T08:00Z ist im Winter
9:00 in Wien. Eine Zeit mit anderer Zone, etwa +01:00, wird abgelehnt.
Die Links in einem Block funktionieren immer, auch bevor der Block erscheint und nachdem er endet. Jeder Link bekommt beim Speichern seinen Kurzlink, so kannst du Links, QR-Codes und Tracking der Kampagne testen, bevor sie startet.
Blöcke verschachteln sich nicht, eine Seite hat höchstens 20, und die
:::-Zeilen beginnen am Zeilenanfang. Bevor ein Block erscheint, lässt die
Markdown-Fassung der Seite (.md) ihn weg, ebenso die Kampagnennamen im Kopf.
Vor dem Speichern prüfen
Der Editor der Web-App hat einen Button Prüfen, die API
POST /v1/pages/{path}/check, MCP das Werkzeug check_page und das
Kommandozeilen-Tool frwrd page check <path> < page.md. Jedes führt alle
Prüfungen des Speicherns aus, speichert nichts und listet Hinweise auf: Dinge,
die erlaubt, aber vermutlich nicht gemeint sind, etwa eine fehlende
Beschreibung, eine Kampagne, die kein Block nutzt, ein zeitgesteuerter Block,
der schon vorbei ist, ein ::: mit Leerzeichen davor (es erscheint als Text),
eine übersprungene Überschriftenebene, ein zweiter #-Titel, ein http-Link
oder ein Bild ohne Beschreibung. Hinweise verhindern das Speichern nie;
Fehler schon, und sie sagen, was zu ändern ist.
Drei vollständige Beispiele
Jedes ist ein ganzes Dokument zum Einfügen. Ersetze die Adressen durch deine.
Ein Link in Bio
---
title: Mila Fischer
description: Illustratorin in Wien. Aufträge möglich.
avatar: https://example.com/mila.jpg
social:
- https://www.instagram.com/milafischer
- https://www.behance.net/milafischer
- https://www.youtube.com/@milafischer
theme: { background: "#fff8e7", accent: "#8a3b00", button: filled, shape: pill, font: serif }
utm: { source: bio, medium: social }
---
# Mila Fischer
Illustratorin in Wien. Ich zeichne Bücher, Plakate und ab und zu eine Wand.
- [Auftrag anfragen](https://example.com/commissions)
- [Drucke kaufen](https://example.com/shop)
- [Newsletter, einmal im Monat](https://example.com/newsletter)
Eine Veranstaltung
---
title: Frwrd Summit 2027
description: Zwei Tage über Links, Seiten und Zahlen. Wien, 14. und 15. Mai 2027.
social: [https://www.linkedin.com/company/example, https://bsky.app/profile/example.com]
theme: { background: dark, accent: "#7fb2ff", button: outline, shape: square, font: sans }
utm: { source: summit, medium: qr, campaign: summit-2027 }
---
# Frwrd Summit 2027
**14. und 15. Mai 2027**, Museumsquartier, Wien.
- [Ticket sichern](https://example.com/tickets)
- [Programm ansehen](https://example.com/programme)
- [Als Speaker bewerben](https://example.com/speakers)
## Gut zu wissen
> Einlass ab 08:30. Das Mittagessen ist inbegriffen.
| Tag | Thema |
|:--|:--|
| 14. Mai | Links und Seiten |
| 15. Mai | Zahlen |
Anreise: [der Veranstaltungsort auf der Karte](https://example.com/map).
Ein Portfolio
---
title: Jonas Weber, Produktdesigner
description: Ausgewählte Arbeiten, Texte und Kontakt.
avatar: https://example.com/jonas.jpg
social: [https://github.com/jonasweber, https://dribbble.com/jonasweber, https://www.linkedin.com/in/jonasweber]
theme: { background: light, accent: "#0f766e", button: outline, shape: rounded, font: mono }
---
# Jonas Weber
Produktdesigner. Ich mache Checkouts weniger mühsam.
## Ausgewählte Arbeiten
- [Checkout-Redesign für Acme](https://example.com/work/acme)
- [Ein Designsystem für Beta](https://example.com/work/beta)
## Texte
Mein neuester Text ist [Warum Buttons eine Beschriftung brauchen](https://example.com/blog/buttons).
Alles steht unter https://example.com/blog.
## Kontakt
Schreib an hallo bei example punkt com, oder nutze [das Kontaktformular](https://example.com/contact).
Von einer KI schreiben lassen
Kopiere diesen Prompt in einen beliebigen Assistenten (Claude, ChatGPT oder einen anderen, der eine Webadresse lesen kann). Er liest diese Seite, fragt dich, was er braucht, und gibt dir das fertige Dokument.
Read https://frwrd.to/@frwrd.to/help-pages.md. It describes the Markdown format of a frwrd.to page: the header (title, description, avatar, social, theme) and the body.
Ask me, one question at a time:
1. My brand or name.
2. One sentence about what I do.
3. The links I want on the page, each with a label.
4. My social profiles, as full https addresses.
5. The address of my logo.
6. My colours: a background (light, dark or a #rrggbb colour) and an accent (#rrggbb).
Then write the whole page as one Markdown document, header included, in a single code block. Follow the format exactly. Check the contrast rule: the accent needs a contrast ratio of at least 4.5 to 1 against the background, so on a light background use a dark accent and on a dark background a light one. Put every colour in quotes. Do not invent links, profiles or facts. Use the three examples on that page as a guide for the structure.
Der Prompt ist englisch, weil die Referenzseite es ist; dein Assistent
antwortet dir trotzdem in deiner Sprache, wenn du ihn darum bittest. Möchtest
du die Seite auf Deutsch, ergänze: "Schreib die Seite auf Deutsch, in der
Adresse de/...."
Speichere das Ergebnis dann: Füge es in den Seiteneditor der
Web-App ein, oder lass deinen Assistenten es über
MCP oder das
Kommandozeilen-Tool veröffentlichen
(frwrd page push). Wenn etwas im Dokument nicht erlaubt ist, sagt dir das
Speichern genau, was du ändern musst.