|
| 1 | +export default { |
| 2 | + nav: { |
| 3 | + home: "Startseite", |
| 4 | + internal: "Intern", |
| 5 | + external: "Extern", |
| 6 | + prevent: "Blockieren", |
| 7 | + analytics: "Analytik", |
| 8 | + confirm: "Bestätigen", |
| 9 | + formGuard: "Form Guard", |
| 10 | + security: "Sicherheit", |
| 11 | + }, |
| 12 | + home: { |
| 13 | + title: "link-interceptor", |
| 14 | + description: |
| 15 | + "Fängt alle Klicks auf {tag}-Tags in Ihrer SPA ab. Framework-unabhängiger Kern mit Vue-, React- und Svelte-Wrappern. Erfasst in der Capture-Phase und bietet Callbacks für interne/externe Links.", |
| 16 | + install: "Installation", |
| 17 | + basic: "Interaktive Demos", |
| 18 | + useCases: "Anwendungsfälle", |
| 19 | + console: "Konsole", |
| 20 | + consoleDescription: |
| 21 | + "Interceptor-Logs erscheinen im Konsolenpanel unten. Klicken Sie auf einen Link, um sie zu sehen.", |
| 22 | + internalDesc: "Interne Links in router.push() umwandeln", |
| 23 | + externalDesc: "URLs externer Links umschreiben", |
| 24 | + preventDesc: "Link-Navigation blockieren", |
| 25 | + analyticsDesc: "Link-Klicks verfolgen", |
| 26 | + confirmDesc: "Bestätigungsdialog für externe Navigation", |
| 27 | + formGuardDesc: "Navigation bei ungespeicherten Formularänderungen verhindern", |
| 28 | + securityDesc: "Domain-Erlaubnisliste + automatisches rel-Attribut", |
| 29 | + }, |
| 30 | + internal: { |
| 31 | + title: "Interne Links", |
| 32 | + description: |
| 33 | + "Erfasst Klicks auf gleichherkunfts-{tag}-Tags mit onInternalLink und wandelt sie über router.push() in SPA-Routing um.", |
| 34 | + normalLinks: "Normale HTML-Links (vom Plugin abgefangen)", |
| 35 | + toHome: "Zur Startseite", |
| 36 | + toExternal: "Zu Externen Links", |
| 37 | + toPrevent: "Zu Blockieren", |
| 38 | + vhtml: "Links in v-html (dynamisch generiertes HTML wird ebenfalls abgefangen)", |
| 39 | + vhtmlContent: |
| 40 | + 'Dies ist Inhalt, der mit v-html gerendert wurde: <a href="/">Zurück zur Startseite</a> | <a href="/prevent">Blockieren ansehen</a>', |
| 41 | + nested: "Verschachtelte Elemente", |
| 42 | + nestedDesc: "Klicks auf Kindelemente innerhalb von {tag} werden ebenfalls erkannt", |
| 43 | + nestedLink: "Dekorierter Link", |
| 44 | + routerLink: "Koexistenz mit Router Link", |
| 45 | + routerLinkDesc: |
| 46 | + "<router-link> und einfache <a>-Tags funktionieren nebeneinander. Der Interceptor erfasst beide in der Capture-Phase. RouterLink prüft event.defaultPrevented und überspringt seine eigene Navigation, wenn der Interceptor sie bereits behandelt hat.", |
| 47 | + routerLinkToHome: "router-link zur Startseite", |
| 48 | + plainLinkToExternal: "einfaches <a> zu Externen Links", |
| 49 | + routerLinkNote: |
| 50 | + "Beide Links erscheinen in der Konsole — der Interceptor behandelt alle <a>-Klicks, unabhängig davon, ob sie von <router-link> oder einfachem HTML stammen.", |
| 51 | + routerLinkGotcha: "Fallstrick: router-link replace", |
| 52 | + routerLinkGotchaDesc: |
| 53 | + "Der Interceptor erfasst auch Klicks auf <router-link replace>. Wenn der Callback ctx.preventDefault() und router.push() aufruft, wird die replace-Prop stillschweigend ignoriert — ein Verlaufseintrag wird hinzugefügt statt ersetzt.", |
| 54 | + routerLinkReplaceBroken: "ohne Workaround — replace wird ignoriert (klicken, dann Zurück drücken zum Prüfen)", |
| 55 | + routerLinkReplaceFixed: "mit data-no-intercept — replace funktioniert (klicken, dann Zurück drücken zum Vergleichen)", |
| 56 | + routerLinkGotchaNote: |
| 57 | + "Der erste Link hat keinen Workaround: Der Interceptor ruft preventDefault() + router.push() auf, daher geht replace verloren und ein Verlaufseintrag wird hinzugefügt. Der zweite Link hat data-no-intercept: Der Callback überspringt preventDefault(), sodass RouterLink die Navigation mit replace durchführt.", |
| 58 | + routerLinkWorkaround: |
| 59 | + "Workaround: Fügen Sie ein data-no-intercept-Attribut zu <router-link>-Elementen hinzu, die Props wie replace beibehalten müssen. Im Callback ctx.anchor.hasAttribute('data-no-intercept') prüfen und ctx.preventDefault() überspringen, damit RouterLink die Navigation selbst durchführt. Siehe main.ts für die Implementierung.", |
| 60 | + }, |
| 61 | + external: { |
| 62 | + title: "Externe Links", |
| 63 | + description: |
| 64 | + "Erfasst Klicks auf externe Links (andere Herkunft) mit onExternalLink. Diese Demo fügt automatisch den Parameter ?from=playground hinzu.", |
| 65 | + externalLinks: "Externe Links (URL wird beim Klick umgeschrieben)", |
| 66 | + note: 'Prüfen Sie die umgeschriebene URL in der Konsole. Links mit target="_blank" werden ebenfalls erfasst.', |
| 67 | + modifierTest: "Modifikatortasten-Test", |
| 68 | + modifierDesc: |
| 69 | + "Versuchen Sie Strg/Cmd + Klick. Klicks mit Modifikatortasten werden übersprungen, das Verhalten des Browsers für neue Tabs wird respektiert.", |
| 70 | + thisLink: "diesen Link", |
| 71 | + }, |
| 72 | + prevent: { |
| 73 | + title: "Navigation blockieren", |
| 74 | + description: |
| 75 | + "Rufen Sie ctx.preventDefault() im Callback auf, um die Link-Navigation abzubrechen.", |
| 76 | + normalLink: "Normaler interner Link (navigiert)", |
| 77 | + toHome: "Zur Startseite navigieren", |
| 78 | + blockedLinks: "Blockierte Links (keine Navigation)", |
| 79 | + blockedDesc: |
| 80 | + "Die folgenden Links haben ein data-block-Attribut. Die Demo blockiert die Navigation in main.ts.", |
| 81 | + blockedLink: "blocked.example.com (Klick navigiert nicht)", |
| 82 | + blockedToast: "Navigation zu {url} blockiert", |
| 83 | + }, |
| 84 | + analytics: { |
| 85 | + title: "Analytik / Tracking", |
| 86 | + description: |
| 87 | + "Beispiel für das Auslösen von Analyse-Events bei Link-Klicks. Stellen Sie sich das Senden an GA4 oder Mixpanel vor.", |
| 88 | + tryClick: "Versuchen Sie, auf diese Links zu klicken", |
| 89 | + internalLink: "Interner Link (Seitennavigation)", |
| 90 | + anotherDemo: "Zu einer anderen Demo-Seite", |
| 91 | + collectedEvents: "Gesammelte Events", |
| 92 | + time: "Zeit", |
| 93 | + type: "Typ", |
| 94 | + url: "URL", |
| 95 | + noEvents: "Noch keine Events", |
| 96 | + }, |
| 97 | + confirm: { |
| 98 | + title: "Bestätigungsdialog", |
| 99 | + description: |
| 100 | + 'Zeigt einen Bestätigungsdialog beim Klick auf einen externen Link. "Abbrechen" blockiert die Navigation, "OK" erlaubt sie.', |
| 101 | + withConfirm: "Links mit Bestätigungsdialog", |
| 102 | + withConfirmDesc: "Die folgenden Links haben ein data-confirm-Attribut.", |
| 103 | + confirmSuffix: " (mit Bestätigung)", |
| 104 | + withoutConfirm: "Links ohne Bestätigung (normales Verhalten)", |
| 105 | + withoutConfirmSuffix: " (ohne Bestätigung)", |
| 106 | + internalLink: "Interner Link (ohne Bestätigung)", |
| 107 | + implementation: "Implementierungsbeispiel", |
| 108 | + confirmPrompt: "Zu {hostname} navigieren?", |
| 109 | + }, |
| 110 | + formGuard: { |
| 111 | + title: "Form Guard", |
| 112 | + description: |
| 113 | + 'Zeigt eine Warnung „Änderungen gehen verloren" beim Klick auf einen Link während der Formularbearbeitung. Der Dialog erscheint nur bei ungespeicherten Eingaben.', |
| 114 | + formSection: "Formular (geben Sie etwas ein und klicken Sie dann auf einen Link)", |
| 115 | + name: "Name", |
| 116 | + namePlaceholder: "Max Mustermann", |
| 117 | + email: "E-Mail", |
| 118 | + emailPlaceholder: "max{'@'}example.com", |
| 119 | + dirty: "Ungespeicherte Änderungen", |
| 120 | + clean: "Keine Änderungen", |
| 121 | + navLinks: "Navigationslinks", |
| 122 | + navDesc: "Ein Bestätigungsdialog erscheint beim Klick mit ungespeicherten Formulareingaben.", |
| 123 | + implementation: "Implementierungsbeispiel", |
| 124 | + confirmLeave: "Änderungen gehen verloren. Trotzdem navigieren?", |
| 125 | + }, |
| 126 | + security: { |
| 127 | + title: "Sicherheit", |
| 128 | + description: |
| 129 | + "Sicherheitskontrollen für externe Links. Kombiniert eine Domain-Erlaubnisliste mit einem automatischen rel-Attribut.", |
| 130 | + allowlist: "Erlaubnisliste", |
| 131 | + allowlistDesc: "Erlaubte Domains: {domains}. Alle anderen sind blockiert.", |
| 132 | + allowed: "Erlaubt", |
| 133 | + blocked: "Blockiert", |
| 134 | + relSection: "Automatisches rel-Attribut", |
| 135 | + relDesc: |
| 136 | + 'Alle externen Links erhalten automatisch rel="noopener noreferrer". Prüfen Sie im Elements-Panel der DevTools.', |
| 137 | + implementation: "Implementierungsbeispiel", |
| 138 | + blockedAlert: "{hostname} ist blockiert", |
| 139 | + }, |
| 140 | + console: { |
| 141 | + title: "Konsole", |
| 142 | + empty: "Klicken Sie auf einen Link, um Interceptor-Logs hier zu sehen", |
| 143 | + }, |
| 144 | +}; |
0 commit comments