112 lines
6.4 KiB
Markdown
112 lines
6.4 KiB
Markdown
# Integracje, SEO, bezpieczeństwo, wydajność
|
||
|
||
Zakres odpowiada sekcjom 5–10 i 13 `wymagania-projektowe-strony.md`,
|
||
zawężonym do tego, co faktycznie dotyczy tego projektu (bez np. e-commerce,
|
||
CRM — których tu nie ma).
|
||
|
||
---
|
||
|
||
## 1. WhatsApp — jedyna „ciężka" integracja tego projektu
|
||
|
||
Nie wymaga API/klucza — to prosty link `https://wa.me/{numer}?text={wiadomość}`.
|
||
Do ustalenia:
|
||
|
||
- **Numer** — z global `Company.whatsappNumber`, patrz [10-architektura-cms.md](./10-architektura-cms.md) §1.
|
||
- **Prefill wiadomości** — rekomendacja: każdy CTA „Napisz na WhatsApp" może
|
||
nieść inny, kontekstowy tekst startowy (np. z `/uslugi`: „Dzień dobry, mam
|
||
pytanie o rozliczenie podatku z Niemiec" — z `/jak-sie-umowic`: „Chciałbym
|
||
rozpocząć proces rozliczenia"). To niewielki dodatek do configu bloku
|
||
`finalCta`/`hero` (pole `whatsappMessage` opcjonalne), ale realnie
|
||
podnosi jakość pierwszego kontaktu — klient wie, z jakiej podstrony
|
||
ktoś pisze, zanim jeszcze odpowie.
|
||
- **Śledzenie konwersji** — kliknięcie w link WhatsApp jako zdarzenie
|
||
(`whatsapp_click`) wysyłane do analityki PO zgodzie (patrz §3) —
|
||
jedyny sposób, żeby zmierzyć skuteczność strony, skoro nie ma
|
||
tradycyjnego „wysłania formularza" jako punktu konwersji.
|
||
|
||
## 2. Formularz kontaktowy (jeśli wdrożony — patrz [08-kontakt.md](./08-kontakt.md) §3)
|
||
|
||
Zgodnie z `wymagania-projektowe-strony.md` §9 i `wymagania-prawne.md` §3:
|
||
|
||
- Walidacja klient + serwer (nie ufać samemu frontowi).
|
||
- Ochrona antyspam: Turnstile (plugin ipal-kit ma wsparcie, patrz
|
||
`turnstile.md` w docs pluginu) — bez własnej implementacji captchy.
|
||
- Zgoda RODO: osobny, NIEZAZNACZONY checkbox z linkiem do polityki
|
||
prywatności (przez `getSystemPagePath`), enforcement server-side
|
||
(`validateSubmission`, `consentFieldName`) — zgodnie z `wymagania-prawne.md` §3.
|
||
Formularz bez zaznaczonej zgody ma nie przejść nawet przy bezpośrednim
|
||
requeście (nie tylko blokada w UI).
|
||
- SMTP: przez `panelSmtpAdapter`/mailAdapter pluginu, testowane przez
|
||
Mail-Tester przed produkcją (SPF/DKIM/DMARC — inaczej maile lądują w spamie
|
||
i formularz jest bezużyteczny mimo poprawnego kodu).
|
||
- Stan sukcesu: prosty komunikat inline (patrz [08-kontakt.md](./08-kontakt.md) §3),
|
||
bez osobnej strony thank-you.
|
||
|
||
## 3. Analityka — za zgodą, nie przed
|
||
|
||
- Rekomendacja narzędzia: **Plausible** (prostsze, nie wymaga cookie
|
||
zgody na poziomie technicznym tak restrykcyjnie jak GA4, mniejszy ciężar
|
||
strony) LUB **GA4**, jeśli klient chce integrację z szerszym ekosystemem
|
||
Google — decyzja do podjęcia z klientem, nie zakładać automatycznie GA4.
|
||
- Niezależnie od wyboru: **zero requestów do domeny analitycznej przed
|
||
akceptacją w bannerze cookies** (weryfikacja: DevTools → Network, filtr po
|
||
domenie analitycznej, przed i po kliknięciu „Tylko niezbędne" —
|
||
`wymagania-projektowe-strony.md` §8).
|
||
- Zdarzenia do zdefiniowania: `whatsapp_click` (per lokalizacja CTA — hero,
|
||
finalCta, floating button), `phone_click`, `email_click`, `form_submit`
|
||
(jeśli formularz wdrożony).
|
||
|
||
## 4. SEO — structured data (schema.org)
|
||
|
||
Zgodnie z `antigravity-zasady-agent.md` część C, punkt 12–13 (funkcje już
|
||
częściowo dostarcza plugin — sprawdzić `seo.md` w docs przed pisaniem
|
||
czegokolwiek własnego):
|
||
|
||
| Typ | Gdzie | Dane |
|
||
|---|---|---|
|
||
| `ProfessionalService` (nie generyczny `Organization` — branża regulowana) | root layout, wszystkie strony | nazwa, adres, telefon, logo, `areaServed` (Niemcy), `knowsLanguage` (pl, de) |
|
||
| `WebSite` | root layout | tylko jeśli jest realna wyszukiwarka na stronie (obecnie brak — pominąć `SearchAction`, zgodnie z ostrzeżeniem w `antigravity-zasady-agent.md` „TYLKO jeśli jest realna wyszukiwarka") |
|
||
| `FAQPage` | `/faq` | 1:1 z widoczną treścią pytań/odpowiedzi (patrz [06-faq.md](./06-faq.md) §5) — nie ukryty tekst |
|
||
| `BreadcrumbList` | każda podstrona poza home | z realnej ścieżki (`resolveRoute`/routing pluginu), nie zaszyte |
|
||
| Recenzje/`Review` | **[do rozważenia, NIE wdrażać bez realnych danych]** — 3 testimoniale na home mają tylko imię+miasto, nie są zweryfikowanymi recenzjami z zewnętrznej platformy (Google/Trustpilot); oznaczanie ich jako `AggregateRating`/`Review` w schema.org bez faktycznej platformy-źródła to ryzyko naruszenia wytycznych Google (rich results dla fałszywych/niepotwierdzalnych ocen) |
|
||
|
||
## 5. Wydajność — cele i konkretne działania
|
||
|
||
Core Web Vitals (`wymagania-projektowe-strony.md` §6): LCP < 2,5s, INP < 200ms,
|
||
CLS < 0,1.
|
||
|
||
- **LCP** — obraz hero (`image` w bloku `hero`) musi mieć `priority` w
|
||
`next/image`, prawidłowe `sizes`, i realne warianty rozmiarów z Payload
|
||
(patrz [10-architektura-cms.md](./10-architektura-cms.md) §3) — bez tego
|
||
cel LCP jest nieosiągalny niezależnie od reszty optymalizacji.
|
||
- **CLS** — `floatingStat` w hero, akordeon FAQ (rozwijanie odpowiedzi),
|
||
floating WhatsApp button — wszystkie muszą rezerwować miejsce z góry
|
||
(aspect-ratio/min-height), nie „wskakiwać" po hydratacji.
|
||
- **INP** — Framer Motion już w użyciu (parallax hero) — pilnować, żeby
|
||
ciężkie komponenty (np. przyszły `VideoSection`) ładowały się przez
|
||
`next/dynamic`, nie w głównym bundlu.
|
||
- **Bundle** — sprawdzić `@next/bundle-analyzer`, czy `framer-motion` nie
|
||
przecieka do stron, które go nie potrzebują (strony prawne — czysty tekst —
|
||
nie powinny ciągnąć animacji).
|
||
|
||
## 6. Bezpieczeństwo
|
||
|
||
Zgodnie z `wymagania-projektowe-strony.md` §7 — w większości odpowiedzialność
|
||
pluginu (`buildSecurityHeaders`), do weryfikacji na wdrożonym środowisku:
|
||
- Nagłówki CSP/HSTS/X-Content-Type-Options/Referrer-Policy/Permissions-Policy
|
||
→ Mozilla Observatory, cel ocena A.
|
||
- HTTPS wymuszony, przekierowanie HTTP→HTTPS.
|
||
- Panel administracyjny (`/admin`) — silne hasło, brak wystawienia na
|
||
publiczne indeksowanie (sprawdzić `robots.txt`).
|
||
|
||
## 7. i18n — hreflang i routing
|
||
|
||
- Sprawdzić, czy `hreflang` między `/pl/...` a `/de/...` jest generowany
|
||
przez plugin (powinien, zgodnie z `seo.md`) — zweryfikować narzędziem
|
||
hreflang Tags Testing Tool po wdrożeniu.
|
||
- Przełącznik języka (`LanguageSwitcher`, już w kodzie) musi zachowywać
|
||
bieżącą podstronę (np. z `/pl/uslugi` na `/de/leistungen`, nie na `/de`) —
|
||
to już wygląda na zaimplementowane przez `clientSwitchLocalePath.ts`
|
||
(patrz `.agents/context/plugin-issues.md` w repo) — potwierdzić ręcznym
|
||
testem na każdej z 10 stron, nie tylko na home.
|