These files were already out of step with the project's Prettier config before this branch of work; running `pnpm format` finally swept them up. No semantic changes. Kept separate from the functional commits so the reformatting does not bury them in diff noise.
152 lines
5.1 KiB
Markdown
152 lines
5.1 KiB
Markdown
# Layout Slots Reference
|
|
|
|
The `Layout` component accepts slot props (`React.ReactNode`) for injecting content at specific positions without replacing built-in components. This is the recommended way to extend Rspress before considering eject.
|
|
|
|
Official reference: <https://rspress.rs/ui/layout-components/layout>
|
|
|
|
---
|
|
|
|
## All Available Slots
|
|
|
|
### Navigation Bar
|
|
|
|
| Slot | Position |
|
|
| ---------------- | ------------------------------------ |
|
|
| `beforeNav` | Before the entire navigation bar |
|
|
| `afterNav` | After the entire navigation bar |
|
|
| `beforeNavTitle` | Before the nav title/logo (top-left) |
|
|
| `navTitle` | Replaces the nav title content |
|
|
| `afterNavTitle` | After the nav title/logo |
|
|
| `beforeNavMenu` | Before the nav menu items |
|
|
| `afterNavMenu` | After the nav menu items |
|
|
|
|
### Sidebar & Outline
|
|
|
|
| Slot | Position |
|
|
| --------------- | ----------------------------------- |
|
|
| `beforeSidebar` | Above the left sidebar |
|
|
| `afterSidebar` | Below the left sidebar |
|
|
| `beforeOutline` | Above the right outline (TOC) panel |
|
|
| `afterOutline` | Below the right outline panel |
|
|
|
|
### Home Page
|
|
|
|
| Slot | Position |
|
|
| ---------------- | ------------------------ |
|
|
| `beforeHero` | Before the Hero section |
|
|
| `afterHero` | After the Hero section |
|
|
| `beforeFeatures` | Before the Features grid |
|
|
| `afterFeatures` | After the Features grid |
|
|
|
|
### Doc Page
|
|
|
|
| Slot | Position |
|
|
| ------------------ | ------------------------------------- |
|
|
| `beforeDoc` | At the very beginning of the doc page |
|
|
| `afterDoc` | At the very end of the doc page |
|
|
| `beforeDocContent` | Before the document content area |
|
|
| `afterDocContent` | After the document content area |
|
|
| `beforeDocFooter` | Before the doc footer (prev/next nav) |
|
|
| `afterDocFooter` | After the doc footer |
|
|
|
|
### Global
|
|
|
|
| Slot | Position |
|
|
| ------------ | ---------------------------------------------------------------------- |
|
|
| `top` | At the very top of the entire page |
|
|
| `bottom` | At the very bottom of the entire page |
|
|
| `components` | Custom MDX component overrides (`Record<string, React.ComponentType>`) |
|
|
|
|
---
|
|
|
|
## Usage Pattern
|
|
|
|
All examples below follow the same structure in `theme/index.tsx`. The key parts:
|
|
|
|
- Import `Layout` from `@rspress/core/theme-original` (not `@rspress/core/theme` — that causes circular imports)
|
|
- Re-export everything: `export * from '@rspress/core/theme-original'`
|
|
- Export your custom `Layout` that wraps the original with slot props
|
|
|
|
### Basic — Single Slot
|
|
|
|
```tsx
|
|
// theme/index.tsx
|
|
import { Layout as OriginalLayout } from "@rspress/core/theme-original"
|
|
export * from "@rspress/core/theme-original"
|
|
|
|
export function Layout() {
|
|
return <OriginalLayout beforeNavTitle={<MyLogo />} />
|
|
}
|
|
```
|
|
|
|
### Multiple Slots
|
|
|
|
```tsx
|
|
// theme/index.tsx
|
|
import { Layout as OriginalLayout } from "@rspress/core/theme-original"
|
|
export * from "@rspress/core/theme-original"
|
|
|
|
export function Layout() {
|
|
return (
|
|
<OriginalLayout
|
|
top={<div className="announcement-bar">New version released!</div>}
|
|
bottom={<footer>© 2025 My Company</footer>}
|
|
afterOutline={<div>Related resources</div>}
|
|
/>
|
|
)
|
|
}
|
|
```
|
|
|
|
### With i18n Hooks
|
|
|
|
```tsx
|
|
// theme/index.tsx
|
|
import { Layout as OriginalLayout } from "@rspress/core/theme-original"
|
|
import { useLang } from "@rspress/core/runtime"
|
|
export * from "@rspress/core/theme-original"
|
|
|
|
function LocalizedBanner() {
|
|
const lang = useLang()
|
|
return <div>{lang === "zh" ? "欢迎" : "Welcome"}</div>
|
|
}
|
|
|
|
export function Layout() {
|
|
return <OriginalLayout top={<LocalizedBanner />} />
|
|
}
|
|
```
|
|
|
|
### Override MDX Components
|
|
|
|
The `components` slot accepts a `Record<string, React.ComponentType>` to override how MDX elements render:
|
|
|
|
```tsx
|
|
// theme/index.tsx
|
|
import { Layout as OriginalLayout } from "@rspress/core/theme-original"
|
|
export * from "@rspress/core/theme-original"
|
|
|
|
function CustomH1({ children }: { children: React.ReactNode }) {
|
|
return <h1 style={{ borderBottom: "2px solid var(--rp-c-brand)" }}>{children}</h1>
|
|
}
|
|
|
|
export function Layout() {
|
|
return <OriginalLayout components={{ h1: CustomH1 }} />
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Available Hooks
|
|
|
|
Use these hooks inside slot components. Import from `@rspress/core/runtime`.
|
|
|
|
| Hook | Purpose |
|
|
| ------------------ | ----------------------------------- |
|
|
| `useDark()` | Returns whether dark mode is active |
|
|
| `useLang()` | Returns current language code |
|
|
| `useVersion()` | Returns current doc version |
|
|
| `usePage()` | Returns current page metadata |
|
|
| `usePages()` | Returns all pages metadata |
|
|
| `useSite()` | Returns site-level configuration |
|
|
| `useFrontmatter()` | Returns current page frontmatter |
|
|
| `useI18n()` | Returns i18n translation function |
|