Code Groups
Tabbed code examples for multiple languages or approaches
Code groups display multiple related code examples in tabs, perfect for showing the same functionality in different languages or approaches.
Basic Code Group
Create tabs by placing multiple code blocks together with title metadata:
- // JavaScript examplefunction greet(name) {console.log(`Hello, ${name}!`);}greet("World");
- # Python exampledef greet(name):print(f"Hello, {name}!")greet("World")
- // Rust examplefn greet(name: &str) {println!("Hello, {}!", name);}fn main() {greet("World");}
- <CodeGroup>```javascript Example.jsfunction greet(name) {console.log(`Hello, ${name}!`);}``````python Example.pydef greet(name):print(f"Hello, {name}!")``````rust Example.rsfn greet(name: &str) {println!("Hello, {}!", name);}```</CodeGroup>
The text after the language identifier becomes the tab title. Use descriptive names like "Example.js" or "Step 1".
Multi-Language API Examples
Show the same API call in different languages:
- const response = await fetch('https://api.example.com/users', {method: 'POST',headers: {'Content-Type': 'application/json','Authorization': 'Bearer YOUR_TOKEN'},body: JSON.stringify({name: 'Alice',email: 'alice@example.com'})});const data = await response.json();console.log(data);
- import requestsresponse = requests.post('https://api.example.com/users',headers={'Content-Type': 'application/json','Authorization': 'Bearer YOUR_TOKEN'},json={'name': 'Alice','email': 'alice@example.com'})data = response.json()print(data)
- package mainimport ("bytes""encoding/json""net/http")func main() {payload := map[string]string{"name": "Alice","email": "alice@example.com",}jsonData, _ := json.Marshal(payload)req, _ := http.NewRequest("POST","https://api.example.com/users",bytes.NewBuffer(jsonData),)req.Header.Set("Content-Type", "application/json")req.Header.Set("Authorization", "Bearer YOUR_TOKEN")client := &http.Client{}resp, _ := client.Do(req)defer resp.Body.Close()}
- use reqwest::header::{AUTHORIZATION, CONTENT_TYPE};use serde_json::json;#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {let client = reqwest::Client::new();let response = client.post("https://api.example.com/users").header(CONTENT_TYPE, "application/json").header(AUTHORIZATION, "Bearer YOUR_TOKEN").json(&json!({"name": "Alice","email": "alice@example.com"})).send().await?;let data = response.json::<serde_json::Value>().await?;println!("{:?}", data);Ok(())}
Installation Steps
Show installation for different package managers:
- npm i -g relevate
- yarn global add relevate
- pnpm add -g relevate
- bun add -g relevate
Configuration Options
Display different configuration approaches:
- {"name": "My Docs","theme": "sky","colors": {"primary": "#1199fb"}}
- name: My Docstheme: skycolors:primary: "#1199fb"
- name = "My Docs"theme = "sky"[colors]primary = "#1199fb"
Step-by-Step Examples
Use tabs for sequential steps:
- npm i -g relevate
- relevate preview
- {"name": "My Documentation","navigation": {"tabs": [{"id": "docs","label": "Documentation","content": ["index"]}]}}
- relevate a11y
- # Publish via the managed Relevate platform
With Line Highlighting
Code groups support line highlighting:
- async function fetchUser(id) {const response = await fetch(`/api/users/${id}`);if (!response.ok) {throw new Error('Failed to fetch user');}return response.json();}
- import requestsdef fetch_user(user_id):response = requests.get(f'/api/users/{user_id}')if not response.ok:raise Exception('Failed to fetch user')return response.json()
- async fn fetch_user(id: &str) -> Result<User, Error> {let response = reqwest::get(&format!("/api/users/{}", id)).await?;if !response.status().is_success() {return Err(Error::FetchFailed);}Ok(response.json().await?)}
Complex Examples
Show complete implementations across languages:
- import { createServer } from 'http';interface Config {port: number;host: string;}class Server {private config: Config;constructor(config: Config) {this.config = config;}start(): void {const server = createServer((req, res) => {res.writeHead(200, { 'Content-Type': 'text/plain' });res.end('Hello World\n');});server.listen(this.config.port, this.config.host, () => {console.log(`Server running at http://${this.config.host}:${this.config.port}/`);});}}const config: Config = {port: 3000,host: 'localhost'};const server = new Server(config);server.start();
- use axum::{Router,routing::get,response::IntoResponse,};use std::net::SocketAddr;#[derive(Clone)]struct Config {port: u16,host: String,}impl Config {fn address(&self) -> SocketAddr {format!("{}:{}", self.host, self.port).parse().expect("Invalid address")}}async fn handler() -> impl IntoResponse {"Hello World\n"}#[tokio::main]async fn main() {let config = Config {port: 3000,host: "127.0.0.1".to_string(),};let app = Router::new().route("/", get(handler));let addr = config.address();println!("Server running at http://{}", addr);axum::Server::bind(&addr).serve(app.into_make_service()).await.unwrap();}
- from http.server import HTTPServer, BaseHTTPRequestHandlerfrom dataclasses import dataclass@dataclassclass Config:port: inthost: strclass Handler(BaseHTTPRequestHandler):def do_GET(self):self.send_response(200)self.send_header('Content-type', 'text/plain')self.end_headers()self.wfile.write(b'Hello World\n')def main():config = Config(port=3000,host='localhost')server = HTTPServer((config.host, config.port), Handler)print(f'Server running at http://{config.host}:{config.port}/')server.serve_forever()if __name__ == '__main__':main()
Best Practices
Use descriptive tab titles
Use descriptive tab titles
Tab titles should clearly indicate what's inside. Use:
Language names: "JavaScript", "Python", "Rust"
File names: "config.json", "Example.ts"
Steps: "Step 1: Install", "Step 2: Configure"
Keep examples consistent
Keep examples consistent
When showing the same operation in multiple languages, keep the logic and structure as similar as possible so users can easily compare.
Order tabs logically
Order tabs logically
Order tabs by:
Popularity (most common languages first)
Alphabetically
Sequentially (for steps)
Don't overuse tabs
Don't overuse tabs
Code groups are powerful but can be overwhelming. Use them when you genuinely need to show alternatives, not for every code block.
Combine with other features
Combine with other features
Code groups work with:
Line highlighting
Syntax highlighting
Long code examples
Comments and documentation
Common Patterns
SDK Installation
- npm install @example/sdk
- yarn add @example/sdk
- pnpm add @example/sdk
- cargo add example-sdk
- pip install example-sdk
Environment Setup
- brew install relevate
- curl -sSL https://relevate.app/install | sh
- winget install relevate
Framework Examples
- // app/page.tsxexport default function Home() {return <h1>Hello World</h1>}
- // app/routes/_index.tsxexport default function Index() {return <h1>Hello World</h1>}
- <!-- src/routes/+page.svelte --><h1>Hello World</h1>
Code groups are especially useful for documentation that serves multiple audiences (different languages, frameworks, or tools). They keep all options visible without cluttering the page.