Customization

Learn how to customize and extend the documentation system—from basic styling tweaks to advanced configuration updates.

Theme Customization

CSS Custom Properties

Override theme variables with custom CSS:

:root {
  --color-primary: #your-brand-color;
  --color-secondary: #your-secondary-color;
  --color-accent: #your-accent-color;
  
  --font-family-sans: 'Your Font', system-ui, sans-serif;
  --font-family-mono: 'Your Mono Font', 'Fira Code', monospace;
  
  --space-unit: 0.25rem;
  --space-xs: calc(var(--space-unit) * 1);
  --space-sm: calc(var(--space-unit) * 2);
  --space-md: calc(var(--space-unit) * 4);
  --space-lg: calc(var(--space-unit) * 6);
  --space-xl: calc(var(--space-unit) * 8);
}

Dark Mode Support

Customize dark mode appearance:

[data-theme="dark"] {
  --color-background: #1a1a1a;
  --color-surface: #2d2d2d;
  --color-text: #ffffff;
  --color-text-muted: #a0a0a0;
  --color-border: #404040;
  
  --color-primary: #66b3ff;
  --color-accent: #ff6b6b;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-background: #1a1a1a;
    --color-text: #ffffff;
  }
}

Custom Fonts

Integrate web fonts:

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Fira+Code:wght@400;500&display=swap');

:root {
  --font-family-sans: 'Inter', system-ui, sans-serif;
  --font-family-mono: 'Fira Code', monospace;
  
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --font-size-3xl: 1.875rem;
}

Layout Customization

Adjust Page Width

.main-content {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 2rem;
}

.prose {
  max-width: 70ch;
}

.wide-content {
  max-width: 100%;
  margin: 0 -2rem;
}
.sidebar {
  width: 280px;
  min-width: 280px;
}

.sidebar-item {
  border-radius: 8px;
  transition: background-color 0.2s ease;
}

.sidebar-item:hover {
  background-color: var(--color-surface);
}

.sidebar-item.active {
  background-color: var(--color-primary);
  color: #fff;
}

Header Customization

.header {
  height: 70px;
  background: linear-gradient(90deg, var(--color-primary), var(--color-accent));
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-border);
}

.logo {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-primary);
}

Component Customization

Buttons

.custom-button {
  background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
  border: none;
  border-radius: 25px;
  padding: 0.75rem 1.5rem;
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.custom-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(0,0,0,0.15);
}

Icons

.icon-xs { font-size: 0.75rem; }
.icon-sm { font-size: 1rem; }
.icon-md { font-size: 1.25rem; }
.icon-lg { font-size: 1.5rem; }
.icon-xl { font-size: 2rem; }

.icon-spin {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

Cards

.custom-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.custom-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 25px rgba(0,0,0,0.15);
}

Configuration Customization

Astro Configuration

import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

export default defineConfig({
  integrations: [mdx()],
  base: '/your-custom-path/',
  site: 'https://your-domain.com',
  outDir: './custom-dist',
  publicDir: './custom-public',
  server: {
    port: 4000,
    host: true
  },
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@import "src/styles/variables.scss";`
        }
      }
    }
  }
});

Project Configuration

Project-level settings live in apps/<project-name>/src/config/project.config.json. Load them with helpers such as getLegacyProjectConfig from @docs/project-config.

{
  "basic": {
    "baseUrl": "/docs/sample-docs",
    "supportedLangs": ["en", "ja"],
    "defaultLang": "en"
  },
  "translations": {
    "ja": {
      "displayName": "サンプルドキュメント",
      "displayDescription": "多言語・多バージョン対応を実演する包括的なサンプルドキュメントです。",
      "categories": {
        "guide": "ガイド",
        "components": "コンポーネント",
        "advanced": "高度な設定",
        "reference": "リファレンス"
      }
    }
  },
  "versioning": {
    "versions": [
      { "id": "v1", "name": "Version 1.0", "isLatest": false },
      { "id": "v2", "name": "Version 2.0", "isLatest": true }
    ]
  }
}

basic.baseUrl affects the published URL, and translations.categories feeds into the generated sidebar. Backups are saved to .backups/project-config-*/; run node scripts/validate-category-structure.js after edits to confirm multi-language consistency.

Content Customization

Custom MDX Components

// src/components/CustomCallout.astro
---
export interface Props {
  type?: 'info' | 'warning' | 'error' | 'success';
  title?: string;
}

const { type = 'info', title } = Astro.props;
---

<div class={`custom-callout custom-callout--${type}`}>
  {title && <div class="custom-callout__title">{title}</div>}
  <div class="custom-callout__content">
    <slot />
  </div>
</div>

<style>
.custom-callout {
  border-left: 4px solid var(--color-primary);
  padding: 1rem;
  margin: 1rem 0;
  border-radius: 4px;
  background: var(--color-surface);
}

.custom-callout--warning {
  border-left-color: var(--color-warning);
  background: rgba(255, 193, 7, 0.1);
}

.custom-callout--error {
  border-left-color: var(--color-danger);
  background: rgba(220, 53, 69, 0.1);
}

.custom-callout--success {
  border-left-color: var(--color-success);
  background: rgba(40, 167, 69, 0.1);
}

.custom-callout__title {
  font-weight: 600;
  margin-bottom: 0.5rem;
}
</style>

Custom Layouts

---
// src/layouts/CustomLayout.astro
import BaseLayout from './BaseLayout.astro';

export interface Props {
  title: string;
  description?: string;
  showSidebar?: boolean;
}

const { title, description, showSidebar = true } = Astro.props;
---

<BaseLayout title={title} description={description}>
  <div class="custom-layout">
    {showSidebar && (
      <aside class="custom-sidebar">
        <!-- Custom sidebar content -->
      </aside>
    )}
    
    <main class="custom-main">
      <header class="custom-header">
        <h1>{title}</h1>
        {description && <p class="description">{description}</p>}
      </header>
      
      <div class="custom-content">
        <slot />
      </div>
    </main>
  </div>
</BaseLayout>

Advanced Customization

Plugin System

// plugins/custom-plugin.js
export function customPlugin(options = {}) {
  return {
    name: 'custom-plugin',
    hooks: {
      'astro:config:setup': ({ addRenderer, config, updateConfig }) => {
        // Custom setup
      },
      'astro:build:start': ({ buildConfig }) => {
        // Before build
      },
      'astro:build:done': ({ dir, routes }) => {
        // After build
      }
    }
  };
}

Internationalization

// src/i18n/languages.ts
export const languages = {
  en: { code: 'en', name: 'English' },
  ja: { code: 'ja', name: '日本語' },
  ko: { code: 'ko', name: '한국어' },
  zh: { code: 'zh', name: '中文' }
};

Performance Optimization

// astro.config.mjs
export default defineConfig({
  image: {
    service: squooshImageService(),
  },
  build: {
    split: true
  },
  prefetch: {
    prefetchAll: true,
    defaultStrategy: 'viewport'
  },
  compressHTML: true,
  vite: {
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['react', 'react-dom'],
            ui: ['@docs/ui']
          }
        }
      }
    }
  }
});

Deployment Customization

Environment Variables

# .env.local
PUBLIC_SITE_URL=https://your-domain.com
PUBLIC_GA_ID=G-XXXXXXXXXX
PUBLIC_SEARCH_API_KEY=your-search-key

DATABASE_URL=your-database-url
API_SECRET=your-api-secret

Build Scripts

{
  "scripts": {
    "build": "astro build",
    "build:staging": "ENVIRONMENT=staging astro build",
    "build:production": "ENVIRONMENT=production astro build",
    "preview": "astro preview",
    "deploy": "npm run build:production && your-deploy-command"
  }
}

Troubleshooting

Styles Not Applying

.docs-content .custom-component {
  /* styles */
}

.urgent-style {
  color: red !important;
}

Build Errors

rm -rf node_modules/.astro
rm -rf dist
pnpm install
pnpm build

Best Practices

Maintainability

  • Prefer CSS variables over hard-coded values
  • Build reusable components
  • Keep configuration centralized

Performance

  • Load only necessary assets
  • Optimize images and media
  • Apply sensible caching

Accessibility

  • Maintain adequate color contrast
  • Support full keyboard navigation
  • Provide meaningful ARIA labels and structure

Next Steps

Once you understand customization: