Appearance
Angular
@pollyou/angular ist eine Standalone-Komponente für Angular 17.3 und neuer (getestet mit 17.3, 19 und 22). Sie verpackt das Web-Component <pollyou-survey> aus dem Script-Snippet in eine Angular-API mit Signal-Inputs und Outputs, funktioniert mit Zone.js und zoneless und ist SSR-sicher.
Installation
bash
npm install @pollyou/angularts
import { Component } from '@angular/core'
import { PollYouSurveyComponent, type PollYouCompleteEvent } from '@pollyou/angular'
@Component({
selector: 'app-feedback',
standalone: true,
imports: [PollYouSurveyComponent],
template: `
<pollyou-survey-ng
surveyId="AbC123xyz0"
apiBase="https://app.pollyou.org"
(complete)="danke($event)"
/>
`,
})
export class FeedbackComponent {
danke(event: PollYouCompleteEvent) {
console.log('Antwort gespeichert', event.responseId)
}
}AbC123xyz0 ist die öffentliche ID der Umfrage (im Dashboard unter „Teilen“, dort gibt es auch den fertigen Code). Ein CUSTOM_ELEMENTS_SCHEMA ist in Ihrer Anwendung nicht nötig – das regelt die Komponente intern. In Anwendungen mit NgModules wird PollYouSurveyComponent in imports des Moduls eingetragen.
Standardwerte für die ganze App
Mit providePollYou() setzen Sie API-Adresse, Sprache und Farbschema einmal zentral. Inputs einzelner Komponenten haben Vorrang.
ts
import { bootstrapApplication } from '@angular/platform-browser'
import { providePollYou } from '@pollyou/angular'
bootstrapApplication(AppComponent, {
providers: [providePollYou({ apiBase: 'https://app.pollyou.org', locale: 'de' })],
})Ohne apiBase (weder Input noch Provider) verwendet die Umfrage die Adresse der eigenen Seite – das passt nur, wenn PollYou unter derselben Domain läuft.
Inputs
| Input | Typ | Bedeutung |
|---|---|---|
surveyId | string (Pflicht) | Öffentliche ID der Umfrage. |
embedId | string | Embed-Konfiguration (erlaubte Domains, Vorgaben, signierte Identität). |
apiBase | string | Adresse der PollYou-API. Standard: providePollYou, sonst die eigene Seite. |
mode | 'inline' | 'popup' | 'slider' | 'fullpage' | Darstellung, Standard inline; Overlays sichtbar solange open. Auslöser (Verzögerung, Scrolltiefe …) nur über die Embed-Konfiguration, siehe Overlays. |
open | boolean | Popup ist geöffnet (nur mode="popup"). |
locale | string | Sprache, z. B. de. Standard: providePollYou, dann <html lang>, dann der Browser. |
theme | 'auto' | 'light' | 'dark' | Farbschema, Standard auto (folgt dem Dark Mode des Systems). |
showResults | boolean | false blendet Ergebnisse aus, auch wenn die Umfrage sie anzeigen würde. |
liveResults | boolean | Angezeigte öffentliche Ergebnisse aktualisieren sich in Echtzeit (Live-Ergebnisse). |
identityToken | string | Signierte Identität des angemeldeten Nutzers, siehe unten. |
meta | Record<string, string | number | boolean> | Zusatzdaten zur Antwort (höchstens 20 Werte zusammen mit hidden). |
hidden | Record<string, string | number | boolean> | Versteckte Felder, z. B. { kundennummer: 4711 }. |
channel | string | Kanal in den Statistiken, Standard angular. |
Statische Texte schreiben Sie ohne Klammern (surveyId="AbC123xyz0"), alles andere als Property-Binding ([showResults]="false", [hidden]="{ ref: 'newsletter' }").
Outputs
Alle Outputs liefern das detail des jeweiligen pollyou:*-Ereignisses (siehe Ereignisse) und laufen innerhalb der Angular-Zone – Änderungen im Handler werden sofort angezeigt.
| Output | Typ | Wann |
|---|---|---|
(ready) | PollYouReadyEvent | Umfrage geladen: { surveyId, type, status } |
(start) | PollYouStartEvent | Erste Antwort gegeben: { surveyId } |
(answer) | PollYouAnswerEvent | Eine Frage beantwortet: { surveyId, questionKey, answer } |
(complete) | PollYouCompleteEvent | Abgeschickt: { surveyId, responseId, results } |
(close) | PollYouCloseEvent | Popup geschlossen: { surveyId, mode } |
(error) | PollYouErrorEvent | Laden oder Absenden fehlgeschlagen: { surveyId, phase, status } |
Popup
ts
@Component({
selector: 'app-umfrage-button',
standalone: true,
imports: [PollYouSurveyComponent],
template: `
<button type="button" (click)="open = true">Umfrage öffnen</button>
<pollyou-survey-ng surveyId="AbC123xyz0" mode="popup" [open]="open" (close)="open = false" />
`,
})
export class UmfrageButtonComponent {
open = false
}Setzen Sie open im (close)-Handler zurück, damit ein erneuter Klick das Popup wieder öffnet.
Identitäts-Token
Für Umfragen nur für angemeldete Nutzer oder „eine Antwort pro Kunde“ erzeugt Ihr Server ein signiertes Identitäts-Token, das Sie an die Komponente weitergeben:
ts
@Component({
// …
template: `
@if (token(); as token) {
<pollyou-survey-ng surveyId="AbC123xyz0" [identityToken]="token" />
}
`,
})
export class KundenUmfrageComponent {
token = toSignal(inject(HttpClient).get('/api/pollyou-token', { responseType: 'text' }))
}Das Embed-Secret bleibt auf dem Server – erzeugen Sie das Token nie im Browser.
Server-Side Rendering (Angular Universal / @angular/ssr)
Die Komponente ist SSR-sicher: Auf dem Server wird nur das leere Element <pollyou-survey> mit seinen Attributen gerendert. Das Web-Component (@pollyou/embed-core) wird ausschließlich im Browser per dynamischem import() nach dem ersten Rendern (afterNextRender) geladen und landet in einem eigenen Chunk. Mit Hydration übernimmt der Browser das serverseitig gerenderte Element unverändert; die Umfrage lädt anschließend clientseitig. Es ist keine weitere Konfiguration nötig.
Tests
Mit dem Token POLLYOU_LOADER ersetzen Sie das Laden des Web-Components, z. B. in Komponententests:
ts
TestBed.configureTestingModule({
providers: [{ provide: POLLYOU_LOADER, useValue: () => Promise.resolve() }],
})Beispiel-App
Ein lauffähiges Beispiel liegt im Playground: frontend/apps/playground/angular – Angular-CLI-App mit SSR (outputMode: "server"), Standalone-Komponenten und providePollYou(). / wird pro Anfrage serverseitig gerendert, /about beim Build vorgerendert.
Fehlersuche
- Die Umfrage bleibt leer oder zeigt „nicht gefunden“: Nur veröffentlichte Umfragen sind öffentlich; ein Entwurf oder eine archivierte Umfrage liefert 404. Das Ereignis
(error)meldet{ phase: 'load', status }. - Fehler „blocked by CORS policy“ oder
403 origin_not_allowed: Die Embed-Konfiguration erlaubt nur bestimmte Origins. Tragen Sie die Origin Ihrer Seite ein – mit Schema und Port, also auch den lokalen Dev-Server (z. B.http://localhost:5173).apiBaseist die Origin der API ohne Pfad (https://app.pollyou.org, nicht…/api). - Content-Security-Policy: Erlauben Sie die API in
connect-src(z. B.connect-src 'self' https://app.pollyou.org, für Live-Ergebnisse zusätzlich den Hub).script-srcbraucht keinen Eintrag:@pollyou/embed-coreist Teil Ihres Bundles und wird als eigener Chunk von Ihrer Origin nachgeladen. Die Styles setzt das Web-Component per Constructable Stylesheets und CSSOM,'unsafe-inline'instyle-srcist nicht nötig – nur eigenes Theme-CSS wird als<style>eingefügt und fehlt ohne'unsafe-inline'(die Umfrage funktioniert trotzdem). Das Captcha kommt ohne Worker undevalaus. - Lokal in Chrome keine Verbindung zur API: Chrome blockiert mit Local Network Access Anfragen von öffentlichen Seiten an
localhost. Die Seite muss selbst lokal laufen (localhost/127.0.0.1), wie die Apps im Playground. - SSR: „URL with hostname … is not allowed“: Der SSR-Server von Angular prüft den Host der Anfrage. Tragen Sie Ihre Hosts in
angular.jsonunterbuild.options.security.allowedHostsein (der Playground erlaubt127.0.0.1undlocalhost) oder setzen SieNG_ALLOWED_HOSTS. - SSR: leeres Element im HTML: Gewollt – der Server rendert nur
<pollyou-survey>, das Web-Component lädt erst im Browser (afterNextRender). Greifen Sie für die Umfrage-ID nicht aufwindowoderlocationzu (auf dem Server undefiniert), sondern z. B. aufActivatedRoute. - Hydration-Fehler (
NG0500ff.): Entstehen, wenn Server und Browser unterschiedliche Inputs berechnen. Inputs aus Route oder Server-Daten ableiten, nicht aus Browser-APIs.