Server-Side Syntax Highlighting
Codesh for Grav is a plugin that provides server-side syntax highlighting for code blocks in your Grav site.
Codesh provides server-side syntax highlighting using Phiki, a PHP port of Shiki that uses TextMate grammars and VS Code themes. All highlighting happens on the server - no JavaScript required, faster page loads, and perfect SEO.
Basic Syntax Highlighting
Tip
View the markdown source for this page to see the raw syntax.
Use the [codesh] shortcode with the language as a shorcode parameter rusulting in:
function greet(name) {
return `Hello, ${name}!`;
}
const message = greet('World');
console.log(message);
def greet(name):
return f"Hello, {name}!"
message = greet("World")
print(message)
<?php
function greet($name) {
return "Hello, {$name}!";
}
$message = greet('World');
echo $message;
Wrapping Markdown Code Blocks
For compatibility with markdown editors, you can wrap standard fenced code blocks:
fn main() {
println!("Hello, Rustaceans!");
}
Supported Languages
Codesh supports 200+ languages via TextMate grammars, including:
| Language | Identifier |
|---|---|
| JavaScript | javascript, js |
| TypeScript | typescript, ts |
| Python | python, py |
| PHP | php |
| Ruby | ruby, rb |
| Go | go |
| Grav | grav |
| Rust | rust, rs |
| Shell/Bash | bash, shell, sh |
| SQL | sql |
| YAML | yaml, yml |
| JSON | json |
| HTML | html |
| CSS | css |
| Markdown | markdown, md |
| Swift | swift |
| Kotlin | kotlin, kt |
| And 180+ more... |
Line Numbers
Enable line numbers with the line-numbers attribute:
1// This block has line numbers
2const a = 1;
3const b = 2;
4const c = a + b;
5console.log(c);
Custom Starting Line
Start from a specific line number:
10# Starting from line 10
11def calculate(x, y):
12 return x + y
13
14result = calculate(5, 3)
Line Highlighting
Highlight specific lines to draw attention using highlight or hl:
1function processData(data) {
2 const filtered = data.filter(item => item.active);
3
4 const mapped = filtered.map(item => ({
5 id: item.id,
6 name: item.name.toUpperCase()
7 }));
8
9 return mapped;
10}
Syntax: highlight="LINE_NUMBERS" where LINE_NUMBERS can be:
- Single lines:
1,3,5 - Ranges:
2-4 - Combined:
1,3-5,8
Line Focus
Focus on specific lines by dimming non-focused lines:
1function example() {
2 // setup code
3 const important = true;
4 doSomething(important);
5 return important;
6 // cleanup code
7}
This is useful for drawing attention to the most important parts of longer code examples.
Title/Filename Display
Show a filename or custom title in the header instead of the language:
<?php
namespace App\Controller;
class UserController extends AbstractController
{
public function index(): Response
{
return $this->render('user/index.html.twig');
}
}
Hide Language Badge
Hide the language badge entirely with hide-lang="true":
npm install
npm run build
Minimal Mode (No Header)
Hide the entire header bar for a super minimal look with hide-header="true":
const minimal = true;
console.log('No header, just code');
Automatic Light/Dark Mode
Codesh automatically detects your theme's light/dark mode setting and uses the appropriate syntax theme. When you toggle the theme, the code blocks switch automatically.
- In light mode: Uses the
theme_lightsetting (default:helios-light) - In dark mode: Uses the
theme_darksetting (default:helios-dark)
Custom Themes
Override the default theme per code block:
GitHub Dark (default)
interface User {
id: number;
name: string;
email: string;
}
Dracula
interface User {
id: number;
name: string;
email: string;
}
Nord
interface User {
id: number;
name: string;
email: string;
}
One Dark Pro
interface User {
id: number;
name: string;
email: string;
}
Tokyo Night
interface User {
id: number;
name: string;
email: string;
}
Catppuccin Mocha
interface User {
id: number;
name: string;
email: string;
}
Rose Pine
interface User {
id: number;
name: string;
email: string;
}
GitHub Light
interface User {
id: number;
name: string;
email: string;
}
Available Themes
Codesh includes 70+ VS Code themes:
| Dark Themes | Light Themes |
|---|---|
github-dark, github-dark-dimmed |
github-light |
dracula, dracula-soft |
one-light |
nord |
solarized-light |
one-dark-pro |
catppuccin-latte |
monokai |
vitesse-light |
tokyo-night |
min-light |
catppuccin-mocha, catppuccin-macchiato |
gruvbox-light-* |
rose-pine, rose-pine-moon |
rose-pine-dawn |
material-theme-* variants |
material-theme-lighter |
vitesse-dark, vitesse-black |
snazzy-light |
ayu-dark |
everforest-light |
night-owl |
|
poimandres |
|
houston |
|
synthwave-84 |
|
vesper |
Terminal Output
Use bash or shell for terminal commands:
$ npm install codesh-plugin
+ [email protected]
added 10 packages in 2.1s
$ npm run build
> Building assets...
> Done in 1.2s
Diff Highlighting
Show code changes with diff (diff=true) syntax:
- const greeting = 'Hello';
+ const greeting = 'Hello, World!';
function sayHello() {
- console.log(greeting);
+ console.log(`${greeting} How are you?`);
}
Code Groups
Display multiple code examples in a tabbed interface. Perfect for showing the same functionality in different languages.
Basic Code Group
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("World"));
def greet(name):
return f"Hello, {name}!"
print(greet("World"))
<?php
function greet($name) {
return "Hello, {$name}!";
}
echo greet("World");
Synced Code Groups
Use the sync attribute to synchronize tab selection across multiple code groups on the same page. When you select a tab in one group, all groups with the same sync key switch to match.
Variable Declaration:
const name = "World";
const greeting = `Hello, ${name}!`;
name = "World"
greeting = f"Hello, {name}!"
$name = "World";
$greeting = "Hello, {$name}!";
Output:
console.log(greeting);
// Output: Hello, World!
print(greeting)
# Output: Hello, World!
echo $greeting;
// Output: Hello, World!
Tab selections are automatically persisted, so they survive page reloads.
Why Codesh?
| Feature | Benefit |
|---|---|
| Server-side rendering | No JavaScript required, instant display |
| 200+ languages | Comprehensive language support |
| 70+ VS Code themes | Beautiful, familiar syntax themes |
| Built-in line highlighting | Highlight specific lines easily |
| Built-in line focus | Draw attention to key code sections |
| TextMate grammars | Accurate, industry-standard highlighting |
| SEO-friendly | Code is in the HTML, fully indexable |
Shortcode Attributes Reference
| Attribute | Description | Example |
|---|---|---|
lang |
Programming language | lang="php" |
theme |
Override syntax theme | theme="dracula" |
line-numbers |
Show line numbers | line-numbers="true" |
start |
Starting line number | start="10" |
highlight / hl |
Lines to highlight | highlight="1,3-5" |
focus |
Lines to focus | focus="2-4" |
title |
Filename or title to display | title="config.yaml" |
hide-lang |
Hide the language badge | hide-lang="true" |
hide-header |
Hide the header bar | hide-header="true" |
class |
Additional CSS class | class="my-class" |
Code Group Attributes
| Attribute | Description | Example |
|---|---|---|
sync |
Sync key for tab synchronization | sync="lang" |
Configuration
Configure defaults in user/config/plugins/codesh.yaml:
enabled: true
active: true
theme_dark: github-dark # Theme for dark mode
theme_light: github-light # Theme for light mode
show_line_numbers: false # Show line numbers by default
process_markdown: true # Auto-highlight markdown code blocks