بنقرة واحدة
lumi-survey
Integrer @navikt/lumi-survey tilbakemeldingswidget i en Nav-frontendapplikasjon
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Integrer @navikt/lumi-survey tilbakemeldingswidget i en Nav-frontendapplikasjon
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Utforsk designkonsepter visuelt med Aksel-tema i nettleser, og lever som Figma-skisse. Brukes via /prototype når et konsept skal visualiseres.
Klarsprak-skillen veileder klarspråk og språkvask av feilmeldinger, mikrotekst og AI-markører i norsk tekst. Brukes via /klarsprak når brukeren ber om klarspråk, språkvask, AI-markører, feilmeldinger eller mikrotekst.
Feilsøking av runtime-problemer i Nav-miljø — pod crash, OOMKilled, 401/403, auth-feil, Kafka lag, DB-timeout, Flyway-feil, logger og Nais-diagnostikk. Brukes via /nav-troubleshoot ved driftsfeil.
Sikkerhetsgjennomgang for Nav-applikasjoner — PII, FNR, helseopplysninger, secrets, logging, auditlogg, accessPolicy, eksterne integrasjoner, DPIA og sikkerhetschampion. Brukes via /security-review ved sikkerhetsreview.
UU/WCAG-review for Nav-frontend — tastaturflyt, skjermleser, axe, kontrast, fokus, feilmeldinger, skjema og Aksel-bruk. Brukes via /accessibility-review før PR eller release.
Dulting (nudging) i Nav-tjenester — utforsk muligheter, design intervensjoner og prototype med EAST, Fogg og FORGOOD-etikk. Brukes via /dulting ved utforsking av dulting-muligheter eller design av atferdsintervensjoner.
| name | lumi-survey |
| description | Integrer @navikt/lumi-survey tilbakemeldingswidget i en Nav-frontendapplikasjon |
Legg til en Lumi Survey-widget i applikasjonen din. Dekker installasjon, survey-konfigurasjon, backend-transportendepunkt og NAIS-oppsett.
Før du gjør endringer, kartlegg eksisterende oppsett:
package.json for eksisterende avhengigheter — er @navikt/ds-react og @navikt/ds-css installert?@navikt/ds-react ≥ 8.0.0). Lumi Survey krever v8. Hvis appen er på v7 eller lavere, må Aksel oppgraderes først — det er utenfor scope for denne skillen.tokenx, azure.application) og accessPolicy@navikt/lumi-survey-bruk (grep -r "lumi-survey" --include="*.ts" --include="*.tsx")_app.tsx, layout.tsx, main.tsx, root.tsx)Etter kartleggingen bør du ha svar på disse — de styrer resten av integrasjonen:
| Funn | Brukes i |
|---|---|
| Aksel-versjon (v8+ = ok, lavere = stopp) | Gate — ikke fortsett uten v8 |
| Rammeverk (Next.js / TanStack Start / Remix / etc.) | Fase 3c (stil-import), Fase 5 (backend-mønster) |
| Auth-type (TokenX / AzureAD / begge / ingen) | Fase 2 (auto-deteksjon), Fase 5 (endepunkt), Fase 6 (NAIS-konfig) |
| Stil-entry point (filnavn) | Fase 3c (der stiler importeres) |
| Backend-type (Node.js BFF / Kotlin BFF / annet) | Fase 5 (hvilken mal som brukes) |
| Eksisterende lumi-survey? | Hvis ja → tilpass eksisterende, ikke ny integrasjon |
Bruk disse funnene aktivt i de neste fasene — de bestemmer hvilke maler og konfigurasjoner som genereres.
Før du genererer kode, avklar det som trengs. Bruk kartleggingen fra Fase 1 til å besvare så mye som mulig automatisk — spør bare utvikleren om det du ikke kan utlede.
Les NAIS-manifestet fra Fase 1 og bestem auth-type:
| Funn i manifest | Auth-type | Audience-format |
|---|---|---|
tokenx.enabled: true | TokenX | <cluster>:team-esyfo:lumi-api |
azure.application.enabled: true | AzureAD | api://<cluster>.team-esyfo.lumi-api/.default |
| Begge er aktivert | Avhenger av brukergruppe — spør utvikleren | Se over |
| Ingen av delene | Auth mangler — spør utvikleren om oppsett | — |
Hvis auth-type er entydig, ikke spør — informer utvikleren om hva du fant: "Jeg ser at appen bruker TokenX. Bruker det for Lumi-integrasjonen."
Spør kun hvis det er tvetydig eller mangler.
Spør: "Hva slags tilbakemelding vil du samle inn?"
Presenter alternativer med anbefalinger:
| Type | Passer best for | Anbefaling |
|---|---|---|
| Rating (emoji 😡🙁😐😀😍) | Generell tilfredshet — "hvordan var opplevelsen?" | ✅ Anbefalt standard. Enkel, høy fullføringsrate. |
| Rating (tommel 👎👍) | Rask binær tilbakemelding på en spesifikk funksjon | Bra for målrettet, lavterskel feedback |
| Discovery | Forstå brukermål — "hva prøvde du å gjøre?" | Best for nye tjenester eller store redesign |
| Top Tasks | Måle oppgavesuksess/-feilrate (McGovern-metoden) | Best for etablerte tjenester med kjente brukeroppgaver |
| Task Priority | Rangere hva som betyr mest for brukerne (Long Neck-metoden) | Best for veikartprioritering |
| Tilpasset | Skreddersydde spørsmålsflyter med forgreningslogikk | Kun når forhåndsdefinerte typer ikke passer |
Hvis utvikleren er usikker, anbefal Rating med emoji-variant — det er det mest utprøvde mønsteret i Nav.
Hvis utvikleren valgte en rating-survey, spør: "Vil du ha et oppfølgingsspørsmål ved lav score? (anbefalt: ja — fritekstfelt ved score ≤ 2)"
Anbefaling: Ja — fritekst ved lav rating gir handlingsbar innsikt med minimal brukerbelastning. DEFAULT_SURVEY_RATING har dette innebygd.
For andre survey-typer (Discovery, Top Tasks, etc.) har de innebygde oppfølgingsspørsmål allerede — ikke spør.
Sjekk om .npmrc allerede har GitHub Packages-konfig. Hvis ikke:
@navikt:registry=https://npm.pkg.github.com
npm install @navikt/lumi-survey
Peer-avhengigheter (@navikt/ds-react, @navikt/ds-css) er vanligvis allerede installert i Nav-apper. Hvis ikke:
npm install @navikt/ds-react @navikt/ds-css
I appens globale stil-entry point (identifisert i Fase 1), sørg for denne importrekkefølgen:
import "@navikt/ds-css"; // Må komme først
import "@navikt/lumi-survey/styles.css"; // Deretter lumi-survey
Viktig: @navikt/ds-css MÅ importeres før @navikt/lumi-survey/styles.css.
Lag en egen fil for survey-konfigurasjonen (f.eks. survey.ts eller lumiSurvey.ts). Bruk satisfies LumiSurveyConfig for typesikkerhet.
Guiding: Basert på survey-typen valgt i Fase 2, hjelp utvikleren med å bygge opp konfigurasjonen steg for steg. Tilpass spørsmålstekster til tjenesten — bruk norsk og vær konkret.
import type { LumiSurveyConfig } from "@navikt/lumi-survey";
export const survey = {
type: "rating",
questions: [
{
id: "inntrykk",
type: "rating",
variant: "emoji", // "emoji" | "thumbs" | "stars" | "nps"
prompt: "Hva er ditt inntrykk av tjenesten?",
required: true,
},
{
id: "innspill",
type: "text",
prompt: "Har du noen kommentarer eller innspill?",
maxLength: 1000,
visibleIf: {
field: "ANSWER",
questionId: "inntrykk",
operator: "EXISTS",
},
},
],
} satisfies LumiSurveyConfig;
Tilpass til tjenesten:
prompt-tekster til noe som passer appen (f.eks. "Hvordan var det å søke om sykepenger?")visibleIf — vis oppfølging kun ved lav score (operator: "LT", value: 3) eller alltid (operator: "EXISTS")import type { LumiSurveyConfig } from "@navikt/lumi-survey";
export const survey = {
type: "discovery",
questions: [
{
id: "oppgave",
type: "text",
prompt: "Hva prøvde du å gjøre i dag?",
maxLength: 500,
required: true,
},
{
id: "fullfort",
type: "singleChoice",
prompt: "Fikk du gjort det du kom for?",
options: [
{ value: "ja", label: "Ja" },
{ value: "delvis", label: "Delvis" },
{ value: "nei", label: "Nei" },
],
required: true,
},
{
id: "blokkering",
type: "text",
prompt: "Hva hindret deg?",
maxLength: 1000,
visibleIf: {
field: "ANSWER",
questionId: "fullfort",
operator: "EQ",
value: "nei",
},
},
],
} satisfies LumiSurveyConfig;
import type { LumiSurveyConfig } from "@navikt/lumi-survey";
export const survey = {
type: "topTasks",
questions: [
{
id: "oppgave",
type: "singleChoice",
prompt: "Hva kom du hit for å gjøre?",
options: [
{ value: "soke", label: "Søke om ytelse" },
{ value: "status", label: "Sjekke status på søknad" },
{ value: "dokument", label: "Sende inn dokumentasjon" },
{ value: "annet", label: "Annet" },
],
randomize: true,
required: true,
},
{
id: "fullfort",
type: "singleChoice",
prompt: "Fikk du gjort det?",
options: [
{ value: "ja", label: "Ja" },
{ value: "delvis", label: "Delvis" },
{ value: "nei", label: "Nei" },
],
required: true,
},
{
id: "blokkering",
type: "text",
prompt: "Hva hindret deg?",
maxLength: 1000,
visibleIf: {
field: "ANSWER",
questionId: "fullfort",
operator: "NEQ",
value: "ja",
},
},
],
} satisfies LumiSurveyConfig;
import type { LumiSurveyConfig } from "@navikt/lumi-survey";
export const survey = {
type: "taskPriority",
questions: [
{
id: "viktigst",
type: "multiChoice",
variant: "checkbox",
prompt: "Hvilke oppgaver er viktigst for deg? (velg inntil 5)",
maxSelections: 5,
randomize: true,
options: [
{ value: "soke", label: "Søke om ytelse" },
{ value: "status", label: "Sjekke status" },
{ value: "dokument", label: "Sende dokumentasjon" },
{ value: "endring", label: "Melde endring" },
{ value: "utbetaling", label: "Se utbetalinger" },
// Legg til 15-40 oppgaver for robust Long Neck-analyse
],
required: true,
},
],
} satisfies LumiSurveyConfig;
Anbefaling: Inkluder 20-50 oppgaver for god Long Neck-analyse. Bruk randomize: true for å unngå rekkefølgebias.
| Type | Beskrivelse | Viktige props |
|---|---|---|
rating | Skala (emoji/tommel/stjerner/NPS) | variant, prompt, required |
text | Fritekst | prompt, maxLength, minRows, placeholder |
singleChoice | Velg én | prompt, options, randomize |
multiChoice | Velg flere | prompt, options, maxSelections, variant ("checkbox" | "combobox") |
visibleIfVis spørsmål basert på tidligere svar:
| Operator | Betydning | Eksempel |
|---|---|---|
EXISTS | Spørsmålet er besvart | Vis oppfølging uansett hva de svarte |
LT | Mindre enn (tall) | Vis ved lav rating (value: 3) |
GT | Større enn (tall) | Vis ved høy rating |
EQ | Lik (tekst/tall) | Vis ved spesifikt svar (value: "nei") |
NEQ | Ulik | Vis når svaret IKKE er en bestemt verdi |
CONTAINS | Inneholder (multi-choice) | Vis når et bestemt valg er valgt |
Transporten kobler widgeten til ditt backend-endepunkt:
import type { LumiSurveyTransport } from "@navikt/lumi-survey";
const transport: LumiSurveyTransport = {
async submit(submission) {
const response = await fetch("/api/lumi/feedback", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(submission.transportPayload),
});
if (!response.ok) {
throw new Error(`Lumi feedback-innsending feilet: ${response.status}`);
}
},
};
import { LumiSurveyDock } from "@navikt/lumi-survey";
import { survey } from "./survey";
<LumiSurveyDock
surveyId="<app-navn>-feedback"
survey={survey}
transport={transport}
/>
Velg en unik surveyId — bruk appnavnet som prefiks (f.eks. "sykepengesoknad-feedback", "modia-satisfaction"). Denne ID-en identifiserer surveyen i Lumi-dashboardet.
Send med metadata for å muliggjøre filtrering i Lumi-dashboardet:
<LumiSurveyDock
surveyId="<app-navn>-feedback"
survey={survey}
transport={transport}
context={{
tags: {
// Lav kardinalitet — disse blir filterdimensjoner i dashboardet
feature: "new-ui",
role: "employer",
},
}}
/>
Regler for kontekst:
tags: Kun verdier med lav kardinalitet (A/B-testgrupper, roller, features)debug: Høy kardinalitet tillatt (sesjons-ID-er, request-ID-er)For offentlige sider med Nav-dekoratøren (nav.no): standard consent-strategi fungerer automatisk.
For interne apper (Modia, admin-verktøy) uten dekoratøren:
<LumiSurveyDock
behavior={{ storageStrategy: "localStorage" }}
{...otherProps}
/>
Merk:
localStoragebrukes kun for ikke-sensitiv survey UX-state (f.eks. om brukeren har sett/lukket undersøkelsen). Aldri lagre tokens, PII eller sensitiv data i localStorage.
Se references/backend-transport.md for komplette backend-maler (Node.js og Kotlin).
Se references/nais-konfigurasjon.md for NAIS-manifest og accessPolicy-oppsett.
Etter implementasjon, verifiser hele flyten:
@navikt/lumi-survey installert og stiler importert (ds-css FØR lumi-survey)@navikt/ds-react ≥ 8.0.0)LumiSurveyDock rendres i appen med en unik surveyIdsatisfies LumiSurveyConfigsubmit-funksjon kaller ditt backend-endepunktLUMI_FEEDBACK_PATHLUMI_API_HOST, LUMI_AUDIENCE, LUMI_FEEDBACK_PATH og accessPolicy/api/tokenx/..., AzureAD → /api/azure/...)Hvis du bare vil komme raskt i gang uten skreddersøm, finnes det ferdige presets:
import { LumiSurveyDock, DEFAULT_SURVEY_RATING } from "@navikt/lumi-survey";
<LumiSurveyDock surveyId="<app-navn>-feedback" survey={DEFAULT_SURVEY_RATING} transport={transport} />
| Import | Type | Beskrivelse |
|---|---|---|
DEFAULT_SURVEY_RATING | Rating (emoji) | 5-punkts emoji + tekstoppfølging ved lav score |
DEFAULT_SURVEY_THUMBS | Rating (tommel) | Binær tommel opp/ned + tekstoppfølging |
DEFAULT_SURVEY_STARS | Rating (stjerner) | 5-stjerners rating + tekstoppfølging |
DEFAULT_SURVEY_NPS | Rating (NPS) | 0-10 Net Promoter Score |
DEFAULT_SURVEY_DISCOVERY | Discovery | Mål + fullføring + blokkeringsanalyse |
DEFAULT_SURVEY_SERVICE_FEEDBACK | Service feedback | Rating + forhåndsdefinerte årsaker + tekst |
Anbefaling: Bruk presets kun for rask prototyping. For produksjon, lag en skreddersydd konfigurasjon (Fase 4a) med spørsmålstekster tilpasset tjenesten.
Se references/avansert-konfigurasjon.md for forgreningslogikk, events og øvrige avanserte tilpasninger.