Displays a block of code with syntax highlighting.

Importing

The component can be imported via:

import { CodeBlock } from '@customerio/pluma-components/react';

Usage

The CodeBlock component requires two arguments:

  • code - a string of code to be shown
  • language - the language of the code

The component uses Shiki for syntax highlighting, and language must be one of the languages it supports.

export function Example() {
	return <div>Hello, world!</div>;
}
import { CodeBlock } from '@customerio/pluma-components/react';

const code = `export function Example() {
	return <div>Hello, world!</div>;
}`;

export default function Example() {
	return <CodeBlock
		code={code}
    language="jsx"
	/>
}

Themes

The CodeBlock component supports all themes supported by Shiki. They will be loaded lazily when the component is rendered.

To change the theme or display mode, the following props are available:

  • lightTheme - the theme to use when the mode is light (by default, catppuccin-latte)
  • darkTheme - the theme to use when the mode is dark (by default, catppuccin-mocha)
  • mode - the display mode to use (by default, dark)

The same values can be configured for every CodeBlock under a PlumaProvider with componentConfig.PlumaCodeBlock. Set shouldMatchColorScheme to use the provider's resolved light or dark color scheme as the CodeBlock mode. An explicit prop on a CodeBlock still overrides the provider-level default.

For example, to use the default light mode, simply set mode to light.

export function Example() {
	return <div>Hello, world!</div>;
}
import { CodeBlock } from '@customerio/pluma-components/react';

const code = `export function Example() {
	return <div>Hello, world!</div>;
}`;

export default function Example() {
	return <CodeBlock
		code={code}
    language="jsx"
		mode="light"
	/>
}

Copy to clipboard

By default, the component renders a "Copy to clipboard" button. This can be disabled by setting withCopyButton to false.

export function Example() {
	return <div>Hello, world!</div>;
}
import { CodeBlock } from '@customerio/pluma-components/react';

const code = `export function Example() {
	return <div>Hello, world!</div>;
}`;

export default function Example() {
	return <CodeBlock
		code={code}
    language="jsx"
		withCopyButton={false}
	/>
}

Line numbers

The component supports showing line numbers in the left gutter by setting withLineNumbers to true. Additionally, it's possible to specify the starting line number with startLineNumber - in case the code block is not starting from line 1.

export function Example() {
	return <div>Hello, world!</div>;
}
export function Example() {
	return <div>Hello, world!</div>;
}
import { CodeBlock } from '@customerio/pluma-components/react';

const code = `export function Example() {
	return <div>Hello, world!</div>;
}`;

export default function Example() {
	return (<>
		<CodeBlock
			code={code}
			language="jsx"
			withLineNumbers={true}
		/>
		<CodeBlock
			mt="200"
			code={code}
			language="jsx"
			withLineNumbers={true}
			startLineNumber={10}
		/>
	</>);
}

JSON block folding

For JSON code blocks, the component supports collapsing/expanding nested blocks. When language is json this is enabled by default, but can be disabled by setting withLineFoldingControls to false.

{
	"menu": {
		"id": "file",
		"value": "File",
		"popup": {
			"menuitem": [{
					"value": "New",
					"onclick": "CreateNewDoc()"
				},
				{
					"value": "Open",
					"onclick": "OpenDoc()"
				},
				{
					"value": "Close",
					"onclick": "CloseDoc()"
				}
			]
		}
	}
}
import { CodeBlock } from '@customerio/pluma-components/react';

const code = `{
	"menu": {
		"id": "file",
		"value": "File",
		"popup": {
			"menuitem": [{
					"value": "New",
					"onclick": "CreateNewDoc()"
				},
				{
					"value": "Open",
					"onclick": "OpenDoc()"
				},
				{
					"value": "Close",
					"onclick": "CloseDoc()"
				}
			]
		}
	}
}`;

export default function Example() {
	return <CodeBlock
		code={code}
    language="json"
	/>
}

Highlights

The component supports highlighting specific lines and/or parts of lines via the highlights prop.

It accepts an array with values of the following types:

  • a number - highlights a specific line
  • a [number, number] tuple - highlights a range of lines (inclusive)
  • an object of shape { line: number } - highlights a specific line
  • an object of shape { lines: [number, number] | [number, number][] } - highlights a range or multiple ranges of lines
  • an object of shape { line: number, columns: [number, number] | [number, number][] } - highlights specific columns in a line
    • this only highlights the specified columns, but not the line itself
client := customerio.NewAPIClient("Insert your App API Key");

request := customerio.SendEmailRequest{
	TransactionalMessageID: "signup_with_existing_account",
	Identifiers: map[string]string{
		"id": "Customer id",
	},
	To: "Recipient email",
}

body, err := client.SendEmail(context.Background(), &request)
if err != nil {
	fmt.Println(err)
}

fmt.Println(body)
import { CodeBlock } from '@customerio/pluma-components/react';

const code = `client := customerio.NewAPIClient("Insert your App API Key");

request := customerio.SendEmailRequest{
	TransactionalMessageID: "signup_with_existing_account",
	Identifiers: map[string]string{
		"id": "Customer id",
	},
	To: "Recipient email",
}

body, err := client.SendEmail(context.Background(), &request)
if err != nil {
	fmt.Println(err)
}

fmt.Println(body)`;

const highlights = [
	1,
	{
		line: 1,
		columns: [36, 59],
	},
	{
		line: 6,
		columns: [10, 21],
	},
	{
		line: 8,
		columns: [7, 22],
	},
	[11, 14]
];

export default function Example() {
	return <CodeBlock
		code={code}
    language="go"
		highlights={highlights}
	/>
}

Variables

Similar to highlights, the component supports inserting label-like elements into the code block to highlight sections that should be replaced with other values.

It accepts an array of objects with the following keys:

  • line - the line number to insert the label at
  • column - the column number to insert the label at
  • value - the string value to insert into the label

The inserted variable labels won't be included in the content when the code block is copied to the clipboard.

client := customerio.NewAPIClient("");

request := customerio.SendEmailRequest{
	TransactionalMessageID: "signup_with_existing_account",
	Identifiers: map[string]string{
		"id": "",
	},
	To: "",
}

body, err := client.SendEmail(context.Background(), &request)
if err != nil {
	fmt.Println(err)
}

fmt.Println(body)
import { CodeBlock } from '@customerio/pluma-components/react';

const code = `client := customerio.NewAPIClient("");

request := customerio.SendEmailRequest{
	TransactionalMessageID: "signup_with_existing_account",
	Identifiers: map[string]string{
		"id": "",
	},
	To: "",
}

body, err := client.SendEmail(context.Background(), &request)
if err != nil {
	fmt.Println(err)
}

fmt.Println(body)`;

const variables = [
	{
		line: 1,
		column: 36,
		value: 'Insert your App API Key',
	},
	{
		line: 6,
		column: 10,
		value: 'Customer id',
	},
	{
		line: 8,
		column: 7,
		value: 'Recipient email',
	},
];

export default function Example() {
	return <CodeBlock
		code={code}
    language="go"
		variables={variables}
	/>
}

API

The code to be formatted

Default:'catppuccin-mocha'

The theme to use for syntax highlighting when mode is dark. Must be one of the themes supported by Shiki.

Highlight specific lines and/or columns. Multiple formats are supported:

  • a number - highlights a specific line
  • a [number, number] tuple - highlights a range of lines (inclusive)
  • an object of shape { line: number } - highlights a specific line
  • an object of shape { lines: [number, number] | [number, number][] } - highlights a range or multiple ranges of lines
  • an object of shape { line: number, columns: [number, number] | [number, number][] } - highlights specific columns in a line
    • this only highlights the specified columns, but not the line itself

Default:true

By default the code block renders with rounded corners, but you can disable this in case you need to embed it elsewhere with matching styling.

The language to use for syntax highlighting. Must be one of the languages supported by Shiki.

When showing the language label, the component will use the language's displayName retrieved from Shiki. If you want to override the value, you can provide one with languageDisplayName.

Default:'catppuccin-latte'

The theme to use for syntax highlighting when mode is light. Must be one of the themes supported by Shiki.

Default:dark

What theme mode to use.

Default:1

Number of the first line.

Insert tag-like variables into the code block to highlight sections that should be replaced with other values. As opposed to highlights, the inserted variable tags won't be copied with the code block content.

Default:true

Whether a "copy to clipboard" button should be shown.

Default:false

Whether a label with the current language's display name should be shown.

Whether to show buttons for collapsing/expanding code blocks. Currently only available for JSON code blocks. Defaults to true when the language is json.

Default:false

Whether line numbers should be shown in the left gutter.