Syntax Highlighting
eziwiki uses Shiki for beautiful, accurate syntax highlighting.
Why Shiki?
- Accurate β uses the same TextMate grammars as VS Code
- Beautiful β the highlighting you already know from your editor
- Zero client cost β code is highlighted during the build, so no highlighter is sent to the browser
- Both themes at once β light and dark are emitted as CSS variables, so switching theme never flashes or re-highlights
Supported Languages
Shiki bundles grammars for over a hundred languages β JavaScript, TypeScript, Python, Go, Rust, C, C++, C#, Java, Ruby, PHP, SQL, GraphQL, HTML, CSS, YAML, TOML, Bash, and so on.
Only what you use is loaded
Loading all of them costs about twenty seconds before the first page renders, so eziwiki scans your content for the languages it actually contains and loads only those, plus a handful of common defaults. This site loads sixteen grammars and initialises in well under a second.
The practical effect: write a fence in any supported language and it just works β the next build picks it up. A fence whose language Shiki does not recognise renders as plain text rather than failing the build.
Usage
Basic Code Block
Use triple backticks with a language identifier:
```javascript
function greet(name) {
return `Hello, ${name}!`;
}
```Result:
function greet(name) {
return `Hello, ${name}!`;
}TypeScript Example
```typescript
interface User {
id: string;
name: string;
email: string;
}
async function fetchUser(id: string): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
```interface User {
id: string;
name: string;
email: string;
}
async function fetchUser(id: string): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}Python Example
```python
def calculate_fibonacci(n: int) -> list[int]:
"""Generate Fibonacci sequence."""
if n <= 0:
return []
fib = [0, 1]
for i in range(2, n):
fib.append(fib[i-1] + fib[i-2])
return fib
```def calculate_fibonacci(n: int) -> list[int]:
"""Generate Fibonacci sequence."""
if n <= 0:
return []
fib = [0, 1]
for i in range(2, n):
fib.append(fib[i-1] + fib[i-2])
return fibConfiguration
Change Theme
Edit lib/markdown/highlighter.ts:
import { getHighlighter } from 'shiki';
const highlighter = await getHighlighter({
themes: ['github-light', 'github-dark'], // Change themes here
langs: ['javascript', 'typescript', ...],
});Available Themes
Popular themes:
github-light,github-dark(default)norddraculamonokaione-dark-promaterial-themesolarized-light,solarized-dark
See all themes.
Add Languages
Add more languages to support:
const highlighter = await getHighlighter({
themes: ['github-light', 'github-dark'],
langs: [
'javascript',
'typescript',
'python',
'rust', // Add Rust
'kotlin', // Add Kotlin
'swift', // Add Swift
],
});Dark Mode Support
Code blocks automatically adapt to the theme:
// Light mode: github-light theme
// Dark mode: github-dark theme
const html = highlighter.codeToHtml(code, {
lang: 'javascript',
theme: isDark ? 'github-dark' : 'github-light',
});Inline Code
Inline code uses a simple monospace style:
Use `const` instead of `var` in JavaScript.Use const instead of var in JavaScript.
Line Numbers
To add line numbers, modify the highlighter configuration:
const html = highlighter.codeToHtml(code, {
lang: 'javascript',
theme: 'github-light',
lineNumbers: true, // Enable line numbers
});Line Highlighting
Highlight specific lines:
const html = highlighter.codeToHtml(code, {
lang: 'javascript',
theme: 'github-light',
lineOptions: [
{ line: 3, classes: ['highlighted'] },
{ line: 5, classes: ['highlighted'] },
],
});Copy Button
Add a copy button to code blocks:
'use client';
import { useState } from 'react';
import { Copy, Check } from 'lucide-react';
export function CodeBlock({ code, lang }: { code: string; lang: string }) {
const [copied, setCopied] = useState(false);
const copyCode = async () => {
await navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
<div className="relative">
<button
onClick={copyCode}
className="absolute top-2 right-2 p-2 rounded bg-gray-700 hover:bg-gray-600"
>
{copied ? <Check size={16} /> : <Copy size={16} />}
</button>
<pre>
<code>{code}</code>
</pre>
</div>
);
}Language Detection
If no language is specified, Shiki tries to detect it:
```
function hello() {
console.log('Hello!');
}
```But it's better to always specify the language:
```javascript
function hello() {
console.log('Hello!');
}
```Performance
Build-Time Rendering
Code blocks are highlighted at build time, not runtime:
// During build
const html = highlighter.codeToHtml(code, { lang, theme });
// Served as static HTML
<div dangerouslySetInnerHTML={{ __html: html }} />This means:
- Fast loading - No client-side processing
- Small bundle - No syntax highlighting library in browser
- SEO friendly - Fully rendered HTML
Bundle Size
Shiki only runs at build time, so it doesn't increase your client bundle size.
Best Practices
Always Specify Language
β
Good:
```javascript
const x = 10;
```
β Bad:
```
const x = 10;
```Use Proper Indentation
β
Good:
```javascript
function example() {
if (true) {
console.log('Properly indented');
}
}
```
β Bad:
```javascript
function example() {
if (true) {
console.log('Bad indentation');
}
}
```Add Comments
```javascript
// Initialize user data
const user = {
name: 'Alice',
email: 'alice@example.com',
};
// Send welcome email
sendEmail(user.email, 'Welcome!');
```Keep Examples Focused
β
Good - focused example:
```javascript
// Calculate total
const total = items.reduce((sum, item) => sum + item.price, 0);
```
β Bad - too much code:
```javascript
// 100 lines of unrelated code...
```Troubleshooting
Language Not Recognized
If a language isn't highlighted:
- Check the language name is correct
- Add it to
langsarray in highlighter config - See supported languages
Theme Not Working
If theme doesn't apply:
- Check theme name is correct
- Add it to
themesarray in highlighter config - Rebuild the site:
npm run build
Code Not Highlighting
If code blocks aren't highlighted:
- Check triple backticks are correct
- Verify language identifier is specified
- Check for syntax errors in code
- Rebuild the site
Examples
Diff Highlighting
Show code changes:
```diff
- const oldValue = 10;
+ const newValue = 20;
```Shell Commands
```bash
# Install dependencies
npm install
# Start dev server
npm run dev
```Configuration Files
```json
{
"name": "my-project",
"version": "1.0.0",
"scripts": {
"dev": "next dev",
"build": "next build"
}
}
```