Default theme

Install

npm install --save @sveltepress/theme-default
sh

Add in your Vite config

vite.config.(js|ts)
+
+
import { defaultTheme } from '@sveltepress/theme-default' 
import { sveltepress } from '@sveltepress/vite'

import { defineConfig } from 'vite'

const config = defineConfig({
  plugins: [
    sveltepress({
      theme: defaultTheme(/** theme options */) 
    })
  ],
})

export default config
js

Types Overview

/// <reference types="vite/client" />
/// <reference types="@sveltepress/vite/types" />
/// <reference types="@sveltejs/kit/vite" />

declare module 'virtual:sveltepress/theme-default' {
  import type {  } from '@sveltepress/docsearch/types'
  import type {  } from '@sveltepress/twoslash'
  import type {  } from '@sveltepress/vite'
  import type {  } from '@vite-pwa/sveltekit'
  import type {  } from 'shiki'
  import type {  } from 'shiki/langs'
  import type {  } from 'svelte'

  export interface WithTitle {
    ?: string
  }

  export interface LinkItem extends WithTitle {
    ?: string
    ?: string
    ?: boolean
    ?: boolean
    ?: LinkItem[]
  }

  export interface AutoSidebarOptions {
    /**
     * Enable auto-generated sidebar
     */
    : boolean
    /**
     * Routes directory, default 'src/routes'
     */
    ?: string
    /**
     * Root paths to generate sidebar for, e.g. ['/guide/', '/reference/']
     * If not specified, auto-detect from top-level route directories
     */
    ?: string[]
  }

  export interface DefaultThemeOptions {
    ?: <LinkItem>
    ?: string
    ?: string
    ?: <string, LinkItem[]> | AutoSidebarOptions
    ?: string
    ?: string
    ?: string
    ?:  & {
      ?: string
    }
    ?: <, 'container' | 'theme'>
    ?:  | string
    ?: {
      : string
      : string
      ?: string
      /**
       * Darker variant of primary, used for accent text on light backgrounds
       * where the primary color alone lacks contrast.
       * Defaults to `#e11d48` when primary is not customized, otherwise falls back to primary.
       */
      ?: string
      ?: string
      ?: {
        : string
        : string
      }
    }
    ?: {
      ?: []
      ?: 
      ?: 
      ?: boolean | 
      /**
       * Code blocks taller than this many lines start collapsed with an
       * "Expand code" bar. Set to 0 to disable collapsing.
       * @default 30
       */
      ?: number
    }
    ?: {
      ?: string
      ?: string
      ?: string
      ?: string
      ?: string
      ?: string
      /** Label of the expand bar on collapsed long code blocks */
      ?: string
      ?: {
        ?: string
        ?: string
        ?: string
        ?: string
        ?: string
      }
      ?: string
    }
    ?: {
      [: string]: string[]
    }
  }
  export type  = <DefaultThemeOptions>

  const : DefaultThemeOptions
  export default 
}

declare module '@sveltepress/theme-default/context' {
  import type {  } from 'svelte/store'

  export interface SveltepressContext {
    : <boolean>
  }
  export const : symbol
}
ts
Expand code

Theme Options

navbar

  • title The label text of the item in the navigation bar.
  • to The link address
  • icon An HTML string. Will show the html content instead of title. It is useful to display a custom icon on the navbar.
  • external Determine whether the link is external or not. Would render an external icon if set to true
  • items Children links. If this prop is provided it would render a dropdown instead of a single link.

discord

The web invite address to the project's Discord server. Would show a discord icon on the navigation bar when provided.

github

The web address of the project's GitHub repository. Would show a GitHub icon on the navigation bar when provided

logo

The address of the site's logo, to be shown on the navigation bar.

sidebar

The sidebar can be configured in two ways:

Auto-generated sidebar

Pass an object with enabled: true to automatically generate the sidebar from your routes directory.

  • enabled - Set to true to enable auto sidebar generation
  • routesDir - Custom routes directory path. Default is 'src/routes'
  • roots - Root paths to generate sidebar for, e.g. ['/guide/', '/reference/']. If not specified, auto-detected from top-level route directories

Pages can control their sidebar appearance via frontmatter:

  • title - Page title, also used as sidebar label
  • sidebarTitle - Override the sidebar label (takes precedence over title)
  • order - Sort order within the same level. Lower numbers appear first. Default is 100
  • sidebar - Set to false to exclude this page from the sidebar
  • collapsible - Whether the sidebar group is collapsible

Manual sidebar

Pass an object where each key is a group route prefix and each value is an array of sidebar items:

  • title The label text of the sidebar item
  • collapsible Determine whether the sidebar group is collapsible or not.
  • to The link address
  • items Children links. If this prop is provided would render a sidebar group instead of a single sidebar item

highlighter

An object that contains custom highlight options.

  • languages - Customize the supported highlight languages. Default is: ['svelte', 'sh', 'js', 'html', 'ts', 'md', 'css', 'scss']
  • themeLight - The code theme that will be applied in light mode. Default is vitesse-light
  • themeDark - The code theme that will be applied in dark mode. Default is night-owl
  • twoslash - Set to true to enable Twoslash . Default is false
  • codeCollapseLines - Collapse code blocks taller than this number of lines. Default is 30; set it to 0 to disable collapsing.
TIP

You can get all the supported languages and themes in Shiki Repo

editLink

The link used for bottom edit this page on GitHub button For example this site uses https://github.com/SveltePress/sveltepress/edit/main/packages/docs-site/src/routes/:route

:route represent the route path, for example: /foo/bar/+page.md

ga

The id provided by Google Analytics . Something like G-XXXXXXX.

Would add gtag script in site head if provided.

search

The supported custom-search hook, with type Component | string. Use it to integrate a Svelte search component such as @sveltepress/meilisearch. A string identifies the wrapper component's source path:

import {  } from '@sveltepress/theme-default'

({
  : '/src/lib/MeilisearchSearch.svelte',
})
ts
Known production build bug

This public API and M Search integration are supported, but the current default-theme runtime does not bundle a source .svelte path into static production output. Passing a component directly is also lost during theme-option serialization. This is a production bundling bug, not an unsupported feature. See the search guide for the wrapper setup and deployment caveat.

docsearch

  • appId
  • apiKey
  • indexName

All these values are provided by Algolia. Visit Docsearch for more details.

docsearch is used only when search is not provided.

pwa

See PWA for details.

themeColor

The color of window bar when opened as a local PWA application.

  • light - the color that applied on light theme
  • dark - the color that applied on dark theme
  • gradient - the gradient theme color. Would be applied on home page action button and main title. Default is:
const defaultGradient = {
  start: '#fa709a',
  end: '#fee140',
}
js
  • primary - the primary theme color of the site
  • primaryDeep - a darker primary color used for accessible accent text on light backgrounds
  • hover - the hovered links color

i18n

The fixed text contents that can be replaced by your config.

  • onThisPage - The text for "On this page"
  • suggestChangesToThisPage - The text for "Suggest changes to this page"
  • lastUpdateAt - The text for "Last update at:"
  • previousPage - The text for "Previous"
  • nextPage - The text for "Next"
  • expansionTitle - The text for "Click to expand/fold code" in markdown or svelte live code
  • expandCode - The label on the expand bar for collapsed long code blocks
  • pwa - The PWA prompt relative text contents. All of the following fields correspond to the same text in PWA prompt
    • tip
    • reload
    • close
    • appReadyToWorkOffline
    • newContentAvailable
  • footnoteLabel - The auto generated footnotes title. Default is "Footnotes"

preBuildIconifyIcons

The icons in Iconify that you want to pre-build for future usage. An object, key is the collection name, value is the icons array. For example these are the icons this site using:

preBuildIconifyIcons: {
  'vscode-icons': ['file-type-svelte', 'file-type-markdown', 'file-type-vite'],
  'logos': ['typescript-icon', 'svelte-kit', 'svelte-icon'],
  'emojione': ['artist-palette'],
  'ph': ['smiley', 'layout-duotone'],
  'noto': ['package'],
  'solar': ['chat-square-code-outline', 'reorder-outline'],
  'carbon': ['tree-view-alt', 'import-export'],
  'ic': ['sharp-rocket-launch'],
  'tabler': ['icons'],
  'mdi': ['theme-light-dark'],
  'bi': ['list-nested'],
}
ts

These icons looks like this:

<script>
  import {  } from '@sveltepress/theme-default/components'
  import  from 'virtual:sveltepress/theme-default'
</script>
<div ="flex items-center gap-4 text-[48px] flex-wrap">
  {#each .(. || {}) as [, ]}
    {#each  as }
      <div>
        < {} {} />
      </div>
    {/each}
  {/each}
</div>
svelte
View code

Global context

The global context key is in the @sveltepress/theme-default/context. You can get all the contexts with the getContext API

This is an example:

isDark: false
<script lang="ts">
  import type { SveltepressContext } from '@sveltepress/theme-default/context'
  import {  } from '@sveltepress/theme-default/context'
  import {  } from 'svelte'

  const {  } = <SveltepressContext>(
</script>

<div class:dark-text={} ="text-10">
  isDark: {}
</div>
<style>
  .dark-text {
    --at-apply: 'text-red';
  }
</style>
svelte
View code

All contexts:

Virtual modules

virtual:sveltepress/theme-default

This module hold the theme options that pass to defaultTheme() function.

Here's an example for showing the theme options of this site:

    {
  "navbar": [
    {
      "title": "Guide",
      "to": "/guide/introduction/"
    },
    {
      "title": "Reference",
      "to": "/reference/vite-plugin/"
    },
    {
      "title": "Blog theme",
      "to": "/guide/blog-theme/getting-started/"
    },
    {
      "title": "Blog demo",
      "to": "https://sveltepress.github.io/sveltepress/blog-demo/",
      "external": true
    },
    {
      "icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1em\" height=\"1em\" viewBox=\"0 0 32 32\"><path fill=\"currentColor\" d=\"M27.85 29H30l-6-15h-2.35l-6 15h2.15l1.6-4h6.85zm-7.65-6l2.62-6.56L25.45 23zM18 7V5h-7V2H9v3H2v2h10.74a14.71 14.71 0 0 1-3.19 6.18A13.5 13.5 0 0 1 7.26 9h-2.1a16.47 16.47 0 0 0 3 5.58A16.84 16.84 0 0 1 3 18l.75 1.86A18.47 18.47 0 0 0 9.53 16a16.92 16.92 0 0 0 5.76 3.84L16 18a14.48 14.48 0 0 1-5.12-3.37A17.64 17.64 0 0 0 14.8 7z\"/></svg>",
      "items": [
        {
          "title": "简体中文",
          "to": "https://cn.sveltepress.site/",
          "external": true
        },
        {
          "title": "বাংলা",
          "to": "https://bn.sveltepress.site/",
          "external": true
        }
      ]
    }
  ],
  "sidebar": {
    "/guide/": [
      {
        "title": "Introduction",
        "collapsible": true,
        "items": [
          {
            "title": "What is Sveltepress",
            "to": "/guide/introduction/"
          },
          {
            "title": "Quick Start",
            "to": "/guide/quick-start/"
          },
          {
            "title": "Themes",
            "to": "/guide/themes/"
          },
          {
            "title": "Working with TypeScript",
            "to": "/guide/typescript/"
          }
        ]
      },
      {
        "title": "Markdown features",
        "items": [
          {
            "title": "Basic Writing",
            "to": "/guide/markdown/basic-writing/"
          },
          {
            "title": "Frontmatter",
            "to": "/guide/markdown/frontmatter/"
          },
          {
            "title": "Svelte in Markdown",
            "to": "/guide/markdown/svelte-in-markdown/"
          }
        ]
      },
      {
        "title": "Default theme features",
        "collapsible": true,
        "items": [
          {
            "title": "Frontmatter",
            "to": "/guide/default-theme/frontmatter/"
          },
          {
            "title": "Navbar",
            "to": "/guide/default-theme/navbar/"
          },
          {
            "title": "Sidebar",
            "to": "/guide/default-theme/sidebar/"
          },
          {
            "title": "Home page",
            "to": "/guide/default-theme/home-page/"
          },
          {
            "title": "Built-in Components",
            "to": "/guide/default-theme/builtin-components/"
          },
          {
            "title": "Headings & Anchors",
            "to": "/guide/default-theme/headings-and-anchors/"
          },
          {
            "title": "Admonitions",
            "to": "/guide/default-theme/admonitions/"
          },
          {
            "title": "Code related",
            "to": "/guide/default-theme/code-related/"
          },
          {
            "title": "Twoslash",
            "to": "/guide/default-theme/twoslash/"
          },
          {
            "title": "Unocss",
            "to": "/guide/default-theme/unocss/"
          },
          {
            "title": "Search",
            "to": "/guide/default-theme/search/"
          },
          {
            "title": "PWA",
            "to": "/guide/default-theme/pwa/"
          },
          {
            "title": "Google Analytics",
            "to": "/guide/default-theme/google-analytics/"
          }
        ]
      },
      {
        "title": "Blog theme features",
        "collapsible": true,
        "items": [
          {
            "title": "Getting started",
            "to": "/guide/blog-theme/getting-started/"
          },
          {
            "title": "Configuration",
            "to": "/guide/blog-theme/configuration/"
          },
          {
            "title": "Writing posts",
            "to": "/guide/blog-theme/writing-posts/"
          },
          {
            "title": "Features",
            "to": "/guide/blog-theme/features/"
          },
          {
            "title": "Customisation",
            "to": "/guide/blog-theme/customization/"
          }
        ]
      }
    ],
    "/reference/": [
      {
        "title": "Reference",
        "items": [
          {
            "title": "Vite plugin",
            "to": "/reference/vite-plugin/"
          },
          {
            "title": "Default theme",
            "to": "/reference/default-theme/"
          }
        ]
      }
    ]
  },
  "editLink": "https://github.com/SveltePress/sveltepress/edit/main/packages/docs-site/src/routes/:route",
  "github": "https://github.com/SveltePress/sveltepress",
  "logo": "/sveltepress.svg",
  "discord": "https://discord.gg/MeYRrGGxbE",
  "ga": "G-J2W78BKCHB",
  "docsearch": {
    "apiKey": "fbed412316ec83ff28e9a916161bf715",
    "appId": "4D30VFIAMG",
    "indexName": "sveltepress"
  },
  "pwa": {
    "scope": "/",
    "base": "/",
    "strategies": "generateSW",
    "kit": {
      "trailingSlash": "always"
    },
    "darkManifest": "/manifest-dark.webmanifest",
    "manifest": {
      "start_url": "/",
      "scope": "/",
      "name": "Sveltepress",
      "short_name": "Sveltepress",
      "icons": [
        {
          "src": "/android-chrome-192x192.png",
          "sizes": "192x192",
          "type": "image/png"
        },
        {
          "src": "/android-chrome-512x512.png",
          "sizes": "512x512",
          "type": "image/png"
        }
      ],
      "theme_color": "#f2f2f2",
      "background_color": "#f2f2f2",
      "display": "standalone"
    }
  },
  "themeColor": {
    "light": "#f2f2f2",
    "dark": "#18181b"
  },
  "preBuildIconifyIcons": {
    "vscode-icons": [
      "file-type-svelte",
      "file-type-markdown",
      "file-type-vite"
    ],
    "logos": [
      "typescript-icon",
      "svelte-kit",
      "svelte-icon"
    ],
    "emojione": [
      "artist-palette"
    ],
    "ph": [
      "smiley",
      "layout-duotone"
    ],
    "noto": [
      "package"
    ],
    "solar": [
      "chat-square-code-outline",
      "reorder-outline"
    ],
    "carbon": [
      "tree-view-alt",
      "import-export"
    ],
    "ic": [
      "sharp-rocket-launch"
    ],
    "tabler": [
      "icons"
    ],
    "mdi": [
      "theme-light-dark"
    ],
    "bi": [
      "list-nested"
    ]
  },
  "highlighter": {
    "twoslash": true,
    "languages": [
      "svelte",
      "sh",
      "js",
      "html",
      "ts",
      "md",
      "css",
      "scss",
      "json"
    ]
  }
}
  
<script>
  import  from 'virtual:sveltepress/theme-default'
</script>
<div ="viewer">
  <pre>
    {.(, null, 2)}
  </pre>
</div>
<style>
  .viewer {
    max-height: 40vh;
    overflow-y: auto;
    overflow-x: hidden;
  }
</style>
svelte
View code

Working with TypeScript

You need to include @sveltepress/theme-default/types in your src/app.d.ts to get theme options and virtual modules type tips

/src/app.d.ts
/// <reference types="@sveltepress/theme-default/types" />

// Your other types
ts
Last update at: 2026/08/25 17:18