NPM-pakke med hjelpefunksjoner for nav-dekoratoren (header og footer på nav.no)
- Node.js v18 eller nyere er påkrevd, ettersom vi ikke lengre benytter node-fetch. (Node 18 har fetch innebygd)
- Server-side fetch-funksjoner benytter nå service discovery som default. Dette krever visse access policy regler.
- Parametre til fetch-funksjoner er endret, slik at query-parametre til dekoratøren nå er et separat objekt.
Eksempel 1.x -> 2.0:{ env: "prod", context: "arbeidsgiver", simple: true}
->{ env: "prod", params: { context: "arbeidsgiver", simple: true }}
) - Ved bruk av
env: "localhost"
må dekoratørens url nå alltid settes med parameteretlocalUrl
. Dette erstatter parametereneport
ogdekoratorenUrl
, og vi har ikke lengre en default localhost url. - Flere typer er endret eller har fått mer spesifikke navn (f.eks.
Params
->DecoratorParams
)
npm install --save @navikt/nav-dekoratoren-moduler
Obs! Pakkene publiseres nå kun i GitHub Packages registry'et. For å kunne installere nyere versjoner må pakker fra @navikt-orgen scopes til GitHub Packages.
- Legg til dette i
.npmrc
-fila for prosjektet. Opprett fila på rot i prosjektet hvis den ikke finnes.
@navikt:registry=https://npm.pkg.github.com
- Opprett et PAT med
read:packages
scope, og bruk dette som passord ved login.
npm login --registry=https://npm.pkg.github.com --auth-type=legacy
- Sett registry url med f.eks.
actions/setup-node
:
- name: Setup node.js
uses: actions/setup-node@v3
with:
registry-url: 'https://npm.pkg.github.com'
- Sett
NODE_AUTH_TOKEN
pånpm ci
.READER_TOKEN
er en navikt org-wide secret til dette formålet.
- name: Install dependencies
run: npm ci
env:
NODE_AUTH_TOKEN: ${{ secrets.READER_TOKEN }}
Pakka inneholder funksjoner for å laste inn dekoratøren i apper på ulike måter.
Samtlige funksjoner for fetch av dekoratøren tar inn parametre med følgende type:
type DecoratorNaisEnv =
| "prod" // For produksjons-instans av dekoratøren
| "dev" // For stabil dev-instans
| "beta" // Beta dev-instanser ment for internt test-bruk
| "betaTms" // Disse kan være ustabile i lengre perioder
| "devNext"; // dev-instans av decorator-next
| "prodNext"; // prod-instans av decorator-next
// decorator-next er under utvikling og er ikke klar for generell bruk
type DecoratorEnvProps =
// Dersom env er satt til localhost, må du selv sette url for dekoratøren.
| { env: "localhost"; localUrl: string }
// For nais-miljøer settes url automatisk
| { env: DecoratorNaisEnv; serviceDiscovery?: boolean };
type DecoratorFetchProps = {
// Query-parametre til dekoratøren, se dekoratørens readme for dokumentasjon
params?: DecoratorParams;
} & DecoratorEnvProps;
Server-side fetch-funksjonene benytter service discovery som default fra versjon 2.0. Vær obs på at dette kun fungerer ved kjøring på dev-gcp eller prod-gcp nais-clusterne. Dersom appen ikke kjører i ett av disse clusterne, vil vi falle tilbake til å kalle eksterne ingresser.
Du kan også sette parameteret serviceDiscovery: false
for å alltid benytte eksterne ingresser.
fetchDecoratorHtml({
env: "prod",
serviceDiscovery: false,
});
Se nais doc for oppsett av access policy.
Ved bruk av service discovery må følgende regel inkluderes i access policy:
accessPolicy:
outbound:
rules:
- application: nav-dekoratoren
namespace: personbruker
Dersom service discovery ikke benyttes, vil dekoratørens eksterne ingresser kalles. Dette gjelder ved bruk av versjon 1.9 eller tidligere, eller dersom serviceDiscovery: false
er satt.
Følgende access policy kreves:
accessPolicy:
outbound:
external:
- host: www.nav.no # for prod
- host: dekoratoren.ekstern.dev.nav.no # for dev
Server-side rendering av dekoratøren anbefales for optimal brukeropplevelse. Dersom kallet feiler (etter 3 retries), faller vi tilbake til statiske placeholder-elementer som client-side rendres.
Setter inn dekoratøren i en HTML-fil eller et JSDOM-objekt, og returnerer en HTML-string.
Bruk med HTML-fil:
import { injectDecoratorServerSide } from "@navikt/nav-dekoratoren-moduler/ssr";
injectDecoratorServerSide({
env: "prod",
filePath: "index.html",
params: { context: "privatperson", simple: true },
}).then((html) => {
res.send(html);
});
Bruk med JSDOM-objekt:
import { injectDecoratorServerSideDom } from "@navikt/nav-dekoratoren-moduler/ssr";
injectDecoratorServerSideDom({
env: "prod",
dom: myJsDomObject,
params: { context: "privatperson", simple: true },
}).then((html) => {
res.send(html);
});
Henter dekoratøren som HTML-fragmenter.
Eksempel på bruk:
import { fetchDecoratorHtml } from "@navikt/nav-dekoratoren-moduler/ssr";
const fragments = await fetchDecoratorHtml({
env: "dev",
params: { context: "privatperson" },
});
const {
DECORATOR_STYLES,
DECORATOR_SCRIPTS,
DECORATOR_HEADER,
DECORATOR_FOOTER,
} = fragments;
// Sett inn fragmenter i app-html'en med f.eks. en template engine
Henter dekoratøren som React-komponenter. Kan benyttes med React rammeverk som støtter server-side rendering.
Eksempel på bruk med next.js (settes inn i en custom _document page):
import { fetchDecoratorReact } from "@navikt/nav-dekoratoren-moduler/ssr";
class MyDocument extends Document<DocumentProps> {
static async getInitialProps(ctx: DocumentContext) {
const initialProps = await Document.getInitialProps(ctx);
const Decorator = await fetchDecoratorReact({
env: "prod",
params: { language: "no", context: "arbeidsgiver" },
});
return { ...initialProps, Decorator };
}
render() {
const { Decorator } = this.props;
return (
<Html lang={"no"}>
<Head>
<Decorator.Styles />
</Head>
<body>
<Decorator.Header />
<Main />
<Decorator.Footer />
<Decorator.Scripts />
<NextScript />
</body>
</Html>
);
}
}
CSR vil gi en redusert brukeropplevelse pga layout-shifting/"pop-in" når headeren rendres, og bør unngås om mulig.
Setter inn dekoratøren i DOM'en client-side. Service discovery kan ikke benyttes ved client-side injection.
Eksempel på bruk:
import { injectDecoratorClientSide } from "@navikt/nav-dekoratoren-moduler";
injectDecoratorClientSide({
env: "prod",
params: {
simple: true,
chatbot: true,
},
});
Dersom env
er satt til localhost
må dekoratørens URL settes med parametret localUrl
. Benyttes dersom du f.eks. kjører dekoratøren lokalt på egen maskin, eller den hentes via en proxy.
Eksempel:
injectDecoratorServerSide({
filePath: "index.html",
env: "localhost",
localUrl: "http://localhost:8088/dekoratoren",
});
Bygger en Content-Security-Policy header som inkluderer dekoratørens påkrevde direktiver, kombinert med applikasjonens egne direktiver.
Funksjonen gjør et fetch-kall til dekoratøren for å hente gjeldende direktiver.
Eksempel på bruk:
import { buildCspHeader } from "@navikt/nav-dekoratoren-moduler/ssr";
// Direktiver appen din benytter
const myAppDirectives = {
"default-src": ["foo.bar.com"],
"style-src": ["my.css.cdn.com"],
};
const csp = await buildCspHeader(myAppDirectives, { env: "prod" });
app.get("*", (req, res) => {
res.setHeader("Content-Security-Policy", csp);
res.send("Hello!");
});
Sender events til Amplitude via dekoratørens klient.
Eksempel på bruk:
import { getAmplitudeInstance } from "@navikt/nav-dekoratoren-moduler";
const logger = getAmplitudeInstance("dekoratoren");
logger("skjema åpnet", {
skjemaId: 1234,
skjemanavn: "aap",
});
Du kan også utvide taxonomien som er definert for å tilpasse ditt bruk. Det har ingen funksjonell effekt, men vil gjøre det lettere for utviklerene i prosjektet å følge en standard hvis ønskelig.
Eksempel på å definere events:
import {
AmplitudeEvent,
getAmplitudeInstance,
} from "@navikt/nav-dekoratoren-moduler";
type SampleCustomEvents =
| AmplitudeEvent<"first", { hei: string }>
| AmplitudeEvent<"second", { hei: string }>;
const logger = getAmplitudeInstance<SampleCustomEvents>("dekoatoren");
logger("first", {
hei: "hei",
});
Parameteret enforceLogin
i dekoratøren sender brukeren til loginservice ved for lavt innloggingsnivå.
Ulempen er at applikasjonen din kan laste før frontend-kallet mot nav-dekoratoren-api er ferdig og dekoratøren sender brukeren til loginservice.
EnforceLoginLoader
er en wrapper for applikasjonen som viser en spinner mens sjekken pågår. Funksjonen authCallback
trigges etter vellykket innlogging og benyttes for å hente ut brukerens navn ved behov.
import React, { Component } from "react";
import { EnforceLoginLoader } from "@navikt/nav-dekoratoren-moduler";
const Wrapper = () => {
const authCallback = (auth: Auth) => {
console.log(auth);
};
return (
<EnforceLoginLoader authCallback={authCallback}>
<App />
</EnforceLoginLoader>
);
};
ReactDOM.render(<Wrapper />, document.getElementById("app"));
Parameteret breadcrumbs
(brødsmulestien) kan endres / settes på klient-siden ved behov.
Obs! Klikk på breadcrumbs logges til analyseverktøy (Amplitude). Dersom title kan inneholde sensitive opplysninger som f.eks. navn på bruker, må feltet analyticsTitle også settes. Dette feltet vil da logges istedenfor title.
// Type
export type DecoratorBreadcrumb = {
url: string;
title: string;
analyticsTitle?: string;
handleInApp?: boolean;
};
// Bruk
import { setBreadcrumbs } from "@navikt/nav-dekoratoren-moduler";
setBreadcrumbs([
{ title: "Ditt NAV", url: "https://www.nav.no/person/dittnav" }, // Sender brukeren til definert url
{
title: "Kontakt oss",
url: "https://www.nav.no/person/kontakt-oss/nb/",
handleInApp: true, // Håndteres av onBreadcrumbClick
},
]);
// Bruk med analyticsTitle
setBreadcrumbs([
{ title: "Ditt NAV", url: "https://www.nav.no/person/dittnav" }, // Sender brukeren til definert url
{
title: "Opplysninger for Ola Nordmann",
analyticsTitle: "Opplysninger for <Navn>",
url: "https://www.nav.no/min-innloggede-tjeneste",
},
]);
Kalles med breadcrumb
-parametre dersom handleInApp
var satt til true
. Kan benyttes for client-side routing.
import { onBreadcrumbClick } from "@navikt/nav-dekoratoren-moduler";
import router from "my-routing-library";
onBreadcrumbClick((breadcrumb) => {
router.push(breadcrumb.url);
});
Parameteret languages
(liste av tilgjengelige språk i språkvelgeren) kan endres / settes client-side ved behov.
Aktivt språk kan hentes ut fra cookien decorator-language
.
// Type
export type DecoratorLocale = "nb" | "nn" | "en" | "se" | "pl" | "uk" | "ru";
export type DecoratorLanguageOption =
| {
url?: string;
locale: DecoratorLocale;
handleInApp: true;
}
| {
url: string;
locale: DecoratorLocale;
handleInApp?: false;
};
// Bruk
import { setAvailableLanguages } from "@navikt/nav-dekoratoren-moduler";
setAvailableLanguages([
{ locale: "nb", url: "https://www.nav.no/person/kontakt-oss/nb/" }, // Sender brukeren til definert url
{
locale: "en",
url: "https://www.nav.no/person/kontakt-oss/en/",
handleInApp: true,
}, // Håndteres av onLanguageSelect
]);
Kalles med language
-parametre dersom handleInApp
var satt til true
. Kan benyttes for client-side routing.
import { onLanguageSelect } from "@navikt/nav-dekoratoren-moduler";
import router from "my-routing-library";
onLanguageSelect((language) => {
router.push(language.url);
});
Samtlige parametre kan settes client-side via setParams
dersom setAvailableLanguages
og setBreadcrumbs
ikke er tilstrekkelig.
// Type
export type DecoratorParams = Partial<{
context: "privatperson" | "arbeidsgiver" | "samarbeidspartner";
simple: boolean;
simpleHeader: boolean;
simpleFooter: boolean;
enforceLogin: boolean;
redirectToApp: boolean;
redirectToUrl: string;
level: string;
language: DecoratorLocale;
availableLanguages: DecoratorLanguageOption[];
breadcrumbs: DecoratorBreadcrumb[];
utilsBackground: "white" | "gray" | "transparent";
feedback: boolean;
chatbot: boolean;
chatbotVisible: boolean;
urlLookupTable: boolean;
shareScreen: boolean;
logoutUrl: string;
logoutWarning: boolean;
}>;
// Bruk
import { setParams } from "@navikt/nav-dekoratoren-moduler";
setParams({
simple: true,
chatbot: true,
});
Grensesnittet (header, meny etc) finnes i tre språkdrakter: norsk bokmål (nb), engelsk (en) og delvis samisk (se).
Du kan angi at språkvelgeren skal støtte flere språk enn dette, som beskrevet i seksjonen ovenfor, men det er kun disse tre språkene som kan vises i selve dekoratør-grensesnittet. For de resterende språkene som språkvelgeren støtter, så vil "nærmeste" relevante språk vises istedet, feks:
- nn => nb
- pl => en
- ru => en
Hjelpefunksjon for å åpne Chatbot Frida. Denne setter parameteret chatbotVisible=true
og åpner chat-vinduet.
import { openChatbot } from "@navikt/nav-dekoratoren-moduler";
openChatbot();