Theme Switcher

Code Block

Code blocks render and apply syntax highlighting to blocks of code.

ngrok-example.js

const listener = await ngrok.connect({
	// session configuration
	addr: `localhost:8080`, // or `8080` or `unix:${UNIX_SOCKET}`
	authtoken: "<authtoken>",
	authtoken_from_env: true,
	on_status_change: (addr, error) => {
		console.log(`disconnected, addr ${addr} error: ${error}`);
	},
	session_metadata: "Online in One Line",
	// listener configuration
	allow_user_agent: "^mozilla.*",
	basic_auth: ["ngrok:online1line"],
	circuit_breaker: 0.1,
	compression: true,
	deny_user_agent: "^curl.*",
	domain: "<domain>",
	ip_restriction_allow_cidrs: ["0.0.0.0/0"],
	ip_restriction_deny_cidrs: ["10.1.1.1/32"],
	metadata: "example listener metadata from nodejs",
	mutual_tls_cas: [fs.readFileSync('ca.crt', 'utf8')],
	oauth_provider: "google",
	oauth_allow_domains: ["<domain>"],
	oauth_allow_emails: ["<email>"],
	oauth_scopes: ["<scope>"],
	oauth_client_id: "<id>",
	oauth_client_secret: "<secret>",
	oidc_issuer_url: "<url>",
	oidc_client_id: "<id>",
	oidc_client_secret: "<secret>",
	oidc_allow_domains: ["<domain>"],
	oidc_allow_emails: ["<email>"],
	oidc_scopes: ["<scope>"],
	proxy_proto: "", // One of: "", "1", "2"
	request_header_remove: ["X-Req-Nope"],
	response_header_remove: ["X-Res-Nope"],
	request_header_add: ["X-Req-Yup:true"],
	response_header_add: ["X-Res-Yup:true"],
	schemes: ["HTTPS"],
	verify_webhook_provider: "twilio",
	verify_webhook_secret: "asdf",
	websocket_tcp_converter: true,
});
import {
	CodeBlock,
	CodeBlockBody,
	CodeBlockCode,
	CodeBlockCopyButton,
	CodeBlockExpanderButton,
	CodeBlockHeader,
	CodeBlockIcon,
	CodeBlockTitle,
	fmtCode,
} from "@ngrok/mantle/code-block";

<CodeBlock>
	<CodeBlockHeader>
		<CodeBlockIcon preset="file" />
		<CodeBlockTitle>…</CodeBlockTitle>
	</CodeBlockHeader>
	<CodeBlockBody>
		<CodeBlockCopyButton />
		<CodeBlockCode language="…" value={fmtCode`…`} />
	</CodeBlockBody>
	<CodeBlockExpanderButton />
</CodeBlock>

Examples

Single Line with a Header

Many code blocks will be single line command line prompts and should be able to render with a header and copy button. This makes it absolutely clear that this example is a command line prompt and not a code sample.

Command Line

sudo unzip ~/Downloads/ngrok-v3-stable-darwin.zip -d /usr/local/bin
<CodeBlock>
	<CodeBlockHeader>
		<CodeBlockIcon preset="cli" />
		<CodeBlockTitle>Command Line</CodeBlockTitle>
	</CodeBlockHeader>
	<CodeBlockBody>
		<CodeBlockCopyButton />
		<CodeBlockCode language="sh" value={fmtCode`sudo unzip ~/Downloads/ngrok-v3-stable-darwin.zip -d /usr/local/bin`} />
	</CodeBlockBody>
</CodeBlock>

Horizontal Scrolling

This example is included to demonstrate that code blocks can scroll horizontally if the content is too wide. Mantle attempts to normalize scrollbar styling across browsers and platforms.

ngrok-example.js

const http = require('http');
const ngrok = require("@ngrok/ngrok");
const server = http.createServer((req, res) => {
	res.writeHead(200);
	res.end("Hello!");
	setTimeout(() => {
		Promise.resolve(() => {
			console.log("url:", server.tunnel.url());
		})
	}, timeout);
});
// Consumes authtoken from env automatically
ngrok.listen(server).then(() => {
	console.log("url:", server.tunnel.url());
});
// really long line here that should wrap around and stuff Officia ipsum sint eu labore esse deserunt aliqua quis irure.
<CodeBlock>
	<CodeBlockHeader>
		<CodeBlockIcon preset="file" />
		<CodeBlockTitle>ngrok-example.js</CodeBlockTitle>
	</CodeBlockHeader>
	<CodeBlockBody>
		<CodeBlockCopyButton />
		<CodeBlockCode
			language="js"
			value={fmtCode`
				const http = require('http');
				const ngrok = require("@ngrok/ngrok");
				const server = http.createServer((req, res) => {
					res.writeHead(200);
					res.end("Hello!");
					setTimeout(() => {
						Promise.resolve(() => {
							console.log("url:", server.tunnel.url());
						})
					}, timeout);
				});
				// Consumes authtoken from env automatically
				ngrok.listen(server).then(() => {
					console.log("url:", server.tunnel.url());
				});
				// really long line here that should wrap around and stuff Officia ipsum sint eu labore esse deserunt aliqua quis irure.
			`}
		/>
	</CodeBlockBody>
</CodeBlock>

No Header or Copy Button

This is the most simple example of our code block component. While very useful, the copy button is optional. It is also perfectly acceptable to render a code block without a header, especially if context is provided in the surrounding content or the code block is self-explanatory eg. “In your index.js file, paste the following:”.

const http = require('http');
const ngrok = require("@ngrok/ngrok");
const server = http.createServer((req, res) => {
	res.writeHead(200);
	res.end("Hello!");
});
// Consumes authtoken from env automatically
ngrok.listen(server).then(() => {
	console.log("url:", server.tunnel.url());
});
<CodeBlock>
	<CodeBlockBody>
		<CodeBlockCode
			language="js"
			value={fmtCode`
				const http = require('http');
				const ngrok = require("@ngrok/ngrok");
				const server = http.createServer((req, res) => {
					res.writeHead(200);
					res.end("Hello!");
				});
				// Consumes authtoken from env automatically
				ngrok.listen(server).then(() => {
					console.log("url:", server.tunnel.url());
				});
			`}
		/>
	</CodeBlockBody>
</CodeBlock>

Single Line with Horizontal Scrolling

This example is included to show the interaction between the copy button and horizontal scrolling on a single verbose terminal command.

ffmpeg -i multichannel.mxf -map 0:v:0 -map 0:a:0 -map 0:a:0 -c:a:0 ac3 -b:a:0 640k -ac:a:1 2 -c:a:1 aac -b:2 128k out.mp4
<CodeBlock>
	<CodeBlockBody>
		<CodeBlockCopyButton />
		<CodeBlockCode
			language="sh"
			value={fmtCode`ffmpeg -i multichannel.mxf -map 0:v:0 -map 0:a:0 -map 0:a:0 -c:a:0 ac3 -b:a:0 640k -ac:a:1 2 -c:a:1 aac -b:2 128k out.mp4`}
		/>
	</CodeBlockBody>
</CodeBlock>

Overriding default language indentation

By default, the code block code will detect the preferred (or required) indentation of the given language. This is important for languages that require a certain indentation style; for example, Python and YAML are space-indented languages, so the code block will use spaces for indentation. This is done to ensure that the code is displayed and copied correctly and is easy to read. However, you can override this by passing the indentation prop to the CodeBlockCode.

traffic-policy.yaml

# yaml indentation MUST use spaces (we infer this for you)
on_http_request:
  actions:
    type: custom-response
    config:
      status_code: 200
      content: Hello, World!

ngrok-example.js (using space indentation)

// by default, mantle decides that javascript uses tabs,
// but this example uses spaces for indentation
const http = require('http');
const ngrok = require("@ngrok/ngrok");
const server = http.createServer((req, res) => {
  res.writeHead(200);
  res.end("Hello!");
  setTimeout(() => {
    Promise.resolve(() => {
      console.log("url:", server.tunnel.url());
    })
  }, timeout);
});
// Consumes authtoken from env automatically
ngrok.listen(server).then(() => {
  console.log("url:", server.tunnel.url());
});
<CodeBlock>
	<CodeBlockHeader>
		<CodeBlockIcon preset="file" />
		<CodeBlockTitle>traffic-policy.yaml</CodeBlockTitle>
	</CodeBlockHeader>
	<CodeBlockBody>
		<CodeBlockCopyButton />
		<CodeBlockCode
			language="yaml"
			value={fmtCode`
				# yaml indentation MUST use spaces (we infer this for you)
				on_http_request:
					actions:
						type: custom-response
						config:
							status_code: 200
							content: Hello, World!
			`}
		/>
	</CodeBlockBody>
</CodeBlock>

<CodeBlock>
	<CodeBlockHeader>
		<CodeBlockIcon preset="file" />
		<CodeBlockTitle>ngrok-example.js (using space indentation)</CodeBlockTitle>
	</CodeBlockHeader>
	<CodeBlockBody>
		<CodeBlockCopyButton />
		<CodeBlockCode
			language="js"
			indentation="spaces"
			value={fmtCode`
				// by default, mantle decides that javascript uses tabs,
				// but this example uses spaces for indentation
				const http = require('http');
				const ngrok = require("@ngrok/ngrok");
				const server = http.createServer((req, res) => {
					res.writeHead(200);
					res.end("Hello!");
					setTimeout(() => {
						Promise.resolve(() => {
							console.log("url:", server.tunnel.url());
						})
					}, timeout);
				});
				// Consumes authtoken from env automatically
				ngrok.listen(server).then(() => {
					console.log("url:", server.tunnel.url());
				});
			`}
		/>
	</CodeBlockBody>
</CodeBlock>

API Reference

The CodeBlock render and apply syntax highlighting to blocks of code and is composed of several sub-components.

CodeBlock

Code blocks render and apply syntax highlighting to blocks of code. Root container for all CodeBlock sub-components.

All props from standard HTML div attributes, plus:

PropTypeDefaultDescription
asChild
booleanfalse

Use the asChild prop to compose the CodeBlock styling and functionality onto alternative element types or your own React components.

CodeBlockBody

The body of the CodeBlock. This is where the CodeBlockCode and optional CodeBlockCopyButton are rendered as direct children.

All props from standard HTML div attributes, plus:

PropTypeDefaultDescription
asChild
booleanfalse

Use the asChild prop to compose the CodeBlockBody styling and functionality onto alternative element types or your own React components.

CodeBlockCode

The CodeBlock content. This is where the code is rendered and syntax highlighted.

All props from standard HTML pre attributes, plus:

PropTypeDefaultDescription
value
string

The code to display in the CodeBlock. Should be code formatted as a string. This code will be passed to our syntax highlighter. You should strongly consider wrapping this input with the fmtCode tagged template literal function helper.

indentation
  • spaces
  • tabs

The type of indentation to use. Can be either spaces or tabs. By default, the code block code will detect the preferred (or required) indentation of the given language. This is important for languages that require a certain indentation style; for example, Python and YAML are space-indented languages, so the code block will use spaces for indentation. This is done to ensure that the code is displayed and copied correctly and is easy to read. However, you can override this behavior with this prop.

language
  • bash
  • cs
  • csharp
  • css
  • dotnet
  • go
  • html
  • java
  • javascript
  • js
  • json
  • jsx
  • markup
  • plain
  • plaintext
  • py
  • python
  • rb
  • ruby
  • rust
  • sh
  • shell
  • text
  • ts
  • tsx
  • txt
  • typescript
  • xml
  • yaml
  • yml
text

The language of the CodeBlock. This will be used to determine how to syntax highlight the code.

CodeBlockHeader

An optional header slot of the CodeBlock. This is where things like theCodeBlockIcon and CodeBlockTitle are rendered.

All props from standard HTML div attributes, plus:

PropTypeDefaultDescription
asChild
booleanfalse

Use the asChild prop to compose the CodeBlockHeader styling and functionality onto alternative element types or your own React components.

CodeBlockTitle

The (optional) title of a CodeBlock. Default renders as an h3 element; use asChild to render something else.

All props from standard HTML h3 attributes, plus:

PropTypeDefaultDescription
asChild
booleanfalse

Use the asChild prop to compose the CodeBlockTitle styling and functionality onto alternative element types or your own React components.

CodeBlockCopyButton

The (optional) copy button of the CodeBlock. Render this as a child of theCodeBlockBody to allow users to copy the code block contents to their clipboard.

All props from standard HTML button attributes, plus:

PropTypeDefaultDescription
onCopy
(value: string) => void

Callback fired when the copy button is clicked, passes the copied text as an argument.

onCopyError
(error: unknown) => void

Callback fired when an error occurs during copying.

asChild
booleanfalse

Use the asChild prop to compose the CodeBlockCopyButton styling and functionality onto alternative element types or your own React components.

CodeBlockExpanderButton

The (optional) expander button of the CodeBlock. Render this as a child of theCodeBlockBody to allow users to expand/collapse the code block contents.

All props from standard HTML button attributes, plus:

PropTypeDefaultDescription
asChild
booleanfalse

Use the asChild prop to compose the CodeBlockExpanderButton styling and functionality onto alternative element types or your own React components.

CodeBlockIcon

A small icon that represents the type of code block being displayed, rendered as an SVG next to the code block title in the code block header. You can pass in a custom SVG component or use one of the presets (you can exclusively pass one of svg or preset).

All props from Icon, plus:

PropTypeDefaultDescription
svg
ReactNode

A custom icon to display in the code block header. You can exclusively pass one of svg or preset

preset
  • cli
  • file
  • traffic-policy

A preset icon to display in the code block header. You can exclusively pass one of svg or preset