This is a frontend application that provides a unified header/footer for applications running on nav.no. All frontend applications that target the public should use the Decorator to create a cohesive user experience on nav.no.
The Decorator also offers common functionality such as login, analytics, logout warning, search functionality, etc as explained in this documentation.
If you have any questions or suggestions for improvements regarding the Decorator or this documentation, please contact us on the Slack channel #dekoratøren_på_navno
. If you wish to contribute or simply want to run the Decorator locally, refer to CONTRIBUTING.md for detailed documentation on how the Decorator works under the hood.
Important announcements are posted on #dekoratøren_på_navno
, so we encourage teams that use the Decorator to join this channel.
You can use the Decorator through both SSR (server-side rendering) and CSR (client-side rendering). We recommend implementing the Decorator via SSR because it results in fewer layout shifts when your application loads, thereby providing a better user experience.
We recommend using the NPM package @navikt/nav-dekoratoren-moduler, which offers several useful functions for implementating the Decorator and related features.
The Decorator consists of four HTML strings which must be injected into the HTML of your application. These are served from the /ssr
endpoint of the Decorator:
{
"headAssets": "CSS, favicons, etc. Should be injected into the <head> element",
"header": "Header content, should be injected just before your app content",
"footer": "Footer content, should be injected just after your app content",
"scripts": "<script> elements, can be injected anywhere"
}
Example:
fetch("https://www.nav.no/dekoratoren/ssr?context=privatperson&language=en")
.then(res => res.json())
.then(decoratorElements => {
const { headAssets, header, footer, scripts } = decoratorElements;
/*
inject these four elements into your applications HTML response
*/
});
CSR can cause layout shifts as well as multiple asset requests, which might delay the First Contentful Paint (FCP) in your application.
<html>
<head>
<link href="https://github.com/navikt/nav-dekoratoren/blob/main/{INGRESS_URL}/css/client.css" rel="stylesheet" />
</head>
<body>
<div id="decorator-header"></div>
{
YOUR_APP
}
<div id="decorator-footer"></div>
<div id="decorator-env" data-src="https://github.com/navikt/nav-dekoratoren/raw/main/{INGRESS_URL}/env?{PARAMETERS}"></div>
<script async="true" src="https://github.com/navikt/nav-dekoratoren/raw/main/{INGRESS_URL}/client.js"></script>
</body>
</html>
The Decorator is served through both service hosts and regular ingresses. If you're using @navikt/nav-dekoratoren-moduler
, this is all handled automatically, depending on your env
parameter.
Note: The beta instances of the Decorator are intended for internal testing by Team Personbruker. These instances may be unstable for extended periods.
You can configure the Decorator to suit your needs. If you're using @navikt/nav-dekoratoren-moduler
, you can pass a configuration object when initializing the Decorator. If you're implementing your own solution and fetching the Decorator directly, you can configure it by passing query parameters as part of the fetch url request.
All parameters can be set client-side unless explicitly mentioned as a server-render feature only. For more details, see client-side.
Configuration | Type | Default | Explanation |
---|---|---|---|
context | privatperson / arbeidsgiver / samarbeidspartner | privatperson | Set the menu and the context selector in the header |
simple | boolean | false | Shows a simplified header and footer |
simpleHeader | boolean | false | Shows a simplified header |
simpleFooter | boolean | false | Shows a simplified footer |
redirectToApp | boolean | false | Directs the user back to current URL after login |
redirectToUrl | string | undefined | Directs the user to the url after login |
redirectToUrlLogout | string | undefined | Directs the user to the url after logout |
language | nb / nn / en / se / pl / uk / ru | nb | Sets the current language |
availableLanguages | [{ locale: nb / nn / en / se / pl, url: string, handleInApp?: string }] | [ ] | Sets the available languages that are selectable via the language selector |
breadcrumbs | [{ title: string, url: string, handleInApp?: string }] | [ ] | Sets the bread crumbs |
utilsBackground | white / gray / transparent | transparent | Sets the background color for the breadcrumbs and language selector |
feedback | boolean | false | Show or hide the feedback component |
chatbot | boolean | true | Activate or deactivate the chatbot (Frida) |
chatbotVisible | boolean | false | Show or hide the chatbot (Frida ) |
shareScreen | boolean | true | Activate or deactivate the screen sharing feature in the footer |
logoutUrl | string | undefined | Sets the URL for logging out |
maskHotjar | boolean | true | Mask the entire HTML DOM for HotJar |
logoutWarning | boolean | true | Activate or deactivate the Logout Warning |
redirectOnUserChange | boolean | false | Redirects to nav.no if different user is logged in |
This applies to both automatic login and when the login button is clicked. The default setting is false
, which will redirect the user to the "Mitt Nav" application after login.
This will redirect the browser to the specified URL after login. This will override the redirectToApp
configuration that was set. This applies to both automatic login and when the login button is clicked.
Applies both to both automatic logout (after seeing the logout warning) and when clicking the logout button.
The language is automatically set client-side if the current URL contains /no/, /nb/, /nn/, /en/, or /se/. This will override any language parameter that is set. Please note that the actual UI of the Decorator can only display its own textual content and menu in nb
, en
, and se
(partial support). For more information, see "Language support and dropdown menu."
If your application supports multiple locales, you can populate the built-in language selector in the Decorator, allowing users to switch languages. This list can also be updated client-side, for example, if certain routes in your application support specific languages while others do not.
Use setAvailableLanguages
and onLanguageSelect
.
If you set handleInApp
to true
, you must handle actions like route changes yourself.
Note that url
is limited to the domain nav.no
and any sub domain. Any other URL will result in the Decorator returning a 500 server error on request.
Can be set client-side with setBreadcrumbs and onBreadcrumbClick
Note that url
is limited to the domain nav.no
and any sub domain. Any other url will result in the Decorator returning 500 server error on request.
If this is set to false, the chatbot will not be initialized. This means that it will never be available to the page or application, even if the user has an active chat session.
Shows or hides Chatbot Frida. If this is set to true
, the floating chatbot icon will always be visible. When set to false
, the chatbot will only be visible if the user has an active chat session. Please note that chatbotVisible
will have no effect if the chatbot
argument above is set to false.
If set, the Decorator will delegate all logout handling to the specified URL. This means that everything related to logout must be handled by the app! This includes, but is not limited to, cookie clearing and session invalidation. Use with care!
Not to be confused with the redirectToUrlLogout
attribute, which sets the final redirect URL after the user has been successfully logged out.
Sets the data-hj-suppress
attribute on the HTML element, which prevents Hotjar from capturing any actual content on the page. The default is true
. If this is set to false
, you must ensure that elements containing personal information or other sensitive data are masked similarly. This is crucial for complying with privacy regulations. See the Hotjar documentation for more details.
The Decorator’s own elements that contain personal information are masked regardless of this parameter. This cannot be changed client-side.
A modal will display after 55 minutes of login time, allowing the user to extend the session by another 60 minutes or to log out immediately. This serves both as a convenience for the user and to meet WCAG accessibility requirements.
If you choose to disable this feature, you will need to implement a similar logout warning yourself.
If set to true, the page will redirect to nav.no if there is a change of current user in header and authenticated user on server. May occur if user has multiple windows open, and a new user logs in in one of them, and then navigates to a window the old user had open.
Example 1 - Set context:
https://www.nav.no/dekoratoren/?context=arbeidsgiver
Example 2 - Language selector:
https://www.nav.no/dekoratoren/?availableLanguages=[{"locale":"nb","url":"https://www.nav.no/person/kontakt-oss"},{"locale":"en","url":"https://www.nav.no/person/kontakt-oss/en/"}]
Example 3 - Bread crumbs:
https://www.nav.no/dekoratoren/?breadcrumbs=[{"url":"https://www.nav.no/person/dittnav","title":"Ditt Nav"},{"url":"https://www.nav.no/person/kontakt-oss","title":"Kontakt oss"}]
The Decorator provides a range of functionalities so that you don't have to build them yourself.
You can find the current CSP directives at https://www.nav.no/dekoratoren/api/csp. You may also inspect the actual code at content-security-policy.ts for a better understanding of how CSP works.
The @navikt/nav-dekoratoren-moduler
package also offers methods for generating a CSP header that is compatible with the Decorator. If you're building your own custom implementation, you must ensure that your CSP headers match those of the Decorator.
The user interface (header, menu, footer, etc.) supports three languages:
You can provide availableLanguages
to populate the language selector (språkvelger
), depending on how many languages your application supports (see the section for parameters). However, the actual UI in the header and footer will only be displayed in one of the three languages mentioned above.
Search is provided out of the box, with no configuration needed on your part. The search will either point to production or development environments, depending on how the Decorator is set up.
The Decorator provides a login (and logout) button that redirects the user to ID-porten (either production or development) where the user can log in.
The Decorator uses internal API endpoints to display the user's name, login level, and remaining session time.
Please note that there is no login API exposed from the Decorator to your application, which means that no user credentials are exposed to your application in any meaningful or usable way. If you need to check authentication or credentials for the user, you will need to set this up yourself by connecting directly to the services at login.nav.no. For more information, see Authentication and Authorization at NAIS.
A logout warning is a modal that appears for the user 5 minutes before the login token expires. The user can then choose to extend the session by another 60 minutes or click "Log out" to be logged out immediately.
The users entire session har a max life of 6 hours, after which the user has to log out and log in again.
The logoout warning is activated by default. You can disable this feature by setting logoutWarning=false
as a parameter. However, Accessibility Guidelines and WCAG require that you build your own mechanism to allow users to postpone logout.
Nav uses Amplitude for analytics and tracking user events. To properly safeguard privacy, all analytics data must go through amplitude-proxy, which cleans out trackable personal information before sending the data to Amplitude. The Decorator handles this process for you.
The @navikt/nav-dekoratoren-moduler
package provides helper functions for easy Amplitude logging. Please refer to the README for documentation and getting started guides.
The Amplitude client is exposed on window.dekoratorenAmplitude
. Please see logEventFromApp for the code.
Surveys are set up in a separate repository. Please see nav-dekoratoren-config or contact Team Personbruker for more information.
A skip-link is rendered in the header if an element with the id maincontent
exists in the document. Clicking the skip-link will set focus to the maincontent element. The element must be focusable, which can be accomplished by setting the attribute tabindex="-1"
.
Example:
<main id="maincontent" tabindex="-1"><!-- app html goes here! --></main>