@dargmuesli/nuxt-vio 3.7.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -1,73 +1,7 @@
1
- # Nuxt Layer Starter
1
+ # Vio
2
2
 
3
- Create Nuxt extendable layer with this GitHub template.
3
+ Vio is a [Nuxt layer](https://nuxt.com/docs/getting-started/layers) powering:
4
4
 
5
- ## Setup
6
-
7
- Make sure to install the dependencies:
8
-
9
- ```bash
10
- pnpm install
11
- ```
12
-
13
- ## Working on your theme
14
-
15
- Your theme is at the root of this repository, it is exactly like a regular Nuxt project, except you can publish it on NPM.
16
-
17
- The `.playground` directory should help you on trying your theme during development.
18
-
19
- Running `pnpm dev` will prepare and boot `.playground` directory, which imports your theme itself.
20
-
21
- ## Distributing your theme
22
-
23
- Your Nuxt layer is shaped exactly the same as any other Nuxt project, except you can publish it on NPM.
24
-
25
- To do so, you only have to check if `files` in `package.json` are valid, then run:
26
-
27
- ```bash
28
- npm publish --access public
29
- ```
30
-
31
- Once done, your users will only have to run:
32
-
33
- ```bash
34
- npm install --save your-theme
35
- ```
36
-
37
- Then add the dependency to their `extends` in `nuxt.config`:
38
-
39
- ```ts
40
- defineNuxtConfig({
41
- extends: 'your-theme'
42
- })
43
- ```
44
-
45
- ## Development Server
46
-
47
- Start the development server on http://localhost:3000
48
-
49
- ```bash
50
- pnpm dev
51
- ```
52
-
53
- ## Production
54
-
55
- Build the application for production:
56
-
57
- ```bash
58
- pnpm build
59
- ```
60
-
61
- Or statically generate it with:
62
-
63
- ```bash
64
- pnpm generate
65
- ```
66
-
67
- Locally preview production build:
68
-
69
- ```bash
70
- pnpm preview
71
- ```
72
-
73
- Checkout the [deployment documentation](https://v3.nuxtjs.org/docs/deployment) for more information.
5
+ - https://jonas-thelemann.de
6
+ - https://creal.jonas-thelemann.de
7
+ - https://trapparty.jonas-thelemann.de
package/app.config.ts CHANGED
@@ -1,9 +1,6 @@
1
- import { useServerSeoMeta } from '@unhead/vue'
2
-
3
1
  export default defineAppConfig({
4
2
  vio: {
5
3
  pages: undefined,
6
- seoMeta: undefined,
7
4
  server: {
8
5
  middleware: {
9
6
  headers: {
@@ -83,7 +80,6 @@ declare module 'nuxt/schema' {
83
80
  }
84
81
  }
85
82
  }
86
- seoMeta?: Parameters<typeof useServerSeoMeta>[0]
87
83
  server?: {
88
84
  middleware: {
89
85
  headers: {
@@ -1,12 +1,14 @@
1
1
  <template>
2
- <h1>{{ `${statusCode} - ${statusReason}` }}</h1>
3
2
  <div>
4
- {{ description }}
3
+ <h1>{{ `${statusCode} - ${statusReason}` }}</h1>
4
+ <div>
5
+ {{ description }}
6
+ </div>
7
+ <pre
8
+ v-if="stack && !runtimeConfig.public.vio.isInProduction"
9
+ v-html="stack"
10
+ />
5
11
  </div>
6
- <pre
7
- v-if="stack && !runtimeConfig.public.vio.isInProduction"
8
- v-html="stack"
9
- />
10
12
  </template>
11
13
 
12
14
  <script setup lang="ts">
@@ -2,8 +2,7 @@ export const useAppLayout = () => {
2
2
  const appConfig = useAppConfig()
3
3
  const siteConfig = useSiteConfig()
4
4
 
5
- // TODO: replace with `useServerHeadSafe`
6
- useHeadSafe({
5
+ useServerHeadSafe({
7
6
  ...useLocaleHead({ addDirAttribute: true, addSeoAttributes: true }).value,
8
7
  bodyAttrs: {
9
8
  class:
@@ -11,22 +10,16 @@ export const useAppLayout = () => {
11
10
  },
12
11
  })
13
12
 
14
- // TODO: convert to `useServerHeadSafe` (https://github.com/harlan-zw/nuxt-seo-kit/issues/98)
15
- useSeoMeta({
13
+ useServerSeoMeta({
16
14
  titleTemplate: (title) =>
17
- title && title !== siteConfig.name
18
- ? `${title} ${siteConfig.titleSeparator} ${siteConfig.name}`
19
- : siteConfig.name,
15
+ TITLE_TEMPLATE({
16
+ siteName: siteConfig.name,
17
+ title,
18
+ }),
20
19
  })
21
20
 
22
- if (appConfig.vio.seoMeta) {
23
- // TODO: replace with `useServerSeoMeta`
24
- useSeoMeta(appConfig.vio.seoMeta)
25
- }
26
-
27
21
  if (appConfig.vio.themeColor) {
28
- // TODO: replace with `useServerSeoMeta`
29
- useSeoMeta({
22
+ useServerSeoMeta({
30
23
  msapplicationTileColor: appConfig.vio.themeColor,
31
24
  themeColor: appConfig.vio.themeColor,
32
25
  })
@@ -1,11 +1,10 @@
1
1
  export const useFavicons = () => {
2
2
  const appConfig = useAppConfig()
3
3
 
4
- // TODO: replace with `useServerHeadSafe`
5
- useHeadSafe({
4
+ useServerHeadSafe({
6
5
  link: [
7
6
  {
8
- href: `/assets/static/favicon/site.webmanifest?v=${CACHE_VERSION}`,
7
+ href: `/site.webmanifest?v=${CACHE_VERSION}`,
9
8
  rel: 'manifest',
10
9
  },
11
10
  {
@@ -1,22 +1,28 @@
1
1
  import { defu } from 'defu'
2
- import type { ComputedRef } from 'vue'
2
+ import type { UseSeoMetaInput } from '@unhead/vue'
3
3
 
4
4
  export const useHeadDefault = ({
5
5
  extension,
6
6
  title,
7
7
  }: {
8
- extension?: Parameters<typeof useServerSeoMeta>[0]
8
+ extension?: UseSeoMetaInput
9
9
  title: string | ComputedRef<string>
10
10
  }) => {
11
11
  const attrs = useAttrs()
12
+ const siteConfig = useSiteConfig()
12
13
 
13
- const defaults: Parameters<typeof useServerSeoMeta>[0] = {
14
+ const defaults: UseSeoMetaInput = {
14
15
  description: attrs['site-description'] as string, // TODO: remove (https://github.com/harlan-zw/nuxt-site-config/pull/7)
15
16
  msapplicationConfig: `/assets/static/favicon/browserconfig.xml?v=${CACHE_VERSION}`,
16
17
  title,
17
18
  twitterDescription: attrs['site-description'] as string,
18
- twitterTitle: title,
19
+ twitterTitle: ref(
20
+ TITLE_TEMPLATE({
21
+ siteName: siteConfig.name,
22
+ title: toValue(title),
23
+ }),
24
+ ), // TODO: remove `ref`
19
25
  }
20
26
 
21
- useSeoMeta(defu(extension, defaults)) // TODO: replace with `useServerSeoMeta`
27
+ useServerSeoMeta(defu(extension, defaults))
22
28
  }
@@ -5,8 +5,7 @@ export const usePolyfills = () => {
5
5
  '%2C',
6
6
  )}&flags=gated`
7
7
 
8
- // TODO: replace with `useServerHead`
9
- useHead({
8
+ useServerHead({
10
9
  link: [
11
10
  {
12
11
  rel: 'preload',
package/error.vue CHANGED
@@ -21,8 +21,7 @@ const errorProp = toRef(() => props.error)
21
21
  // initialization
22
22
  useAppLayout()
23
23
 
24
- // TODO: replace with `useServerHeadSafe`
25
- useHeadSafe({
24
+ useServerHeadSafe({
26
25
  title: `${errorProp.value.statusCode} - ${errorProp.value.message}`,
27
26
  })
28
27
  </script>
package/nuxt.config.ts CHANGED
@@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url'
4
4
  import { defu } from 'defu'
5
5
 
6
6
  import {
7
- BASE_URL,
7
+ SITE_URL,
8
8
  I18N_COOKIE_NAME,
9
9
  I18N_MODULE_CONFIG,
10
10
  SITE_NAME,
@@ -29,6 +29,9 @@ export default defineNuxtConfig(
29
29
  lang: 'en', // fallback data to prevent invalid html at generation
30
30
  },
31
31
  titleTemplate: '%s', // fully set in `composables/useAppLayout.ts`
32
+ templateParams: {
33
+ separator: '·',
34
+ },
32
35
  },
33
36
  pageTransition: {
34
37
  name: 'layout',
@@ -36,7 +39,7 @@ export default defineNuxtConfig(
36
39
  },
37
40
  devtools: {
38
41
  enabled:
39
- process.env.NODE_ENV !== 'production' &&
42
+ process.env.NODE_ENV === 'development' &&
40
43
  !process.env.NUXT_PUBLIC_VIO_IS_TESTING,
41
44
  timeline: {
42
45
  enabled: true,
@@ -149,7 +152,6 @@ export default defineNuxtConfig(
149
152
  },
150
153
  },
151
154
  linkChecker: {
152
- debug: process.env.NODE_ENV === 'development',
153
155
  failOnError: true,
154
156
  },
155
157
  seo: {
@@ -157,7 +159,6 @@ export default defineNuxtConfig(
157
159
  },
158
160
  site: {
159
161
  debug: process.env.NODE_ENV === 'development',
160
- titleSeparator: '·',
161
162
  },
162
163
  sitemap: {
163
164
  exclude: I18N_MODULE_CONFIG.locales.map(
@@ -170,7 +171,7 @@ export default defineNuxtConfig(
170
171
  },
171
172
  },
172
173
  VIO_NUXT_BASE_CONFIG({
173
- baseUrl: BASE_URL,
174
+ siteUrl: SITE_URL,
174
175
  defaultLocale: 'en',
175
176
  siteName: SITE_NAME,
176
177
  stagingHost: 'localhost:3000',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dargmuesli/nuxt-vio",
3
- "version": "3.7.1",
3
+ "version": "4.0.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -8,7 +8,7 @@
8
8
  "engines": {
9
9
  "node": "20"
10
10
  },
11
- "packageManager": "pnpm@8.7.4",
11
+ "packageManager": "pnpm@8.7.5",
12
12
  "files": [
13
13
  "assets",
14
14
  "components",
@@ -25,13 +25,15 @@
25
25
  "error.vue",
26
26
  "i18n.config.ts",
27
27
  "nuxt.config.ts",
28
+ "playwright.config.ts",
28
29
  "tailwind.config.ts"
29
30
  ],
30
31
  "main": "nuxt.config.ts",
31
32
  "scripts": {
32
- "build": "nuxt build .playground",
33
- "dev": "nuxt dev .playground",
34
- "generate": "nuxt generate .playground",
33
+ "build": "pnpm build:node",
34
+ "build:node": "nuxt build .playground",
35
+ "build:static": "SITE_URL=http://localhost:3002 nuxt generate .playground",
36
+ "generate": "pnpm build:static",
35
37
  "lint:fix": "pnpm lint:js --fix && pnpm lint:ts --fix && pnpm lint:style --fix",
36
38
  "lint:js": "eslint --cache --ext .js,.ts,.vue --ignore-path .gitignore .",
37
39
  "lint:staged": "lint-staged",
@@ -40,16 +42,21 @@
40
42
  "lint": "pnpm lint:js && pnpm lint:ts && pnpm lint:style",
41
43
  "prepare": "nuxt prepare .playground",
42
44
  "preview": "nuxt preview .playground",
43
- "start": "PORT=3001 node .playground/.output/server/index.mjs",
44
- "test:e2e:dev": "cross-env NUXT_PUBLIC_VIO_IS_TESTING=1 pnpm test:e2e",
45
+ "start:dev": "nuxt dev .playground",
46
+ "start:node": "node .playground/.output/server/index.mjs",
47
+ "start:static": "serve .playground/.output/public",
45
48
  "test:e2e:docker:br": "pnpm test:e2e:docker:build && pnpm test:e2e:docker:run",
46
49
  "test:e2e:docker:build": "docker build -t test-e2e_base --build-arg UID=$(id -u) --build-arg GID=$(id -g) --target test-e2e_base ..",
47
- "test:e2e:docker:dev:update": "pnpm test:e2e:docker:dev --update-snapshots",
48
- "test:e2e:docker:dev": "pnpm test:e2e:docker:br pnpm --dir src run test:e2e:dev",
49
- "test:e2e:docker:prod:update": "pnpm test:e2e:docker:prod --update-snapshots",
50
- "test:e2e:docker:prod": "pnpm test:e2e:docker:br pnpm --dir src run test:e2e:prod",
51
50
  "test:e2e:docker:run": "docker run --rm -v \"$PWD/..:/srv/app\" -v \"$(pnpm store path):/srv/.pnpm-store\" test-e2e_base",
52
- "test:e2e:prod": "cross-env NUXT_PUBLIC_VIO_IS_TESTING=1 NODE_ENV=production pnpm test:e2e",
51
+ "test:e2e:docker:server:dev:update": "pnpm test:e2e:docker:server:dev --update-snapshots",
52
+ "test:e2e:docker:server:dev": "pnpm test:e2e:docker:br pnpm --dir src run test:e2e:server:dev",
53
+ "test:e2e:docker:server:node:update": "pnpm test:e2e:docker:server:node --update-snapshots",
54
+ "test:e2e:docker:server:node": "pnpm test:e2e:docker:br pnpm --dir src run test:e2e:server:node",
55
+ "test:e2e:docker:server:static:update": "pnpm test:e2e:docker:server:static --update-snapshots",
56
+ "test:e2e:docker:server:static": "pnpm test:e2e:docker:br pnpm --dir src run test:e2e:server:static",
57
+ "test:e2e:server:dev": "cross-env PORT=3000 SITE_URL=http://localhost:3000 VIO_SERVER=dev pnpm test:e2e",
58
+ "test:e2e:server:node": "cross-env NODE_ENV=production NUXT_PUBLIC_I18N_BASE_URL=http://localhost:3001 NUXT_PUBLIC_SITE_URL=http://localhost:3001 PORT=3001 VIO_SERVER=node pnpm test:e2e",
59
+ "test:e2e:server:static": "cross-env NODE_ENV=production PORT=3002 SITE_URL=http://localhost:3002 VIO_SERVER=static pnpm test:e2e",
53
60
  "test:e2e": "playwright test"
54
61
  },
55
62
  "dependencies": {
@@ -76,12 +83,14 @@
76
83
  "@vuelidate/validators": "2.0.4",
77
84
  "clipboard": "2.0.11",
78
85
  "cookie": "0.5.0",
86
+ "cross-env": "7.0.3",
79
87
  "dayjs": "2.0.0-alpha.4",
80
88
  "is-https": "4.0.0",
81
89
  "jiti": "1.20.0",
82
90
  "jose": "4.14.6",
83
91
  "lodash-es": "4.17.21",
84
92
  "pinia": "2.1.6",
93
+ "serve": "14.2.1",
85
94
  "sweetalert2": "11.7.27",
86
95
  "vue-gtag": "2.0.1",
87
96
  "vue-tsc": "1.8.10"
@@ -89,7 +98,6 @@
89
98
  "devDependencies": {
90
99
  "@intlify/eslint-plugin-vue-i18n": "3.0.0-next.3",
91
100
  "@nuxtjs/eslint-config-typescript": "12.1.0",
92
- "cross-env": "7.0.3",
93
101
  "eslint": "8.49.0",
94
102
  "eslint-config-prettier": "9.0.0",
95
103
  "eslint-plugin-compat": "4.2.0",
@@ -0,0 +1,96 @@
1
+ import { defineConfig, devices } from '@playwright/test'
2
+ import { SITE_URL } from './utils/constants'
3
+
4
+ /**
5
+ * Read environment variables from file.
6
+ * https://github.com/motdotla/dotenv
7
+ */
8
+ // require('dotenv').config();
9
+
10
+ /**
11
+ * See https://playwright.dev/docs/test-configuration.
12
+ */
13
+ export default defineConfig({
14
+ expect: {
15
+ toHaveScreenshot: {
16
+ maxDiffPixelRatio: 0.01,
17
+ },
18
+ },
19
+
20
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
21
+ forbidOnly: !!process.env.CI,
22
+
23
+ /* Run tests in files in parallel */
24
+ fullyParallel: true,
25
+
26
+ outputDir: 'tests/e2e/results',
27
+
28
+ /* Configure projects for major browsers */
29
+ projects: [
30
+ {
31
+ name: 'chromium',
32
+ use: { ...devices['Desktop Chrome'] },
33
+ },
34
+
35
+ {
36
+ name: 'firefox',
37
+ use: { ...devices['Desktop Firefox'] },
38
+ },
39
+
40
+ {
41
+ name: 'webkit',
42
+ use: { ...devices['Desktop Safari'] },
43
+ },
44
+
45
+ /* Test against mobile viewports. */
46
+ // {
47
+ // name: 'Mobile Chrome',
48
+ // use: { ...devices['Pixel 5'] },
49
+ // },
50
+ // {
51
+ // name: 'Mobile Safari',
52
+ // use: { ...devices['iPhone 12'] },
53
+ // },
54
+
55
+ /* Test against branded browsers. */
56
+ // {
57
+ // name: 'Microsoft Edge',
58
+ // use: { ...devices['Desktop Edge'], channel: 'msedge' },
59
+ // },
60
+ // {
61
+ // name: 'Google Chrome',
62
+ // use: { ..devices['Desktop Chrome'], channel: 'chrome' },
63
+ // },
64
+ ],
65
+
66
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
67
+ reporter: [['html', { outputFolder: 'tests/e2e/report' }]],
68
+
69
+ /* Retry on CI only */
70
+ retries: process.env.CI ? 1 : 0,
71
+
72
+ testDir: './tests/e2e/specs',
73
+
74
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
75
+ use: {
76
+ /* Base URL to use in actions like `await page.goto('/')`. */
77
+ baseURL: SITE_URL,
78
+
79
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
80
+ trace: 'on-first-retry',
81
+ },
82
+
83
+ /* Run your local dev server before starting the tests */
84
+ webServer: {
85
+ command: `pnpm run start:${process.env.VIO_SERVER || 'dev'}`,
86
+ env: {
87
+ NUXT_PUBLIC_VIO_IS_TESTING: 'true',
88
+ },
89
+ timeout: process.env.NODE_ENV === 'production' ? 10000 : 100000,
90
+ url: process.env.SITE_URL || SITE_URL,
91
+ reuseExistingServer: !process.env.CI,
92
+ },
93
+
94
+ /* Opt out of parallel tests on CI. */
95
+ workers: process.env.CI ? 1 : undefined,
96
+ })
@@ -2,15 +2,13 @@ import { helpers } from '@vuelidate/validators'
2
2
 
3
3
  export const SITE_NAME = 'Vio'
4
4
 
5
- export const BASE_URL =
6
- (process.env.NUXT_PUBLIC_HOST ? 'https' : 'http') +
7
- '://' +
8
- (process.env.NUXT_PUBLIC_HOST ||
9
- `${process.env.HOST || 'localhost'}:${
10
- !process.env.NODE_ENV || process.env.NODE_ENV === 'development'
11
- ? '3000'
12
- : '3001'
13
- }`)
5
+ export const SITE_URL =
6
+ process.env.SITE_URL ||
7
+ process.env.NUXT_PUBLIC_SITE_URL ||
8
+ (process.env.HOST ? 'https' : 'http') +
9
+ '://' +
10
+ (process.env.HOST ||
11
+ `${process.env.HOST || 'localhost'}:${process.env.PORT || '3000'}`)
14
12
  export const CACHE_VERSION = 'bOXMwoKlJr'
15
13
  export const COOKIE_PREFIX = SITE_NAME.toLocaleLowerCase()
16
14
  export const COOKIE_SEPARATOR = '_'
@@ -45,15 +43,22 @@ export const REGEX_UUID =
45
43
  /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/
46
44
  export const TIMEZONE_COOKIE_NAME = [COOKIE_PREFIX, 'tz'].join(COOKIE_SEPARATOR)
47
45
  export const TIMEZONE_HEADER_KEY = `X-${SITE_NAME}-Timezone`
46
+ export const TITLE_TEMPLATE = ({
47
+ siteName,
48
+ title,
49
+ }: {
50
+ siteName: string
51
+ title?: string
52
+ }) => (title && title !== siteName ? `${title} · ${siteName}` : siteName)
48
53
  export const VALIDATION_SUGGESTION_TITLE_LENGTH_MAXIMUM = 300
49
54
  export const VERIFICATION_FORMAT_UUID = helpers.regex(REGEX_UUID)
50
55
  export const VIO_NUXT_BASE_CONFIG = ({
51
- baseUrl,
56
+ siteUrl,
52
57
  defaultLocale,
53
58
  siteName,
54
59
  stagingHost,
55
60
  }: {
56
- baseUrl?: string
61
+ siteUrl?: string
57
62
  defaultLocale?: string
58
63
  siteName: string
59
64
  stagingHost?: string
@@ -67,14 +72,14 @@ export const VIO_NUXT_BASE_CONFIG = ({
67
72
  runtimeConfig: {
68
73
  public: {
69
74
  i18n: {
70
- ...(baseUrl ? { baseUrl } : {}),
75
+ ...(siteUrl ? { baseUrl: siteUrl } : {}),
71
76
  },
72
77
  vio: {
73
78
  ...(stagingHost
74
79
  ? {
75
80
  stagingHost:
76
81
  process.env.NODE_ENV !== 'production' &&
77
- !process.env.NUXT_PUBLIC_HOST
82
+ !process.env.NUXT_PUBLIC_SITE_URL
78
83
  ? stagingHost
79
84
  : undefined,
80
85
  }
@@ -89,7 +94,7 @@ export const VIO_NUXT_BASE_CONFIG = ({
89
94
  ...I18N_MODULE_CONFIG, // `langDir`, `lazy` and `locales` must be configured to extend a layer having lazy-loaded translations (https://v8.i18n.nuxtjs.org/guide/layers#locales)
90
95
  },
91
96
  site: {
92
- ...(baseUrl ? { url: baseUrl } : {}),
97
+ ...(siteUrl ? { url: siteUrl } : {}),
93
98
  ...(defaultLocale ? { defaultLocale } : {}),
94
99
  name: siteName,
95
100
  },