Global Plugin
The global plugin provides core functionality for registering global UI components, styles, and runtime configuration. It makes shared components and configuration available throughout your documentation site.
Features
- Global Components - Register React components available in all markdown files
- Global Styles - Add site-wide SCSS/CSS stylesheets
- Global UI Components - Add persistent UI elements (header, footer, etc.)
- Runtime Configuration - Expose configuration to client-side code
- Version Management - Handle versioned documentation
- Multi-Site Support - Configure multiple documentation sites
- Login Page - Automatically add authentication pages
Configuration
Configure the global plugin in your doom.config.ts:
import { defineConfig } from '@alauda/doom'
import { globalPlugin } from '@alauda/doom/plugins'
export default defineConfig({
plugins: [
globalPlugin({
version: '2.0.0', // Site version
download: true // Enable download functionality
})
]
})
Plugin Options
Version string for the documentation site. Exposed to runtime code.
Enable download functionality for documentation.
Global Components
The plugin automatically registers components from the runtime components directory, making them available in all markdown files without imports.
Auto-Registration
Components are automatically discovered and registered:
packages/doom/src/plugins/global/index.ts:42-52
markdown: {
globalComponents: fs
.readdirSync(componentsDir)
.filter((file) => {
const basename = path.basename(file, path.extname(file))
return (
!basename.startsWith('_') &&
!basename.endsWith('.d') &&
basename !== 'index'
)
})
.map((file) => path.resolve(componentsDir, file)),
}
Component Rules
Components are registered if they:
- ✅ Exist in the
runtime/components directory
- ✅ Have a valid file extension (
.tsx, .jsx, .ts, .js)
- ✅ Don’t start with underscore (
_private.tsx)
- ✅ Aren’t type definition files (
.d.ts)
- ✅ Aren’t named
index
Usage in Markdown
Once registered, use components directly:
# My Documentation
<Alert type="info">
This component is globally available!
</Alert>
<CodeBlock language="typescript">
const example = "No import needed"
</CodeBlock>
Global Styles
The plugin loads site-wide styles:
packages/doom/src/plugins/global/index.ts:37
globalStyles: pkgResolve('styles/global.scss'),
Adding Custom Styles
Create a styles/global.scss file:
// Custom theme colors
:root {
--primary-color: #3b82f6;
--secondary-color: #8b5cf6;
}
// Global utilities
.highlight {
background-color: var(--primary-color);
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
}
// Component overrides
.rspress-nav {
backdrop-filter: blur(10px);
}
Global UI Components
Register persistent UI elements that appear on every page:
packages/doom/src/plugins/global/index.ts:38-40
globalUIComponents: fs
.readdirSync(globalComponentsDir, 'utf8')
.map((component) => path.resolve(globalComponentsDir, component)),
Use Cases
- Custom Header - Add branding, navigation, search
- Footer - Links, copyright, social icons
- Sidebar - Custom navigation, ads, widgets
- Overlays - Announcement banners, cookie notices
- Analytics - Tracking scripts, monitoring
Example UI Component
import React from 'react'
export default function CustomBanner() {
return (
<div className="custom-banner">
<p>📢 New version available! <a href="/changelog">See what's new</a></p>
</div>
)
}
Runtime Configuration
The plugin exposes configuration through a virtual module:
packages/doom/src/plugins/global/index.ts:54-74
addRuntimeModules(config, isProd) {
return {
'doom-@global-virtual': `export default ${JSON.stringify(
{
userBase: config.userBase,
prefix: config.prefix,
version,
download,
sites: config.sites?.map((site) => ({
...site,
base: addTrailingSlash(
site.base || (site.name === 'acp' ? ACP_BASE : ''),
),
version: site.version,
})),
export: config.export,
},
null,
isProd ? 0 : 2,
)}`
}
}
Accessing Configuration
Import the virtual module in your components:
import globalConfig from 'doom-@global-virtual'
export default function VersionBadge() {
return (
<span className="version">
v{globalConfig.version}
</span>
)
}
Available Fields
interface GlobalVirtual {
userBase: string // Base URL for user content
prefix?: string // URL prefix
version?: string // Site version
download?: boolean // Download enabled
sites?: DoomSite[] // Multi-site configuration
export?: ExportItem[] // Export configuration
}
Multi-Site Configuration
The plugin supports multiple documentation sites:
export default defineConfig({
sites: [
{
name: 'main',
base: '/',
version: '2.0'
},
{
name: 'api',
base: '/api',
version: '2.0'
},
{
name: 'acp',
base: '/acp', // Special handling for ACP
version: '1.5'
}
],
plugins: [
globalPlugin({ version: '2.0.0' })
]
})
Site Navigation
Create a site switcher using the configuration:
import globalConfig from 'doom-@global-virtual'
export function SiteSwitcher() {
return (
<select>
{globalConfig.sites?.map(site => (
<option key={site.name} value={site.base}>
{site.name} (v{site.version})
</option>
))}
</select>
)
}
Login Page
The plugin automatically adds login pages:
packages/doom/src/plugins/global/index.ts:76-97
addPages(config) {
let loginPath: string
for (const ext of ['.js', '.tsx']) {
loginPath = baseResolve(`login/index${ext}`)
if (fs.existsSync(loginPath)) {
break
}
}
if ((config.themeConfig?.locales?.length ?? 0) < 1) {
return [
{
routePath: '/login',
filepath: loginPath!,
},
]
}
const lang = config.lang
return config.themeConfig!.locales!.map((l) => ({
routePath: l.lang && l.lang !== lang ? `/${l.lang}/login` : '/login',
filepath: loginPath,
}))
}
Localized Login
Login pages are automatically generated for each locale:
- English site:
/login
- Chinese site:
/zh/login
- French site:
/fr/login
Custom Login Page
Create a custom login component:
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
export default function LoginPage() {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const navigate = useNavigate()
const handleLogin = async () => {
// Authentication logic
await authenticate(username, password)
navigate('/')
}
return (
<div className="login-page">
<h1>Login</h1>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Username"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button onClick={handleLogin}>Sign In</button>
</div>
)
}
Version Management
Display version information throughout your site:
import globalConfig from 'doom-@global-virtual'
export function Header() {
return (
<header>
<h1>My Docs</h1>
{globalConfig.version && (
<span className="version-badge">
Version {globalConfig.version}
</span>
)}
</header>
)
}
Version-Based Features
Conditionally show features based on version:
import globalConfig from 'doom-@global-virtual'
export function DownloadButton() {
if (!globalConfig.download) {
return null
}
return (
<button onClick={handleDownload}>
Download v{globalConfig.version}
</button>
)
}
Best Practices
- Component Naming - Use PascalCase for global components
- Style Scoping - Use CSS modules or scoped selectors to avoid conflicts
- Performance - Keep global UI components lightweight
- TypeScript - Add type definitions for virtual modules
- Testing - Test components in isolation before making them global
Component Organization
Recommended Structure
packages/doom/
├── src/
│ ├── runtime/
│ │ └── components/ # Global markdown components
│ │ ├── Alert.tsx
│ │ ├── CodeBlock.tsx
│ │ └── _internal/ # Not registered (starts with _)
│ ├── global/ # Global UI components
│ │ ├── Header.tsx
│ │ ├── Footer.tsx
│ │ └── Banner.tsx
│ ├── styles/
│ │ └── global.scss # Global styles
│ └── login/
│ └── index.tsx # Login page
Component Categories
Runtime Components (in markdown):
- Alerts, warnings, notes
- Code blocks with special features
- Tabs, accordions
- Custom formatting
Global UI Components (persistent):
- Header, footer
- Navigation, breadcrumbs
- Announcement banners
- Search overlays
TypeScript Support
Add type definitions for the virtual module:
declare module 'doom-@global-virtual' {
export interface DoomSite {
name: string
base: string
version?: string
}
export interface ExportItem {
// Your export types
}
export interface GlobalVirtual {
userBase: string
prefix?: string
version?: string
download?: boolean
sites?: DoomSite[]
export?: ExportItem[]
}
const globalConfig: GlobalVirtual
export default globalConfig
}
Advanced Usage
Dynamic Component Loading
import { lazy, Suspense } from 'react'
const HeavyComponent = lazy(() => import('./HeavyComponent'))
export default function GlobalWrapper() {
return (
<Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</Suspense>
)
}
Context Providers
import { createContext, useContext } from 'react'
import globalConfig from 'doom-@global-virtual'
const ConfigContext = createContext(globalConfig)
export function useGlobalConfig() {
return useContext(ConfigContext)
}
export default function ConfigProvider({ children }) {
return (
<ConfigContext.Provider value={globalConfig}>
{children}
</ConfigContext.Provider>
)
}
Troubleshooting
Components Not Available
If global components aren’t working:
- Verify file is in
runtime/components directory
- Check filename doesn’t start with
_
- Ensure valid file extension (
.tsx, .jsx)
- Restart dev server after adding new components
Styles Not Applied
If global styles aren’t loading:
- Check
styles/global.scss exists
- Verify SCSS syntax is valid
- Look for conflicting styles
- Check browser console for errors
Virtual Module Errors
If doom-@global-virtual import fails:
- Add TypeScript declaration file
- Restart TypeScript server
- Check plugin is registered
- Verify build is up to date