tim
tim
NNuxt
Created by tim on 3/8/2025 in #❓・help
How to test Nuxt 3 Nitro Server endpoints and middlewares (avoiding defineEventHandler not defined)
vitest.config.ts:
import { defineVitestConfig } from '@nuxt/test-utils/config';
import { loadEnv } from 'vite';

export default defineVitestConfig({
test: {
env: loadEnv('test', process.cwd()),
environment: 'nuxt',
environmentOptions: {
nuxt: {
mock: {
intersectionObserver: true,
indexedDb: true,
},
},
},
coverage: {
provider: 'istanbul',
reporter: ['text', 'json', 'html'],
reportsDirectory: './coverage',
all: true,
include: ['**/*.{ts,vue}'],
exclude: ['node_modules/', 'tests/'],
},
},
});
import { defineVitestConfig } from '@nuxt/test-utils/config';
import { loadEnv } from 'vite';

export default defineVitestConfig({
test: {
env: loadEnv('test', process.cwd()),
environment: 'nuxt',
environmentOptions: {
nuxt: {
mock: {
intersectionObserver: true,
indexedDb: true,
},
},
},
coverage: {
provider: 'istanbul',
reporter: ['text', 'json', 'html'],
reportsDirectory: './coverage',
all: true,
include: ['**/*.{ts,vue}'],
exclude: ['node_modules/', 'tests/'],
},
},
});
10 replies
NNuxt
Created by tim on 3/8/2025 in #❓・help
How to test Nuxt 3 Nitro Server endpoints and middlewares (avoiding defineEventHandler not defined)
package.json:
{
"name": "website",
"version": "v2025.3.1-dev",
"type": "module",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"preinstall": "npx only-allow pnpm",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "vitest",
"test:watch": "vitest --watch",
"test:coverage": "vitest run --coverage",
"lhci:mobile": "lhci autorun",
"lhci:desktop": "lhci autorun --collect.settings.preset=desktop"
},
"engines": {
"node": ">=18.18.0",
"npm": ">=9.7.0"
},
"dependencies": {
"@headlessui/vue": "^1.7.23",
"@heroicons/vue": "^2.2.0",
"@nuxt/devtools": "latest",
"@nuxt/types": "^2.18.1",
"@nuxtjs/i18n": "^9.2.1",
"@nuxtjs/tailwindcss": "^6.12.2",
"@nuxtjs/turnstile": "^0.9.11",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15",
"@types/node": "^22.13.9",
"@vueuse/core": "^12.7.0",
"motion-v": "0.10.1",
"nuxt-cloudflare-analytics": "^1.0.8",
"nuxt-headlessui": "^1.2.0",
"nuxt-security": "2.1.5",
"resend": "4.1.2"
},
"devDependencies": {
"@inspira-ui/plugins": "^0.0.1",
"@lhci/cli": "^0.14.0",
"@nuxt/eslint": "^1.0.1",
"@nuxt/scripts": "^0.10.4",
"@nuxt/test-utils": "^3.17.1",
"@nuxtjs/apollo": "5.0.0-alpha.14",
"@nuxtjs/supabase": "^1.4.4",
"@vitest/coverage-istanbul": "^3.0.3",
"@vue/test-utils": "^2.4.6",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"eslint": "^9.20.1",
"happy-dom": "^17.1.9",
"nuxt": "^3.14.1592",
"playwright-core": "^1.49.1",
"tailwind-merge": "^3.0.1",
"tailwindcss-animate": "^1.0.7",
"vitest": "^3.0.3"
}
}
{
"name": "website",
"version": "v2025.3.1-dev",
"type": "module",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"preinstall": "npx only-allow pnpm",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "vitest",
"test:watch": "vitest --watch",
"test:coverage": "vitest run --coverage",
"lhci:mobile": "lhci autorun",
"lhci:desktop": "lhci autorun --collect.settings.preset=desktop"
},
"engines": {
"node": ">=18.18.0",
"npm": ">=9.7.0"
},
"dependencies": {
"@headlessui/vue": "^1.7.23",
"@heroicons/vue": "^2.2.0",
"@nuxt/devtools": "latest",
"@nuxt/types": "^2.18.1",
"@nuxtjs/i18n": "^9.2.1",
"@nuxtjs/tailwindcss": "^6.12.2",
"@nuxtjs/turnstile": "^0.9.11",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15",
"@types/node": "^22.13.9",
"@vueuse/core": "^12.7.0",
"motion-v": "0.10.1",
"nuxt-cloudflare-analytics": "^1.0.8",
"nuxt-headlessui": "^1.2.0",
"nuxt-security": "2.1.5",
"resend": "4.1.2"
},
"devDependencies": {
"@inspira-ui/plugins": "^0.0.1",
"@lhci/cli": "^0.14.0",
"@nuxt/eslint": "^1.0.1",
"@nuxt/scripts": "^0.10.4",
"@nuxt/test-utils": "^3.17.1",
"@nuxtjs/apollo": "5.0.0-alpha.14",
"@nuxtjs/supabase": "^1.4.4",
"@vitest/coverage-istanbul": "^3.0.3",
"@vue/test-utils": "^2.4.6",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"eslint": "^9.20.1",
"happy-dom": "^17.1.9",
"nuxt": "^3.14.1592",
"playwright-core": "^1.49.1",
"tailwind-merge": "^3.0.1",
"tailwindcss-animate": "^1.0.7",
"vitest": "^3.0.3"
}
}
10 replies
NNuxt
Created by tim on 3/8/2025 in #❓・help
How to test Nuxt 3 Nitro Server endpoints and middlewares (avoiding defineEventHandler not defined)
and thats my test file (tests/unit/server/middleware/visibilityGuard.global.spec.ts):
import { describe, it, expect, vi, beforeEach } from 'vitest';
import type { H3Event, EventHandlerRequest } from 'h3';
import { sendRedirect } from 'h3';
import visibilityGuard from '../../../../server/middleware/visibilityGuard.global';

vi.stubGlobal('defineEventHandler', (handler: any) => handler);
const runtimeConfigMock = vi.fn(() => ({ APP_STATE: 'maintenance' }));
vi.stubGlobal('useRuntimeConfig', runtimeConfigMock);

vi.mock('h3', async () => {
return {
sendRedirect: vi.fn(),
};
});

describe('visibilityGuard global middleware', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('should be a function', () => {
expect(typeof visibilityGuard).toBe('function');
});

const createEvent = (path: string): H3Event<EventHandlerRequest> => ({
path,
context: {}, // Mock necessary context
} as unknown as H3Event<EventHandlerRequest>);

it('redirects to /maintenance when app state is maintenance and path is not /maintenance', () => {
runtimeConfigMock.mockReturnValueOnce({ APP_STATE: 'maintenance' });
const event = createEvent('/dashboard');

visibilityGuard(event);

expect(sendRedirect).toHaveBeenCalledWith(event, '/maintenance');
});

// more test cases

it('does nothing (allows navigation) when app state is development', () => {
runtimeConfigMock.mockReturnValueOnce({ APP_STATE: 'development' });
const event = createEvent('/dashboard');

visibilityGuard(event);

expect(sendRedirect).not.toHaveBeenCalled();
});
});
import { describe, it, expect, vi, beforeEach } from 'vitest';
import type { H3Event, EventHandlerRequest } from 'h3';
import { sendRedirect } from 'h3';
import visibilityGuard from '../../../../server/middleware/visibilityGuard.global';

vi.stubGlobal('defineEventHandler', (handler: any) => handler);
const runtimeConfigMock = vi.fn(() => ({ APP_STATE: 'maintenance' }));
vi.stubGlobal('useRuntimeConfig', runtimeConfigMock);

vi.mock('h3', async () => {
return {
sendRedirect: vi.fn(),
};
});

describe('visibilityGuard global middleware', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('should be a function', () => {
expect(typeof visibilityGuard).toBe('function');
});

const createEvent = (path: string): H3Event<EventHandlerRequest> => ({
path,
context: {}, // Mock necessary context
} as unknown as H3Event<EventHandlerRequest>);

it('redirects to /maintenance when app state is maintenance and path is not /maintenance', () => {
runtimeConfigMock.mockReturnValueOnce({ APP_STATE: 'maintenance' });
const event = createEvent('/dashboard');

visibilityGuard(event);

expect(sendRedirect).toHaveBeenCalledWith(event, '/maintenance');
});

// more test cases

it('does nothing (allows navigation) when app state is development', () => {
runtimeConfigMock.mockReturnValueOnce({ APP_STATE: 'development' });
const event = createEvent('/dashboard');

visibilityGuard(event);

expect(sendRedirect).not.toHaveBeenCalled();
});
});
10 replies
NNuxt
Created by tim on 3/8/2025 in #❓・help
How to test Nuxt 3 Nitro Server endpoints and middlewares (avoiding defineEventHandler not defined)
thats my middleware (server/middleware/visibilityGuard.global.ts):
import type { EventHandlerRequest, H3Event } from 'h3';
import type { NitroRuntimeConfig } from 'nitropack';
import { sendRedirect } from 'h3';

export default defineEventHandler((event: H3Event<EventHandlerRequest>) => {
const runtimeConfig: NitroRuntimeConfig = useRuntimeConfig(event);
const appState: string = runtimeConfig.APP_STATE || 'maintenance';

switch (appState) {
case 'development':
break;
case 'production':
if (event.path === '/maintenance' || event.path === '/coming-soon') {
return sendRedirect(event, '/');
}
break;
case 'coming':
if (event.path !== '/coming-soon') {
return sendRedirect(event, '/coming-soon');
}
break;
case 'maintenance':
if (event.path !== '/maintenance') {
return sendRedirect(event, '/maintenance');
}
break;
default:
break;
}
});
import type { EventHandlerRequest, H3Event } from 'h3';
import type { NitroRuntimeConfig } from 'nitropack';
import { sendRedirect } from 'h3';

export default defineEventHandler((event: H3Event<EventHandlerRequest>) => {
const runtimeConfig: NitroRuntimeConfig = useRuntimeConfig(event);
const appState: string = runtimeConfig.APP_STATE || 'maintenance';

switch (appState) {
case 'development':
break;
case 'production':
if (event.path === '/maintenance' || event.path === '/coming-soon') {
return sendRedirect(event, '/');
}
break;
case 'coming':
if (event.path !== '/coming-soon') {
return sendRedirect(event, '/coming-soon');
}
break;
case 'maintenance':
if (event.path !== '/maintenance') {
return sendRedirect(event, '/maintenance');
}
break;
default:
break;
}
});
10 replies
NNuxt
Created by tim on 6/12/2024 in #❓・help
Nuxt 3.12.1 Update: Prerender Error with app.use Function
Do you know if there is any issue open for that already?
9 replies
NNuxt
Created by tim on 6/12/2024 in #❓・help
Nuxt 3.12.1 Update: Prerender Error with app.use Function
Oh luckily, I already feared that the configuration should have been more fine-grained and that I had made mistakes that would only stop the startup with the new version, but that reassures me, then it goes back to the old version for now. Thank you very much!
9 replies
NNuxt
Created by tim on 6/12/2024 in #❓・help
Nuxt 3.12.1 Update: Prerender Error with app.use Function
This was the initial (500) error:
message-compiler.mjs:94 Uncaught (in promise) SyntaxError: Need to install with `app.use` function (at message-compiler.mjs:94:19)
at createCompileError (message-compiler.mjs:94:19)
at createI18nError (vue-i18n.mjs:103:12)
at useI18n (vue-i18n.mjs:2325:15)
at setup (app.vue:13:40)
at callWithErrorHandling (runtime-core.esm-bundler.js:195:19)
at setupStatefulComponent (runtime-core.esm-bundler.js:7630:25)
at setupComponent (runtime-core.esm-bundler.js:7591:36)
at mountComponent (runtime-core.esm-bundler.js:5917:7)
at processComponent (runtime-core.esm-bundler.js:5883:9)
at patch (runtime-core.esm-bundler.js:5351:11)
message-compiler.mjs:94 Uncaught (in promise) SyntaxError: Need to install with `app.use` function (at message-compiler.mjs:94:19)
at createCompileError (message-compiler.mjs:94:19)
at createI18nError (vue-i18n.mjs:103:12)
at useI18n (vue-i18n.mjs:2325:15)
at setup (app.vue:13:40)
at callWithErrorHandling (runtime-core.esm-bundler.js:195:19)
at setupStatefulComponent (runtime-core.esm-bundler.js:7630:25)
at setupComponent (runtime-core.esm-bundler.js:7591:36)
at mountComponent (runtime-core.esm-bundler.js:5917:7)
at processComponent (runtime-core.esm-bundler.js:5883:9)
at patch (runtime-core.esm-bundler.js:5351:11)
This is the latest (500) error:
[nuxt] error caught during app initialization TypeError: Cannot destructure property 'url' of 'config' as it is undefined.
at setup (supabase.client.mjs:11:13)
at client.mjs:35:36
at executeAsync (index.mjs:111:19)
at setup (client.mjs:35:36)
at nuxt.js:137:60
at fn (nuxt.js:214:44)
at Object.runWithContext (runtime-core.esm-bundler.js:3980:18)
at callWithNuxt (nuxt.js:220:24)
at nuxt.js:37:41
at EffectScope.run (reactivity.esm-bundler.js:43:16)
[nuxt] error caught during app initialization TypeError: Cannot destructure property 'url' of 'config' as it is undefined.
at setup (supabase.client.mjs:11:13)
at client.mjs:35:36
at executeAsync (index.mjs:111:19)
at setup (client.mjs:35:36)
at nuxt.js:137:60
at fn (nuxt.js:214:44)
at Object.runWithContext (runtime-core.esm-bundler.js:3980:18)
at callWithNuxt (nuxt.js:220:24)
at nuxt.js:37:41
at EffectScope.run (reactivity.esm-bundler.js:43:16)
9 replies