npm package: @nlo/nuxt-common
Description: Nuxt3 layer for the common user interface of NLO lottery websites
Latest version: 17.3.0

# Common package for Nuxt3 front-end websites of NLO

The purpose of this package is to provide tooling and runtime utilities to make developing a front-end for NLO websites easier.

To set up your own NLO Nuxt3 application, please read the [setup page](https://loterij.atlassian.net/wiki/spaces/NLDT/pages/3415769093/Nuxt+setup)

## Features

- Portal header and portal footer proxy vue components `<CommonHeader/>` and `<CommonFooter/>`
- Portal client api integration using `const { $nloPortal } = useNuxtApp();`
- Portal .NET api integration using `useNloPlayer` composable
- Flash messages using `useNloFlashMessage` composable
- SSL certificate generation
- reCAPTCHA support using `<common-recaptcha/>` (see playground for example)
- GTM tracking using `const { trackPage } = useNloGtm();`
- Lottie animations using `<common-lottie-animation/>`
- Marketing consent component `<CommonConsent />`
- Vertical specific UI components e.g. `<PortalCommonButton />` see https://localhost:3000/portal-common-components for more
- Type-safe history flow using `useStepInUrl` composable. (see playground for example)
- Type-safe mutation async-data `useAsyncDataMutation` composable. (see unit tests for example)
- Common icons using `<common-icon name="..." />`
- Common horizontal stepper using `<common-stepper />` (see playground for example)
- Common more info component `<common-more-info />` (see playground for example)
- Common tooltip component `<common-tooltip />` (see playground for example)
- Common modal base using `<common-modal>` (see playground for example)
- Common promises bar using `<common-promises />` (see playground for example)
- Common Heading using `<CommonHeading />` (see playground for example)
- Common Paragraph using `<CommonParagraph />` (see playground for example)
- Common Markdown using `<CommonMarkdown />` (see playground for example)
- Common Column using `<CommonColumn />` (see playground for example)
- Common Row using `<CommonRow />` (see playground for example)
- Common Button using `<CommonButton />` (see playground for example)
- Common Button-link using `<CommonButtonLink />` (see playground for example)
- Common link using `<CommonLink />` (see playground for example)
- Common Button-link using `<CommonButtonEqualChoice />` (see playground for example)
- Common Expandable List using `<CommonExpandableList />` (see playground for example)
- Common Image using `<CommonImage imageUrl="..." />` (see playground for example)
- Common Responsive Image using `<CommonResponsiveImage />` (see playground for example)
- Common Marketing Image using `<CommonMarketingImage />` (see playground for example)
- Common Marketing Gifts using `<CommonMarketingGifts />` (see playground for example)
- Common Three Column Block using `<CommonThreeColumnBlock />` (see playground for example)
- Common Background Image using `<CommonBackgroundImage />` (see playground for example)
- Common Page Error using `<CommonPageError />` (see playground for example)
- Common Responsive Background Image using `<CommonResponsiveBackgroundImage />` (see playground for example)
- Common List item link using `<CommonListItemLink/>` (see playground for example)
- `<CommonMarketingHeader />` special header for marketing pages, props are for the background and campaign visual (see playground for example)
- `<CommonMarketingHeaderContentBasic />` (see `<CommonMarketingHeader />` for example)
- `<CommonPromoCodeForm />` for the promo code forms (this component it self is 'dumb' the submit logic should be handled in a wrapper) so that it can be used with validated and unvalidated promo's (see `<CommonMarketingHeader />` for example)
- `<CommonPromoCodeInput />` (see `<CommonPromoCodeForm />` for example)
- `<CommonInteractiveNumberInput />` (see playground for example)
- `<CommonRadioGroup />` (see playground for example)
- `<CommonRadioInput />` (see playground for example)
- `<CommonCheckbox />` (see playground for example)
- `<CommonDivider />` (see playground for example)
- `<CommonQrCodeScanner />` a full screen qr code scanner overlay (see playground for example)
- `useBraze()` see [Braze Demo](https://localhost:3000/braze) for more info

## Usage

Add this as a dependency

```
npm install @nlo/nuxt-common
```

Add the layer to your nuxt.config.ts

```
import { createResolver } from '@nuxt/kit';
const { resolve } = createResolver(import.meta.url);

{
    extends: '@nlo/nuxt-common',
    runtimeConfig: {
		public: {
			nloNuxtCommon: {
				recaptcha: {
					siteKey: RECAPTCHA_SITE_KEY,
				},
				scripts: {
					optimalScripts: [],
					limitedScripts: [],
					basicScripts: [],
				},
			},
		},
	},
	alias: {
		'@nlo-assets': resolve('./node_modules/@nlo/nuxt-common/assets'),
	}
}
```

Add type definitions to your tsconfig.json:

```json
{
	"include": ["./node_modules/@types/grecaptcha", "./.nuxt/nuxt.d.ts", "./**/*"],
	"vueCompilerOptions": {
		"strictTemplates": true,
		"dataAttributes": ["data-test"]
	}
}
```

## Generating ssl certificates

SSL certificates are required to run Nuxt3 locally on SSL. To generate these certificates, use the following command:
`npx generate-ssl-certificates --dir secrets`

This will create two files in the provided `secrets` folder. These certificates can be used when starting up Nuxt in development mode, by adding this to the startup command:
Allowing local certificate: `export NODE_TLS_REJECT_UNAUTHORIZED=0` (add this before the nuxt dev command)
Tell Nuxt what certificates to use: `--https --ssl-cert secrets/cert.pem --ssl-key secrets/key.pem` (add this after the nuxt dev command)

Full command example:
`export NODE_TLS_REJECT_UNAUTHORIZED=0 && nuxt dev --port 3010 --https --ssl-cert secrets/key.cert --ssl-key secrets/key.pem`

## Generate api types from swagger json

To generate typescript definition files from swagger json, use the following script:
`npx generate-api-types --input ./path/to/swagger.json --output ./path/to/mytypes.d.ts`

## Storybook

The nuxt common components come with Storybook support. To show the stories in the Storybook of the vertical, use the following:

Add to `.storybook/main.ts` of the vertical Storybook story locations.

```
'../node_modules/@nlo/nuxt-common/components/**/*.stories.@(js|jsx|ts|tsx)',
```

In `.storybook/preview.ts` of the vertical Storybook add:

Add the import

```
import { commonThemeControls } from '@nlo/nuxt-common/storybook-utils/storybook-vertical-themes';
```

Add, spread or pick the theme controls you need. To make every story work, include all.

```
globalTypes: {
	commonThemeControls,
},
```

## Environment variables

This nuxt layer uses environment variables to configure the features to your runtime needs.
The following environment variables are available:

- `NUXT_PUBLIC_COMMON_RECAPTCHA_SITE_KEY` The site key for recaptcha
- `NUXT_PUBLIC_COMMON_BRAZE_SETTINGS_API_KEY` The api key for Braze (see Braze web)
- `NUXT_PUBLIC_COMMON_BRAZE_SETTINGS_SDK_ENDPOINT` The endpoint to our Braze project (see Braze web)
- `NUXT_PUBLIC_COMMON_BRAZE_SETTINGS_ENABLE_LOGGING` Boolean that switches logging on and off (please don't enable this on production)

## Development

- Run `npm run dev:prepare` to generate type stubs.

### Running the playground

The playground is a Nuxt application that allows you to try out your feature within this repository.

- Run `npx generate-ssl-certificates --dir secrets` to generate SSL certificates
- Run `npm install` in `./playground`
- Use `npm run dev` to start [playground](./playground) in development mode.

# Usage per feature

## GTM

The GTM implementation works by exposing a composable called `useNloGtm` that you can use in your application.

### Track event context

Tracking events to GTM uses a `trackEvent` datalayer push, and uses the eventLabel parameter (context) as a value for the event label. Since the value of context is reliant on where the tracking is performed, we also provide an easy way to provide context through provide/inject using the `provideContextName` function.
When using `provideContextName`, you can easely set the context for all descendant components without the need of prop drilling. However, you can override the injected context by passing the eventLabel in the tracking functions of the composable.

### Button tracking

Using the `trackButtonPress` method, you can track a click event on a button or a link.
Example usage:

```Typescript
// Text of the button is required
// Context of the button is optional, if not provided, the injected context name is used.
trackButtonPress('Text of the button', 'Context of the button');
```

## Common icon

When adding an icon to the library there are a couple of requirements:

- An icon should be 24x24px and should be named by use. For example delete.svg instead of trashcan.svg.
- Flatten the icons as much as possible. Most groups are useless and just increase the file size.
- Remove the fill colors from the svg element and the paths, we control that with css which nlo-icon gets from currentColor.
- Add them in alphabetical order.