diff --git a/src/cli/domain/ocConfig.ts b/src/cli/domain/ocConfig.ts
index 93ed681e..65cfdc0e 100644
--- a/src/cli/domain/ocConfig.ts
+++ b/src/cli/domain/ocConfig.ts
@@ -9,6 +9,10 @@ export interface OpenComponentsConfig {
registries?: string[];
/** Development-specific configuration settings */
development?: {
+ /** JavaScript code to be included in the preview HTML's
section.
+ * Can be either a filepath to a JS script or inline JavaScript code.
+ */
+ preload?: string;
/** Fallback configuration for when components cannot be found locally */
fallback?: {
/** URL of the fallback registry to use when components cannot be found locally */
@@ -41,6 +45,7 @@ type ParsedConfig = {
sourcePath?: string;
registries: string[];
development: {
+ preload?: string;
plugins: {
dynamic?: Record;
static?: Record;
@@ -84,6 +89,7 @@ function parseConfig(config: OpenComponentsConfig): ParsedConfig {
...config,
registries: config.registries || [],
development: {
+ preload: config.development?.preload,
plugins,
fallback: config.development?.fallback
}
diff --git a/src/cli/facade/dev.ts b/src/cli/facade/dev.ts
index d20717a0..5275ad64 100644
--- a/src/cli/facade/dev.ts
+++ b/src/cli/facade/dev.ts
@@ -43,9 +43,9 @@ const dev = ({ local, logger }: { logger: Logger; local: Local }) =>
let fallbackRegistryUrl = opts.fallbackRegistryUrl;
let fallbackClient = false;
+ const localConfig = getOcConfig(componentsDir);
if (!fallbackRegistryUrl) {
try {
- const localConfig = getOcConfig(componentsDir);
if (
!fallbackRegistryUrl &&
typeof localConfig.development?.fallback?.url === 'string'
@@ -207,7 +207,8 @@ const dev = ({ local, logger }: { logger: Logger; local: Local }) =>
path: path.resolve(componentsDir),
port,
templates: dependencies.templates,
- verbosity: 1
+ verbosity: 1,
+ preload: localConfig.development?.preload
});
registerPlugins(registry);
diff --git a/src/registry/domain/options-sanitiser.ts b/src/registry/domain/options-sanitiser.ts
index ee005420..2b5238fe 100644
--- a/src/registry/domain/options-sanitiser.ts
+++ b/src/registry/domain/options-sanitiser.ts
@@ -113,6 +113,31 @@ export default function optionsSanitiser(input: RegistryOptions): Config {
options.templates = [];
}
+ // Handle preload script - if it's a filepath, read the file content
+ if (
+ options.preload &&
+ !options.preload.includes(';') &&
+ !options.preload.includes('{')
+ ) {
+ try {
+ const fs = require('node:fs');
+ const path = require('node:path');
+ const preloadPath = path.isAbsolute(options.preload)
+ ? options.preload
+ : path.resolve(process.cwd(), options.preload);
+
+ if (fs.existsSync(preloadPath)) {
+ options.preload = fs.readFileSync(preloadPath, 'utf8');
+ }
+ } catch (error) {
+ // If file reading fails, keep the original value (might be inline JS)
+ console.warn(
+ `Warning: Could not read preload file "${options.preload}":`,
+ (error as Error).message
+ );
+ }
+ }
+
if (options.compileClient || options.compileClient !== false) {
const clientOptions =
typeof options.compileClient === 'boolean'
diff --git a/src/registry/routes/component-preview.ts b/src/registry/routes/component-preview.ts
index f18c842a..b9118632 100644
--- a/src/registry/routes/component-preview.ts
+++ b/src/registry/routes/component-preview.ts
@@ -37,6 +37,7 @@ function componentPreview(
: undefined,
href: res.conf.baseUrl,
liveReload,
+ preload: res.conf.preload,
qs: urlBuilder.queryString(req.query as any),
templates
})
diff --git a/src/registry/views/preview.ts b/src/registry/views/preview.ts
index a881e7f1..68d2343d 100644
--- a/src/registry/views/preview.ts
+++ b/src/registry/views/preview.ts
@@ -7,6 +7,7 @@ export default function preview(vm: {
qs: string;
liveReload: string;
templates: TemplateInfo[];
+ preload?: string;
}): string {
const baseUrl = vm.href.replace('http://', '//').replace('https://', '//');
const { name, version } = vm.component;
@@ -18,6 +19,7 @@ export default function preview(vm: {
return `
+ ${vm.preload ? `` : ''}