Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ generated: true
---
## vendureDashboardPlugin

<GenerationInfo sourceFile="packages/dashboard/vite/vite-plugin-vendure-dashboard.ts" sourceLine="242" packageName="@vendure/dashboard" since="3.4.0" />
<GenerationInfo sourceFile="packages/dashboard/vite/vite-plugin-vendure-dashboard.ts" sourceLine="254" packageName="@vendure/dashboard" since="3.4.0" />

This is the Vite plugin which powers the Vendure Dashboard, including:

Expand All @@ -23,7 +23,7 @@ Parameters

## VitePluginVendureDashboardOptions

<GenerationInfo sourceFile="packages/dashboard/vite/vite-plugin-vendure-dashboard.ts" sourceLine="39" packageName="@vendure/dashboard" since="3.4.0" />
<GenerationInfo sourceFile="packages/dashboard/vite/vite-plugin-vendure-dashboard.ts" sourceLine="40" packageName="@vendure/dashboard" since="3.4.0" />

Options for the [vendureDashboardPlugin](/reference/dashboard/vite-plugin/vendure-dashboard-plugin#venduredashboardplugin) Vite plugin.

Expand Down Expand Up @@ -85,6 +85,17 @@ type VitePluginVendureDashboardOptions = {
* The path to the directory where the generated GraphQL Tada files will be output.
*/
gqlOutputPath?: string;
/**
* @description
* The directory into which the VendureConfig is transpiled and loaded in order
* to introspect the configuration during the dashboard build.
*
* Defaults to `<project>/node_modules/.cache/vendure-dashboard-temp`. It must
* not be located inside a `"type": "module"` package (such as
* `@vendure/dashboard` itself), because the config is compiled to CommonJS and
* Node would then load it as ESM, failing with
* `exports is not defined in ES module scope`.
*/
tempCompilationDir?: string;
/**
* @description
Expand Down
2 changes: 1 addition & 1 deletion docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4271,7 +4271,7 @@
"title": "VendureDashboardPlugin",
"slug": "vendure-dashboard-plugin",
"file": "docs/reference/dashboard/vite-plugin/vendure-dashboard-plugin.mdx",
"lastModified": "2026-07-10T14:29:40+02:00"
"lastModified": "2026-07-30T10:08:40+02:00"
}
],
"lastModified": "2026-01-28T14:49:21+01:00"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { i18n } from '@lingui/core';
import { act } from 'react';
import { createRoot } from 'react-dom/client';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import { defaultLocale } from '../../providers/i18n-provider.js';
import { useDashboardExtensions } from './use-dashboard-extensions.js';

const runDashboardExtensions = vi.hoisted(() => vi.fn());

(globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;

vi.mock('virtual:dashboard-extensions', () => ({
runDashboardExtensions,
}));

vi.mock('./define-dashboard-extension.js', () => ({
onExtensionSourceChange: vi.fn(),
}));

describe('useDashboardExtensions', () => {
let container: HTMLDivElement;
let root: ReturnType<typeof createRoot>;

beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
root = createRoot(container);
});

afterEach(async () => {
await act(async () => {
root.unmount();
});
container.remove();
vi.clearAllMocks();
});

it('can evaluate translations before the full locale catalog has loaded', async () => {
let extensionError: unknown;

runDashboardExtensions.mockImplementation(async () => {
try {
const extensionMessageId = ['Extension', 'label'].join(' ');
i18n._(extensionMessageId);
} catch (error) {
extensionError = error;
}
});

function DashboardBootstrap() {
useDashboardExtensions();
return null;
}

await act(async () => {
root.render(<DashboardBootstrap />);
});

expect(runDashboardExtensions).toHaveBeenCalledOnce();
expect(i18n.locale).toBe(defaultLocale);
expect(extensionError).toBeUndefined();
});
});
7 changes: 7 additions & 0 deletions packages/dashboard/src/lib/providers/i18n-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import React from 'react';

export const defaultLocale = 'en';

// Dashboard extensions are evaluated asynchronously during app bootstrap and
// may translate source-locale strings at module scope. Activate an empty source
// catalog synchronously so those translations are safe while the compiled
// dashboard and plugin catalogs load in parallel.
i18n.load(defaultLocale, {});
i18n.activate(defaultLocale);

/**
* We do a dynamic import of just the catalog that we need
* @param locale any locale string
Expand Down
Loading