Language Switcher
Add a language picker when you need to switch between languages in a code block.
content.mdx
<CodeSwitcher>```java !!public class Main {public static int factorial(int n) {if (n == 0) {return 1;} else {return n * factorial(n - 1);}}}``````cpp !!int factorial(int n) {if (n == 0) {return 1;} else {return n * factorial(n - 1);}}``````scala !!object Main {def factorial(n: Int): Int = {if (n == 0) {return 1} else {return n * factorial(n - 1)}}}``````py !!def factorial(n):if n == 0:return 1else:return n * factorial(n - 1)``````matlab !!function result = factorial(n)if n == 0result = 1;elseresult = n * factorial(n - 1);endend``````js !!function factorial(n) {if (n === 0) {return 1} else {return n * factorial(n - 1)}}``````kotlin !!fun factorial(n: Int): Int {return if (n == 0) {1} else {n * factorial(n - 1)}}``````go !!func factorial(n int) int {if n == 0 {return 1} else {return n * factorial(n - 1)}}``````swift !!func factorial(n: Int) -> Int {if n == 0 {return 1} else {return n * factorial(n: n - 1)}}``````rust !!fn factorial(n: i32) -> i32 {if n == 0 {return 1;} else {return n * factorial(n - 1);}}``````fsharp !!let rec factorial n =if n = 0 then1elsen * factorial (n - 1)```</CodeSwitcher>
public class Main {public static int factorial(int n) {if (n == 0) {return 1;} else {return n * factorial(n - 1);}}}
Pick a different language from the dropdown to see the code block change.
Implementation
We use the Select
components from shadcn/ui:
npx shadcn@latest add select
Since our component will have state we need a client component:
code.tsx
"use client"import { HighlightedCode, Pre, highlight } from "codehike/code"import { useState } from "react"import {Select,SelectContent,SelectItem,SelectTrigger,SelectValue,} from "@/components/ui/select"export function Code({ highlighted }: { highlighted: HighlightedCode[] }) {const [selectedLang, setSelectedLang] = useState(highlighted[0].lang)const selectedCode = highlighted.find((code) => code.lang === selectedLang)!return (<div className=""><Pre code={selectedCode} className="" /><div className=""><Select value={selectedLang} onValueChange={setSelectedLang}><SelectTrigger className=""><SelectValue /></SelectTrigger><SelectContent position="item-aligned">{highlighted.map(({ lang }, index) => (<SelectItem key={index} value={lang}>{lang}</SelectItem>))}</SelectContent></Select></div></div>)}
If you are using React Server Components, we also need a component to highlight the codeblocks:
language-switcher.tsx
import { RawCode, highlight } from "codehike/code"import { Code } from "./code"export async function CodeSwitcher(props: { code: RawCode[] }) {const highlighted = await Promise.all(props.code.map((codeblock) => highlight(codeblock, "github-dark")),)return <Code highlighted={highlighted} />}
If you want to animate the transitions, you can use the token transitions handler.
If you need to persist and/or sync the selected language across multiple code blocks, you can replace the useState
with a useLocalStorage
hook, for example using @uidotdev/usehooks
or your own implementation.