Insights / Technische Beiträge
Technisches Design zur Übergabe des Kontexts eines Service-CTA an das Kontaktformular
Implementierungsdesign, das den auf einer Serviceseite gelesenen Kontext an das Kontaktformular übergibt. Behandelt werden Mini-CTAs in Astro, der URL-Parameter-Vertrag, die anfängliche Kategorieauswahl, Subject-Prefill, mehrsprachige URLs, GA-Messung und Prüfung des generierten HTML.
Inhaltsverzeichnis
- Formularinitialisierung anhand eines CTA prüfen
- Das Ziel ist nicht nur weniger Formulareingabe
- Verantwortlichkeiten in eine CTA-Komponente auslagern
- URL-Parameter als Vertrag mit dem Formular
- Klassifikationstabelle im Formular
- Data-Attribute an option setzen
- Prefill im Client
- Mit dem hash zum Formular springen
- Warum kein weiteres hidden-Feld
- Ansatz für mehrsprachige Websites
- Generiertes HTML prüfen
- Rollenverteilung mit dem KI-Chat
- Zusammenfassung
- Ergänzung vom 6. Oktober 2026: Vom Kontaktformular zum Verwaltungsdatensatz
Aktualisierung vom September 2026: Die Beispiele
ServiceSectionActionsundservice=webdokumentieren das Unternehmenssite-Design vom Juni 2026. Heute übergeben Acecore-Systems-Service-CTAscategory,service,fromundentry; das Kontaktformular prüft kurze Service-Keys und belegt Kategorie und Betreff vor. Es nutzt auch versteckte Felder für Messung und Integration. Übernehmen Sie die damalige Entscheidung ohne versteckte Felder nicht als aktuellen Vertrag. URL-Werte müssen weiterhin erlaubten Formularoptionen zugeordnet werden.
Wenn ein Besucher auf einer Serviceseite denkt „dazu möchte ich eine Anfrage stellen“, geht ein Teil des Kontexts verloren, wenn er lediglich zum Kontaktformular weitergeleitet wird.
Er muss den Servicetyp erneut auswählen und den Betreff schreiben. Auch das empfangende Team kann vor dem Lesen der Nachricht kaum erkennen, ob es um Webproduktion, Serverbetrieb oder Aceserver geht.
Auf der Acecore-Website haben wir diesen Weg mit dem PR zur Übergabe des Serviceziels an das Kontaktformular verbessert. Dieser Artikel beschreibt die Lösung sowohl als Astro-Implementierung als auch als wiederverwendbares Journey-Design.
Formularinitialisierung anhand eines CTA prüfen
Testen Sie gültige und unbekannte Schlüssel sowie Zurücknavigation nach Betreffeingabe. Prüfen Sie zulässige Optionen und Erhalt des Betreffs mit demselben Wertevertrag in Sprach-URLs. Übergeben Sie Kontext über kurze Kennungen; personenbezogene Daten und Freitext gehören nicht in URLs.
MDN URLSearchParams:URL-Parameter lesen
Das Ziel ist nicht nur weniger Formulareingabe
Der Zweck besteht nicht einfach darin, Felder automatisch auszufüllen und das Formular leichter wirken zu lassen.
Entscheidend ist, den auf der Serviceseite entstandenen Kontext korrekt an Formular und Empfangsbetrieb weiterzugeben.
| Perspektive | Gewünschte Verbesserung |
|---|---|
| Nutzer | Den gelesenen Service nicht erneut auswählen müssen |
| Formular | Kategorie und Betreff passend zur Anfrage initialisieren |
| Empfang | Das Ziel allein anhand der Kategorie klassifizieren |
| Messung | Erkennen, von welchem Service-CTA die Anfrage begann |
| Mehrsprachiger Weg | Zur Kontakt-URL der passenden locale führen |
Optisch handelt es sich nur um einen kleinen CTA, doch das Design umfasst CTA, URL, Formular, Übersetzung, Messung und Empfangsbetrieb.
Verantwortlichkeiten in eine CTA-Komponente auslagern
Am Ende jedes Serviceabschnitts steht ein CTA „Zu diesem Service beraten lassen“.
Die gleiche Linkerzeugung und dieselben GA-Attribute sollten nicht in jedem Abschnitt direkt wiederholt werden. Bei sieben Services erscheint dieselbe Logik siebenmal und kann beim Ändern von Text oder URL-Spezifikation teilweise vergessen werden.
Deshalb bündelt ServiceSectionActions den Kontakt-CTA.
---
import Icon from "./Icon.astro";
import { t, getLocalizedUrl, type Locale } from "../i18n";
interface Props {
locale: Locale;
gaLabel: string;
gaLocation: string;
serviceKey: string;
}
const { locale, gaLabel, gaLocation, serviceKey } = Astro.props;
const u = (path: string) => getLocalizedUrl(path, locale);
const contactUrl = `${u("/contact/")}?category=service&service=${encodeURIComponent(serviceKey)}#contact-form`;
---
<a
href={contactUrl}
class="ac-btn-outline gap-2 text-sm sm:w-auto"
data-ga-event="cta_click"
data-ga-label={gaLabel}
data-ga-location={gaLocation}
data-ga-destination={contactUrl}
>
<Icon name="message-circle" class="text-sm" />
{t(locale, "pages.services.miniCta")}
</a>
Die Komponente hat drei Aufgaben:
- Eine zur locale passende Kontakt-URL erzeugen
- Den service key in einen URL-Parameter setzen
- label und location für die GA-Messung tragen
Ein CTA ist Aktions- und Messpunkt, nicht nur UI. data-ga-label und data-ga-location bleiben erhalten, damit später sichtbar ist, von welchem Service die Anfrage ausging.
URL-Parameter als Vertrag mit dem Formular
Die Werte werden über URL-Parameter übergeben.
/contact/?category=service&service=web#contact-form
Wichtig ist, keinen sichtbaren Anzeigetext in die URL zu setzen.
Ein Label wie Webサイト制作・運用について wird von Übersetzung, Schreibvarianten und künftigen Namensänderungen beeinflusst. In die URL gehört nur ein kurzer service key wie web oder server.
| Parameter | Rolle |
|---|---|
category |
Kennzeichnet den Einstieg zur Verarbeitung als Serviceanfrage |
service |
Stabiler key für den Zielservice |
| hash | Dient zum Scrollen zum Formular |
URL-Parameter können vom Nutzer bearbeitet werden. Das Formular übernimmt den URL-Wert deshalb nicht direkt, sondern ordnet ihn einem vorhandenen option zu.
- CTA-Kontext auflösen Einen stabilen service key der lokalisierten URL und einer erlaubten Formularoption zuordnen.
- Eingaben und Berechtigungen prüfen Den Betreff nur vorbelegen, wenn er leer ist; die API prüft außerdem die Identität des Nutzers und die Aktionsberechtigung.
- In die Annahmeakte übernehmen Anfrage, Verlauf und Folgeaufgaben erfassen; der Abschluss durch das Team bleibt ein eigener Status.
Klassifikationstabelle im Formular
Das Kontaktformular führt die Servicekategorien in einem Array.
const serviceCategoryOptions = [
{
key: "server",
value: "サーバー構築・運用について",
label: t(locale, "pages.contact.formCategoryServiceServer"),
subject: t(locale, "pages.services.server.title"),
},
{
key: "web",
value: "Webサイト制作・運用について",
label: t(locale, "pages.contact.formCategoryServiceWeb"),
subject: t(locale, "pages.services.web.title"),
},
];
key, value, label und subject haben unterschiedliche Rollen.
| Feld | Rolle |
|---|---|
key |
Stabiler Bezeichner zum Finden über den URL-Parameter |
value |
Anfragekategorie, die beim Senden beim Team ankommt |
label |
Übersetzter option, der auf dem Bildschirm erscheint |
subject |
Servicename zur Initialisierung des Betreffs |
Auf einer mehrsprachigen Website wird label für die locale übersetzt. value dient der Klassifikation im Empfang und bleibt daher ein stabiler japanischer Wert.
Die Entscheidung hängt vom Produkt ab. Unterstützt das CRM mehrsprachige Klassifikationen, kann value ebenfalls nach locale variieren. Für einen einfachen Empfangsbetrieb ist die Trennung von sichtbarem Label und gesendetem Wert leichter zu verwalten.
Data-Attribute an option setzen
Der select gibt pro Service einen option aus.
<select id="category" name="category" required>
<option value="" disabled selected>
{t(locale, "pages.contact.formCategoryPlaceholder")}
</option>
<option value="サービス全般について">
{t(locale, "pages.contact.formCategoryService")}
</option>
{
serviceCategoryOptions.map((option) => (
<option
value={option.value}
data-service-key={option.key}
data-service-subject={option.subject}
>
{option.label}
</option>
))
}
</select>
data-service-key wird mit service in der URL verglichen. data-service-subject dient zur Erstellung des Betreffs.
Auch hier wird der URL-Wert nicht direkt in category.value eingesetzt. Die Auswahl eines vorhandenen option verhindert, dass unbekannte service keys oder ungültige Werte in die gesendeten Daten gelangen.
Prefill im Client
Ein kleines Skript initialisiert das Formular nach dem Laden.
function initContactServicePrefill() {
const form = document.getElementById("contact-form");
if (!form || form.dataset.servicePrefillInitialized === "true") return;
form.dataset.servicePrefillInitialized = "true";
const url = new URL(window.location.href);
const requestedCategory = url.searchParams.get("category");
const requestedService = url.searchParams.get("service") || "";
const category = document.getElementById("category");
const subject = document.getElementById("subject");
if (
requestedCategory === "service" &&
category instanceof HTMLSelectElement
) {
const serviceOption = Array.from(category.options).find((option) => {
return option.dataset.serviceKey === requestedService;
});
category.value = serviceOption?.value || "サービス全般について";
category.dispatchEvent(new Event("input", { bubbles: true }));
category.dispatchEvent(new Event("change", { bubbles: true }));
if (
serviceOption &&
subject instanceof HTMLInputElement &&
!subject.value.trim()
) {
const template = form.dataset.serviceSubjectTemplate || "{service}";
const serviceName =
serviceOption.dataset.serviceSubject ||
serviceOption.textContent?.trim() ||
"";
subject.value = template.replace("{service}", serviceName);
}
}
}
Vier Punkte sind wichtig:
data-service-prefill-initializedprüfen, um doppelte Initialisierung zu vermeiden- Nur bei
category=serviceverarbeiten - Bei unbekanntem service key auf
サービス全般についてzurückfallen - Den Betreff nur initialisieren, wenn er leer ist
Der letzte Punkt ist entscheidend. Hat eine Zurück-Navigation oder Browser-Autovervollständigung den Betreff erhalten, verschlechtert ein Überschreiben die Erfahrung.
Bei Astro View Transitions oder Clientnavigation wird zusätzlich bei astro:page-load initialisiert.
document.addEventListener("astro:page-load", initContactServicePrefill);
initContactServicePrefill();
Mit dem hash zum Formular springen
Die CTA-URL enthält #contact-form.
/contact/?category=service&service=web#contact-form
Da eine Kontaktseite auch FAQ, LINE, Erklärungen und andere Kontaktwege enthalten kann, ist der direkte Sprung zum Formular für Besucher eines Service-CTA natürlicher.
Bei der Formularinitialisierung muss der Scrollzeitpunkt beachtet werden. requestAnimationFrame sorgt dafür, dass erst nach dem Rendern gescrollt wird.
if (window.location.hash === "#contact-form") {
window.requestAnimationFrame(() => {
form.scrollIntoView({ block: "start" });
});
}
Es ist nur ein kleines Verhalten, doch wenn CTA-Absicht und sichtbare Formularposition auseinanderliegen, entsteht Unsicherheit. URL, Vorauswahl und Scrollposition werden gemeinsam gestaltet.
Warum kein weiteres hidden-Feld
Wir haben kein hidden-Feld 相談対象サービス hinzugefügt.
Der Zielservice sollte allein über die Anfragekategorie erkennbar sein.
Zusätzliche Felder erzeugen zusätzliche Prüfungen:
- Soll es in der Benachrichtigungs-E-Mail erscheinen?
- Braucht die Verwaltungsoberfläche oder Tabelle eine weitere Spalte?
- Beeinflusst es bestehende Auto-Reply-Vorlagen?
- Wird es in CRM oder Webhook verarbeitet?
- Wie werden mehrsprachige Anzeigenamen und Empfangswerte getrennt?
Können vorhandene Felder die Information ausdrücken, bleibt der Betrieb stabiler, wenn kein neues hinzukommt. お問い合わせ種別 wird in allgemeine und servicespezifische Kategorien geteilt.
Ein hidden-Feld kann sinnvoll sein, wenn mehrere Services gewählt, eine Kampagnen-ID gespeichert oder ein eigenes CRM-Feld verwendet werden soll.
Ansatz für mehrsprachige Websites
Die Trennung von drei Werten verhindert Verwirrung.
| Typ | Beispiel | Von locale abhängig |
|---|---|---|
| URL key | web, server, aceserver |
Nein |
| Sichtbares Label | About Website Design usw. |
Ja |
| Gesendeter Wert | Webサイト制作・運用について |
Je nach Betrieb |
Der URL key wird besser nicht übersetzt, weil er beim Teilen, Messen und Abgleichen im Formular verwendet wird.
Das sichtbare Label wird immer übersetzt, da der Nutzer es im Formular liest.
Der gesendete Wert richtet sich nach dem Betrieb. Hier nutzen wir stabile japanische Werte. Mehrsprachige Anzeige und interne Verarbeitung nach dem Senden getrennt zu gestalten erleichtert die Verwaltung.
Der Übersetzungsfluss wird auch in Mehrsprachige Blogs mit Sveltia CMS betreiben beschrieben.
Generiertes HTML prüfen
Nur die Komponente zu betrachten reicht nicht. Nach dem build muss geprüft werden, ob Links und option tatsächlich ausgegeben wurden.
Wir prüften:
- Sieben servicespezifische CTA in
/services/ - Jeder CTA enthält
?category=service&service=...#contact-form - Sieben option mit
data-service-keyin/contact/ サービス全般についてund servicespezifische Kategorien sind vorhanden- Kein hidden-Feld
相談対象サービスist vorhanden
Zum Beispiel lässt sich rg verwenden.
rg -n "category=service&service=.*#contact-form" dist\services\index.html
rg -n "data-service-key" dist\contact\index.html
rg -n "相談対象サービス" dist\contact\index.html
Die letzte Prüfung bestätigt die Abwesenheit dessen, was nicht hinzugefügt werden sollte. Bei Formularänderungen werden sowohl Ergänzungen als auch bewusst ausgelassene Elemente geprüft.
Rollenverteilung mit dem KI-Chat
Der Weg passt zum technischen Design des Anfrage-KI-Chats, doch die Rollen unterscheiden sich.
| Weg | Stärke |
|---|---|
| KI-Chat | Im Dialog klären, welcher Service passt |
| Service-CTA | Den Kontext des gelesenen Service an das Formular übergeben |
| Formular | Die offizielle Anfrage empfangen und dokumentieren |
Der KI-Chat hilft, solange der Nutzer noch unsicher ist. Hat er die Serviceseite gelesen und sich entschieden, ist die direkte Weiterleitung ohne zusätzlichen Dialog natürlicher.
Mehr Wege sollten nicht alle dieselbe Rolle erhalten. Dialog, CTA und Formular werden je nach Zustand des Nutzers eingesetzt.
Zusammenfassung
Die Kontextübergabe von der Serviceseite zum Formular wirkt stärker, als die kleine sichtbare Änderung vermuten lässt.
Wichtige Punkte waren:
- CTA als Komponente ausführen und URL-Erzeugung sowie Messattribute bündeln
- Stabilen service key statt Anzeigetext in der URL verwenden
- service key im Formular einem option zuordnen
- Gesendeten Wert, Label und Servicenamen für den Betreff trennen
- Bei unbekanntem service key auf allgemeine Anfragen zurückfallen
- Betreff nur vorausfüllen, wenn er leer ist
- Ohne weiteres hidden-Feld über die Kategorie klassifizieren
- Nach dem build Link- und option-Anzahl sowie das Fehlen unnötiger Felder prüfen
Formularverbesserung bedeutet nicht nur weniger Eingabefelder. Wird der gelesene Kontext bis zum empfangenden Team übertragen, wird die tatsächliche Bearbeitung einfacher.
Ergänzung vom 6. Oktober 2026: Vom Kontaktformular zum Verwaltungsdatensatz
In einer anonymisierten Integration wurden der Eingang einer Anfrage, ihre Übernahme in CRM-Verlauf und Aufgaben sowie der Abschluss der Bearbeitung durch das Team als getrennte Zustände behandelt. URL-Werte und Kontaktwege werden geprüft; die Kanalwerte werden einem stabilen Enum zugeordnet. Die URL der Administrationsoberfläche zu kennen, berechtigt nicht dazu, Verlauf oder Aufgaben zu ändern.
Auch die API prüft die nutzende Person und ihre Berechtigungen. Kundendaten werden weder in die öffentliche Suche noch in öffentliche KI-Antworten übernommen. Eine abgeschlossene Implementierung von Annahme und Erfassung bedeutet nicht, dass der vollständige Ablauf vom Kontakt mit echten Kunden bis zum Abschluss der Bearbeitung getestet wurde.
Die Formularvorbelegung wird von den Eingaben der Person getrennt. Ist ein Rückruf erforderlich, wird der bevorzugte Kontaktweg als verpflichtende feste Auswahl erfasst und an die nachfolgende Aufgabe übergeben. Die Pflichtangaben in Oberfläche und API sowie die Lese- und Ergänzungsrechte des Teams werden aufeinander abgestimmt; nach einer Datenbankänderung werden Schema und Constraints geprüft. Notwendige Prüfungen in der Produktion bleiben davon getrennt, die gesamte Datenbank echter Kunden in eine Entwicklungsumgebung zu kopieren.
Ablauf zur Übergabe des Kontexts vom Service-CTA an das Formular
Service
Dem CTA jedes Serviceabschnitts einen service key geben.
URL
Über einen URL-Vertrag wie /contact/?category=service&service=web#contact-form übergeben.
Form
Passende Anfragekategorie und passenden Betreff im Formular initialisieren.
Ops
Das empfangende Team erkennt den Servicekontext allein an der Anfragekategorie.
Unterschied bei der Verbindung von CTA und Formular
Nur zum Formular weiterleiten
- Der Nutzer muss denselben Servicenamen erneut auswählen
- Der Betreff bleibt leer und der Inhalt der Anfrage ist schwer erkennbar
- Das empfangende Team muss die Nachricht lesen, um den Service zu bestimmen
- Die Wirkung einzelner Service-CTAs bleibt schwer messbar
Kontext weitergeben
- Die Anfragekategorie kann über den service key des CTA vorausgewählt werden
- Der Servicename kann den Betreff füllen und die Anfrage strukturieren
- Das empfangende Team kann anhand der Kategorie klassifizieren
- GA label und URL-Parameter erleichtern die Auswertung pro CTA
Designprüfung bei der Einführung
- In URL-Parametern nur kurze, stabile service keys verwenden
- Als Formularwerte betrieblich stabile Werte statt sichtbarer Nutzertexte verwenden
- Bei unbekanntem service key auf allgemeine Serviceanfragen zurückfallen
- Den Betreff nur dann vorausfüllen, wenn er leer ist
- Vor zusätzlichen hidden-Feldern prüfen, ob die bestehende Kategorie zur Klassifizierung reicht
- Die Kontakt-URL für jede locale serverseitig erzeugen
- Dem CTA GA label und location für die Wirkungsmessung geben
- Nach dem build Anzahl der CTA und option sowie Vorhandensein oder Fehlen von hidden-Feldern im HTML prüfen
Zugehörige Seiten
Häufig gestellte Fragen
Warum wird der Zielservice nicht in einem hidden-Feld gesendet?
Im Juni 2026 wurde nur mit der vorhandenen Kategorie klassifiziert, ohne zusätzliche versteckte Felder. Das aktuelle Systems-Formular speichert service, from und entry zusätzlich in versteckten Feldern für die Integration.
Ist eine Manipulation der URL-Parameter unproblematisch?
Ein unbekannter service key fällt auf allgemeine Serviceanfragen zurück. Der gesendete Wert wird aus den option des Formulars gewählt; der URL-Wert selbst wird daher nicht direkt gesendet.
Wie funktioniert das auf einer mehrsprachigen Website?
CTA-Ziele werden pro locale erzeugt und sichtbare Formularlabels übersetzt. Stabile japanische Klassifikationswerte als gesendete Werte halten den Empfangsbetrieb konsistent.