diff --git a/packages/site/README.md b/packages/site/README.md
index e26264af2..c4be3e362 100644
--- a/packages/site/README.md
+++ b/packages/site/README.md
@@ -25,7 +25,7 @@
```js
module.exports = {
modules: [
- 'druxt-site'
+ 'druxt-site/nuxt'
],
druxt: {
baseUrl: 'https://demo-api.druxtjs.org'
diff --git a/packages/site/package.json b/packages/site/package.json
index 4c7b0ae90..4aaf16a96 100644
--- a/packages/site/package.json
+++ b/packages/site/package.json
@@ -33,18 +33,21 @@
"import": "./dist/druxt-site.esm.js"
},
"./components/*": "./dist/components/*",
- "./layouts/*": "./dist/layouts/*"
+ "./layouts/*": "./dist/layouts/*",
+ "./nuxt": "./nuxt/index.js"
},
"main": "dist/druxt-site.ssr.js",
"module": "dist/druxt-site.esm.js",
"files": [
"dist",
+ "nuxt",
"templates"
],
"dependencies": {
+ "@nuxt/kit": "^3.11.2",
"drupal-jsonapi-params": "^2.3.1",
"druxt": "^0.24.0",
- "druxt-blocks": "^0.17.1",
+ "druxt-blocks": "^0.17.2",
"druxt-breadcrumb": "^0.17.1",
"druxt-entity": "^0.28.0",
"druxt-menu": "^0.21.0",
diff --git a/packages/site/src/index.js b/packages/site/src/index.js
index 8d7a33050..e848ebd8e 100644
--- a/packages/site/src/index.js
+++ b/packages/site/src/index.js
@@ -1,5 +1,3 @@
-import { DruxtSiteNuxtModule } from './nuxtModule'
-
/**
* Vue.js Mixin.
*
@@ -26,23 +24,10 @@ import { DruxtSiteNuxtModule } from './nuxtModule'
export { DruxtSiteMixin } from './mixins/site'
/**
- * The Nuxt.js module functions.
- *
- * Installs and configures all DruxtJS Site modules.
+ * Default function to alert user to incorrectly installed module.
*
- * @type {Function}
- * @exports default
- * @name DruxtSiteNuxtModule
- * @see {@link ./nuxtModule|DruxtSiteNuxtModule}
- *
- * @example
nuxt.config.js @lang js
- * module.exports = {
- * modules: [
- * 'druxt-site'
- * ],
- * druxt: {
- * baseUrl: 'https://demo-api.druxtjs.org'
- * }
- * }
+ * This was added as part of the @nuxt/kit update due to breaking changes.
*/
-export default DruxtSiteNuxtModule
+export default () => {
+ throw new Error("DruxtSite Nuxt module must be installed as 'druxt-site/nuxt'")
+}
diff --git a/packages/site/src/nuxt/index.js b/packages/site/src/nuxt/index.js
new file mode 100644
index 000000000..7ad60dcc9
--- /dev/null
+++ b/packages/site/src/nuxt/index.js
@@ -0,0 +1,90 @@
+import { addLayout, defineNuxtModule, installModule } from '@nuxt/kit'
+import { existsSync } from 'fs'
+import { resolve } from 'path'
+// import DruxtSiteStorybook from '../nuxtStorybook'
+
+/**
+ * Nuxt module function to install Druxt Site.
+ *
+ * - Adds the DruxtSite component.
+ * - Adds the core modules for DruxtJS Site.
+ * - Adds default configuration for @nuxtjs/proxy.
+ * - Enables Vuex store.
+ *
+ * @param {ModuleOptions} moduleOptions - The Nuxt.js module options.
+ */
+const DruxtSiteNuxtModule = defineNuxtModule({
+ meta: {
+ name: 'druxt-site',
+ },
+ defaults: {
+ baseUrl: '',
+ endpoint: '/jsonapi'
+ },
+
+ async setup(moduleOptions, nuxt) {
+ // Prevent issue "FATAL: Cannot determine nuxt version! Is current
+ // instance passed?".
+ nuxt._version = nuxt._version || '2.'
+ // This is required to prevent "FATAL: nuxt.options._layers is not iterable"
+ // error when using `installModule()`.
+ nuxt.options._layers = nuxt.options._layers || []
+
+ // Set default options.
+ const options = {
+ baseUrl: moduleOptions.baseUrl,
+ ...nuxt.options?.druxt,
+ proxy: {
+ api: false,
+ files: true,
+ ...nuxt.options?.druxt?.proxy,
+ },
+ site: {
+ layout: true,
+ ...nuxt.options?.druxt?.site,
+ ...moduleOptions,
+ },
+ }
+ nuxt.options.druxt = options
+
+ // Register components directories.
+ nuxt.hook('components:dirs', dirs => {
+ dirs.push({ path: resolve(__dirname, '../dist/components') })
+ })
+
+ // Add Druxt modules.
+ const druxtModules = [
+ 'druxt/nuxt',
+ 'druxt-blocks/nuxt',
+ 'druxt-breadcrumb/nuxt',
+ 'druxt-entity/nuxt',
+ 'druxt-menu/nuxt',
+ 'druxt-router/nuxt',
+ 'druxt-schema/nuxt',
+ 'druxt-views/nuxt'
+ ]
+ for (const module of druxtModules) {
+ await installModule(module, {}, nuxt)
+ }
+
+ // Add default layout.
+ if (!(await existsSync(resolve(nuxt.options.srcDir, nuxt.options.dir.layouts))) && options.site.layout) {
+ addLayout(resolve(__dirname, '../dist/layouts/default.vue'), 'default')
+ }
+
+ // Nuxt Storybook.
+ // @TODO - @nuxt/kit and @nuxt/storybook aren't compatible.
+ // this.nuxt.hook('storybook:config', async ({ stories }) => {
+ // await DruxtSiteStorybook.call(this, { options, stories })
+ // })
+ }
+})
+
+export default DruxtSiteNuxtModule
+
+/**
+ * Module options object.
+ *
+ * @typedef {object} ModuleOptions
+ * @see {@link ./typedefs/moduleOptions|ModuleOptions}
+ */
diff --git a/packages/site/src/nuxtStorybook.js b/packages/site/src/nuxt/storybook.js
similarity index 100%
rename from packages/site/src/nuxtStorybook.js
rename to packages/site/src/nuxt/storybook.js
diff --git a/packages/site/src/nuxtModule.js b/packages/site/src/nuxtModule.js
deleted file mode 100644
index c5e6dcc35..000000000
--- a/packages/site/src/nuxtModule.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import { existsSync } from 'fs'
-import { join, resolve } from 'path'
-import DruxtSiteStorybook from './nuxtStorybook'
-
-/**
- * Nuxt module function to install Druxt Site.
- *
- * - Adds the DruxtSite component.
- * - Adds the core modules for DruxtJS Site.
- * - Adds default configuration for @nuxtjs/proxy.
- * - Enables Vuex store.
- *
- * @param {ModuleOptions} moduleOptions - The Nuxt.js module options.
- */
-const DruxtSiteNuxtModule = async function (moduleOptions = {}) {
- // Set default options.
- const options = {
- baseUrl: moduleOptions.baseUrl,
- ...(this.options || {}).druxt || {},
- proxy: {
- api: false,
- files: true,
- ...((this.options || {}).druxt || {}).proxy,
- },
- site: {
- layout: true,
- ...((this.options || {}).druxt || {}).site,
- ...moduleOptions,
- },
- }
- this.options.druxt = options
-
- // Register components directories.
- this.nuxt.hook('components:dirs', dirs => {
- dirs.push({ path: join(__dirname, 'components') })
- })
-
- // Add Druxt modules.
- const druxtModules = [
- 'druxt',
- 'druxt-blocks',
- 'druxt-breadcrumb',
- 'druxt-entity',
- 'druxt-menu',
- 'druxt-router/nuxt',
- 'druxt-schema',
- 'druxt-views'
- ]
- for (const module of druxtModules) {
- await this.addModule(module)
- }
-
- // Add default layout.
- if (!(await existsSync(resolve(this.options.srcDir, this.options.dir.layouts))) && options.site.layout) {
- this.addLayout(resolve(__dirname, './layouts/default.vue'), 'default')
- }
-
- // Nuxt Storybook.
- this.nuxt.hook('storybook:config', async ({ stories }) => {
- await DruxtSiteStorybook.call(this, { options, stories })
- })
-}
-
-DruxtSiteNuxtModule.meta = require('../package.json')
-
-export { DruxtSiteNuxtModule }
-
-/**
- * Module options object.
- *
- * @typedef {object} ModuleOptions
- * @see {@link ./typedefs/moduleOptions|ModuleOptions}
- */
diff --git a/packages/site/test/__snapshots__/nuxtStorybook.test.js.snap b/packages/site/test/nuxt/__snapshots__/storybook.test.js.snap
similarity index 100%
rename from packages/site/test/__snapshots__/nuxtStorybook.test.js.snap
rename to packages/site/test/nuxt/__snapshots__/storybook.test.js.snap
diff --git a/packages/site/test/nuxt/index.test.js b/packages/site/test/nuxt/index.test.js
new file mode 100644
index 000000000..f77c8ce7c
--- /dev/null
+++ b/packages/site/test/nuxt/index.test.js
@@ -0,0 +1,39 @@
+import DruxtSiteNuxtModule from '../../src/nuxt'
+
+jest.mock('../../src/nuxt/storybook')
+
+jest.mock('@nuxt/kit', () => ({
+ addLayout: jest.fn(),
+ defineNuxtModule: (module) => module,
+ installModule: jest.fn(),
+}))
+
+import { installModule } from '@nuxt/kit'
+
+const nuxtMock = {
+ hook: jest.fn((hook, fn) => {
+ const arg = {
+ 'components:dirs': [],
+ 'storybook:config': { stories: [] }
+ }
+ return fn(arg[hook])
+ }),
+}
+
+jest.mock('druxt-schema')
+
+describe('DruxtJS Site module', () => {
+ test('Nuxt module', async () => {
+ nuxtMock.options = {
+ dir: { layouts: 'layouts' },
+ druxt: {},
+ srcDir: __dirname,
+ }
+
+ // Call DruxtSite module.
+ await await DruxtSiteNuxtModule.setup({}, nuxtMock)
+
+ // Expect 9 modules to be added.
+ expect(installModule).toHaveBeenCalledTimes(8)
+ })
+})
diff --git a/packages/site/test/nuxtStorybook.test.js b/packages/site/test/nuxt/storybook.test.js
similarity index 88%
rename from packages/site/test/nuxtStorybook.test.js
rename to packages/site/test/nuxt/storybook.test.js
index 837b1d7c2..9665cf035 100644
--- a/packages/site/test/nuxtStorybook.test.js
+++ b/packages/site/test/nuxt/storybook.test.js
@@ -1,5 +1,5 @@
import { resolve } from 'path'
-import DruxtEntityStorybook from '../src/nuxtStorybook'
+import DruxtEntityStorybook from '../../src/nuxt/storybook'
jest.mock('axios')
diff --git a/packages/site/test/nuxtModule.test.js b/packages/site/test/nuxtModule.test.js
deleted file mode 100644
index f36ec3b64..000000000
--- a/packages/site/test/nuxtModule.test.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { DruxtSiteNuxtModule } from '../src/nuxtModule'
-
-jest.mock('../src/nuxtStorybook')
-
-const mock = {
- addLayout: jest.fn(),
- addModule: jest.fn(),
- addPlugin: jest.fn(),
- addTemplate: jest.fn(),
- nuxt: {
- hook: jest.fn((hook, fn) => {
- const arg = {
- 'components:dirs': [],
- 'storybook:config': { stories: [] }
- }
- return fn(arg[hook])
- }),
- },
- DruxtSiteNuxtModule
-}
-
-jest.mock('druxt-schema')
-
-describe('DruxtJS Site module', () => {
- test('Nuxt module', async () => {
- mock.options = {
- dir: { layouts: 'layouts' },
- druxt: {},
- srcDir: __dirname,
- }
-
- // Call DruxtSite module.
- await mock.DruxtSiteNuxtModule()
-
- // Expect 9 modules to be added.
- expect(mock.addModule).toHaveBeenCalledTimes(8)
- })
-})