Content reuse directives allow you to include external files directly in your markdown content, enabling a "Write Once, Publish Everywhere" strategy.
See also: Content Reuse for detailed strategies, best practices, and common patterns.
Key Terms
- Include Directive
- A directive (
{include}) that includes markdown files directly in your content. Supports line ranges and relative path resolution. - Literal Include Directive
- A directive (
{literalinclude}) that includes code files as syntax-highlighted code blocks. Auto-detects language from file extension and supports line ranges, emphasis, and line numbers. - Snippet
- A reusable content file (typically markdown or code) that can be included in multiple pages. Organized in dedicated directories like
content/snippets/. - Path Resolution
- The process of finding included files. Bengal resolves paths relative to the current page's directory first, then falls back to the site root.
- Path Traversal Prevention
- Security feature that prevents including files outside the site root. Blocks
../sequences and absolute paths to protect against unauthorized file access.
Include
Include markdown files directly in your content.
Syntax:
:::{include} path/to/file.md
:::
With Options:
:::{include} path/to/file.md
:start-line: 5
:end-line: 20
:::
Options:
:start-line:- Starting line number (1-indexed):end-line:- Ending line number (1-indexed)
Path Resolution
Paths are resolved relative to:
- Current page's directory - If you're in
content/docs/content/,snippets/warning.mdlooks incontent/docs/content/snippets/ - Site root - Falls back to site root if not found relative to page
Example: Path Resolution
- Page:
content/docs/getting-started/installation.md - Include:
snippets/warning.md - Resolves to:
content/docs/getting-started/snippets/warning.md(orcontent/snippets/warning.mdif not found)
Examples
Example: Include Entire File
:::{include} snippets/warning.md
:::
Example: Include Specific Lines
:::{include} snippets/api-example.md
:start-line: 5
:end-line: 20
:::
Example: Nested Directives
Included content can use other directives:
<!-- snippets/warning.md -->
:::{warning}
This feature is in beta.
:::
Literal Include
Include code files as syntax-highlighted code blocks.
Syntax:
:::{literalinclude} path/to/file.py
:::
With Options:
:::{literalinclude} path/to/file.py
:language: python
:start-line: 10
:end-line: 25
:emphasize-lines: 15,16,17
:linenos: true
:::
Options:
:language:- Override auto-detected language:start-line:- Starting line number (1-indexed):end-line:- Ending line number (1-indexed):emphasize-lines:- Highlight specific lines:7,8,9or7-9:linenos:- Show line numbers:true,false(default:false)
Language Detection
literalincludeauto-detects language from file extensions:
- Python:
.py - JavaScript:
.js,.ts - Web:
.html,.css - Config:
.yaml,.yml,.json,.toml - Shell:
.sh,.bash,.zsh - And many more
Examples
Example: Basic Include
:::{literalinclude} examples/api.py
:::
Example: With Line Range
:::{literalinclude} examples/api.py
:start-line: 10
:end-line: 25
:::
Example: With Emphasized Lines
:::{literalinclude} examples/api.py
:emphasize-lines: 7,8,9
:::
Example: With Line Numbers
:::{literalinclude} examples/api.py
:linenos: true
:::
Example: Complete Example
:::{literalinclude} examples/api.py
:language: python
:start-line: 10
:end-line: 30
:emphasize-lines: 15,16,17
:linenos: true
:::
Path Resolution
Same as{include}- paths resolve relative to current page's directory, then site root.
Security and Robustness
Both directives include security measures and robustness limits to prevent common issues:
Security
- Path containment: Only allows paths within the site root
- Path traversal protection: Validates
..sequences stay within bounds - Symlink rejection: Symlinks are rejected to prevent escaping containment
- Absolute path rejection: Absolute paths are not allowed
Robustness Limits
| Limit | Value | Purpose |
|---|---|---|
| Maximum include depth | 10 | Prevents stack overflow from deeply nested includes |
| Maximum file size | 10 MB | Prevents memory exhaustion from large files |
| Cycle detection | Automatic | Prevents infinite loops (a.md → b.md → a.md) |
If an include exceeds these limits, an error message is rendered inline with context about the issue.
Best Practices
Organize Snippets
Create a dedicated directory structure:
content/
├── snippets/
│ ├── warnings/
│ │ ├── beta-notice.md
│ │ └── deprecated-feature.md
│ ├── code-examples/
│ │ ├── api-client.py
│ │ └── config.yaml
│ └── common-content/
│ ├── installation-steps.md
│ └── troubleshooting.md
└── docs/
└── guides/
└── my-guide.md # Uses snippets via {include}
Keep Snippets Focused
Each snippet should have a single purpose:
✅ Good:snippets/warnings/beta-notice.md- One warning
❌ Bad:snippets/all-warnings.md- Multiple warnings mixed together
Use Relative Paths
Prefer relative paths for portability:
✅ Good:snippets/warning.md
❌ Bad:/absolute/path/to/warning.md
Document Snippets
Add comments explaining purpose:
<!--
Purpose: Beta feature warning
Used in: Installation guides, API docs
Last updated: 2025-01-15
-->
:::{warning}
This feature is in beta.
:::
Common Patterns
Reusable Warnings
<!-- snippets/warnings/beta.md -->
:::{warning}
This feature is in beta. Please report issues.
:::
Use in multiple pages:
:::{include} snippets/warnings/beta.md
:::
Code Examples
<!-- snippets/code/api-example.py -->
def get_user(user_id: int) -> User:
"""Get user by ID."""
return db.query(User).filter(User.id == user_id).first()
Include with emphasis:
:::{literalinclude} snippets/code/api-example.py
:emphasize-lines: 2
:::
Troubleshooting
File Not Found
Error:Include error: File not found: snippets/warning.md
Solutions:
- Check the path is correct relative to your page
- Verify the file exists
- Try an absolute path from site root:
content/snippets/warning.md
Path Traversal Blocked
Error:Include path traversal rejected
Cause: Attempted to include files outside the site root (security feature)
Solution: Keep all snippets within your site's content directory
Syntax Errors in Included Content
If included markdown has syntax errors, they'll appear in the rendered page.
Solution: Validate snippet files independently before including them
Related
- Content Reuse - Detailed strategies and best practices
- Formatting Directives - Other formatting options