├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── packages
├── docs
│ ├── components
│ │ ├── Code.tsx
│ │ ├── Preview.tsx
│ │ └── theme.ts
│ ├── examples
│ │ ├── CopyCodeToClipboard.tsx
│ │ ├── RenderAdditionalElements.tsx
│ │ └── placeholder-code.ts
│ ├── next-env.d.ts
│ ├── next.config.mjs
│ ├── package.json
│ ├── pages
│ │ ├── _app.tsx
│ │ ├── _meta.json
│ │ ├── api-reference.mdx
│ │ ├── examples.mdx
│ │ ├── index.mdx
│ │ ├── usage.mdx
│ │ └── usage
│ │ │ ├── _meta.json
│ │ │ ├── shiki-support.mdx
│ │ │ ├── with-mdx.mdx
│ │ │ └── with-react-server-components.mdx
│ ├── plugins.mjs
│ ├── postcss.config.js
│ ├── public
│ │ └── banner.jpg
│ ├── styles.css
│ ├── tailwind.config.js
│ ├── theme.config.tsx
│ └── tsconfig.json
└── react-code-block
│ ├── package.json
│ ├── src
│ ├── code-block.tsx
│ ├── contexts.ts
│ ├── index.ts
│ ├── shared
│ │ ├── prop-types.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ ├── shiki
│ │ ├── code-block.tsx
│ │ ├── contexts.ts
│ │ ├── index.ts
│ │ └── types.ts
│ └── types.ts
│ └── tsconfig.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .next
2 | node_modules
3 | dist
4 | out
5 | .DS_Store
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 - Present Akash Hamirwasia
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
React Code Block 🧩
5 |
6 | Set of unstyled UI components to build powerful code blocks in React.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 
22 |
23 | ### Features
24 |
25 | - ✅ **Unstyled**
26 | - ✅ **Syntax highlighting**
27 | - ✅ **Line numbers**
28 | - ✅ **Line highlighting**
29 | - ✅ **Word highlighting**
30 | - ✅ **Theming**
31 | - ✅ **Shiki support**
32 |
33 | ### Getting started
34 |
35 | ```bash
36 | npm i react-code-block prism-react-renderer
37 | ```
38 |
39 | [**Continue with basic example here →**](https://react-code-block.netlify.app/usage#basic-example)
40 |
41 | ### Documentation
42 |
43 | You can find the complete documentation at [**react-code-block.netlify.app**](https://react-code-block.netlify.app)
44 |
45 | ### Why?
46 |
47 | **Let's face it, building code blocks is hard!** There are various libraries out there that handle syntax highlighting, but then you realize that you need more than just
48 | syntax highlighting. If you are writing a technical blog or documentation, chances are you need features like line numbers, line highlighting, word highlighting and so on.
49 | Most of the syntax highlighting libraries don't come with this out-of-the-box, so you have to spend time implementing all this by yourself. Or if they do come with these
50 | features, it's incredibly hard to extend and style them according to the way you want it to be.
51 |
52 | React Code Block solves all these problems by only providing you with the core functionality without any of the styling. You can compose the primitive components from this
53 | library to build any kind of code block you need.
54 |
55 | ### How does it work?
56 |
57 | React Code Block uses an existing syntax highlighting library under the hood for syntax highlighting. On top of this, it adds
58 | additional features like line numbers, line highlighting, etc. which can be styled through the primitive components this package exposes.
59 | Currently supported syntax highlighted libraries:
60 | - [prism-react-renderer](https://github.com/FormidableLabs/prism-react-renderer)
61 | - [shiki](https://shiki.matsu.io/)
62 |
63 | ### License
64 |
65 | React Code Block is [MIT Licensed](https://github.com/blenderskool/react-code-block/blob/master/LICENSE).
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "author": "Akash Hamirwasia",
4 | "workspaces": [
5 | "packages/*"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/docs/components/Code.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 | import { onlyText } from 'react-children-utilities';
3 | import { CodeBlock } from 'react-code-block';
4 | import { useCopyToClipboard } from 'react-use';
5 | import theme from './theme';
6 |
7 | export default function Code({
8 | children,
9 | filename,
10 | hideLineNumbers = false,
11 | words = [],
12 | lines = [],
13 | className = '',
14 | }) {
15 | const [, copyToClipboard] = useCopyToClipboard();
16 | const [isCopied, setIsCopied] = useState(false);
17 | const code = onlyText(children);
18 | const options = children.props.className.split(',');
19 | const language = options[0].replace(/language-/, '');
20 |
21 | const copyCode = () => {
22 | copyToClipboard(code);
23 | setIsCopied(true);
24 | };
25 |
26 | useEffect(() => {
27 | const timeout = setTimeout(() => {
28 | setIsCopied(false);
29 | }, 2000);
30 |
31 | return () => clearTimeout(timeout);
32 | }, [isCopied]);
33 |
34 | return (
35 |
42 |
45 | [**Continue with basic example here →**](./usage#basic-example)
46 |
47 |
48 | ### Why?
49 |
50 | **Let's face it, building code blocks is hard!** There are various libraries out there that handle syntax highlighting, but then you realize that you need more than just
51 | syntax highlighting. If you are writing a technical blog or documentation, chances are you need features like line numbers, line highlighting, word highlighting and so on.
52 | Most of the syntax highlighting libraries don't come with this out-of-the-box, so you have to spend time implementing all this by yourself. Or if they do come with these
53 | features, it's incredibly hard to extend and style them according to the way you want it to be.
54 |
55 | React Code Block solves all these problems by only providing you with the core functionality without any of the styling. You can compose the primitive components from this
56 | library to build any kind of code block you need.
57 |
58 | ### How does it work?
59 |
60 | React Code Block uses an existing syntax highlighting library under the hood for syntax highlighting. On top of this, it adds
61 | additional features like line numbers, line highlighting, etc. which can be styled through the primitive components this package exposes.
62 | Currently supported syntax highlighted libraries:
63 | - [prism-react-renderer](https://github.com/FormidableLabs/prism-react-renderer)
64 | - [shiki](https://shiki.matsu.io/)
65 |
66 | ### License
67 |
68 | React Code Block is [MIT Licensed](https://github.com/blenderskool/react-code-block/blob/master/LICENSE).
69 |
--------------------------------------------------------------------------------
/packages/docs/pages/usage.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra/components';
2 | import { CodeBlock } from 'react-code-block';
3 | import { js } from '../examples/placeholder-code';
4 |
5 | # Usage
6 |
7 | ## Installation
8 |
9 | Start by installing `react-code-block` and its peer-dependency `prism-react-renderer`.
10 |
11 | ```bash hideLineNumbers
12 | npm i react-code-block prism-react-renderer
13 | ```
14 |
15 |
16 | If you prefer using Shiki as the syntax highlighter instead, follow [this guide](/usage/shiki-support) to get started and come back here for all the customization options.
17 |
18 |
19 | ## Basic example
20 |
21 | React Code Block exposes all the un-styled primitives you need to build a code block component through its `CodeBlock` component and various other subcomponents attached to it.
22 |
23 | ```jsx
24 | import { CodeBlock } from 'react-code-block';
25 |
26 | function CodeBlockDemo() {
27 | return (
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | );
36 | }
37 | ```
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | Doesn't look very exciting _just yet_. Because these components are un-styled, **you have to add the styles** to make your code block look the way you want it to be. With a little bit
50 | of CSS(using TailwindCSS in the examples), we can completely change the way the code block looks like.
51 |
52 | ```jsx
53 | import { CodeBlock } from 'react-code-block';
54 |
55 | function CodeBlockDemo({ code, language }) {
56 | return (
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | );
65 | }
66 |
67 | const code = `
68 | async function sayHello(name) {
69 | console.log('Hello', name);
70 | }
71 | `;
72 |
73 | ;
74 | ```
75 |
76 |
77 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | ## Showing line numbers
94 |
95 | To render line numbers for each line in the code block, you can use the `CodeBlock.LineNumber` component. A common approach is to render the line numbers on the left column.
96 | To keep line numbers and the code aligned correctly, you can use CSS Grids or Table layout.
97 |
98 | ```jsx lines={[8]} words={["table-cell", "table-row"]}
99 | import { CodeBlock } from 'react-code-block';
100 |
101 | function CodeBlockDemo({ code, language }) {
102 | return (
103 |
104 |
105 |
126 |
127 |
128 |
129 |
130 | ## Line highlighting
131 |
132 | You can highlight specific lines or line-ranges in your code via the `lines` prop on `CodeBlock` component. State information of **which line should be highlighted is
133 | made available through `isLineHighlighted` render prop** on `CodeBlock.Code` component, so you can add styles for how a line should be highlighted.
134 |
135 | ```jsx words={["lines", "isLineHighlighted"]}
136 | import { CodeBlock } from 'react-code-block';
137 |
138 | function CodeBlockDemo({ code, language }) {
139 | return (
140 |
141 |
142 | {({ isLineHighlighted }) => (
143 |
182 | )}
183 |
184 |
185 |
186 |
187 | ## Word highlighting
188 |
189 | Specific words can be highlighted within a code block using `words` prop on the `CodeBlock` component. State information of **which word to highlight is made available
190 | through `isTokenHighlighted` render prop** on `CodeBlock.Token` component. This can be used to style the highlighted words accordingly.
191 |
192 | ```jsx words={["words", "isTokenHighlighted"]}
193 | import { CodeBlock } from 'react-code-block';
194 |
195 | function CodeBlockDemo({ code, language }) {
196 | return (
197 |
198 |
199 |
200 |
201 | {({ isTokenHighlighted, children }) => (
202 |
209 | {children}
210 |
211 | )}
212 |
213 |
214 |
215 |
216 | );
217 | }
218 | ```
219 |
220 |
221 |
222 |
223 |
224 |
225 | {({ isTokenHighlighted, children }) => (
226 |
231 | {children}
232 |
233 | )}
234 |
235 |
236 |
237 |
238 |
239 |
240 | ## Copy code to clipboard button
241 |
242 | There is no built-in way to show a "Copy code" button in the code block. This is because both the styling and functionality depends on your project and the APIs / libraries
243 | you are using to copy data to user's clipboard. Therefore, you have to implement this feature on your own. An example of how it could look like:
244 |
245 | ```jsx words={['copyCode', 'useCopyToClipboard', 'copyToClipboard']} lines={['24:29']} file=../examples/CopyCodeToClipboard.tsx
246 |
247 | ```
248 |
249 | import CopyCodeToClipboard from '../examples/CopyCodeToClipboard';
250 |
251 |
252 |
253 |
254 |
255 | ## Rendering additional elements
256 |
257 | Since all the `CodeBlock` components are composable in nature, you have complete freedom to render additional elements in your code blocks. This could be showing the
258 | filename, language used, captions, etc.
259 |
260 | ```jsx lines={["7:8", "17:24", "33:36"]} file=../examples/RenderAdditionalElements.tsx
261 |
262 | ```
263 |
264 | import RenderAdditionalElements from '../examples/RenderAdditionalElements';
265 |
266 |
267 |
268 |
269 |
270 | ## Theming
271 |
272 | React Code Block uses `prism-react-renderer` under the hood for syntax highlighting. Default theme is `vsDark` and it can be changed using the `theme` prop in the
273 | `CodeBlock` component. Follow [this guide](https://github.com/FormidableLabs/prism-react-renderer#theming) by `prism-react-renderer` for custom themes.
274 |
275 | ```jsx lines={[2,6]}
276 | import { CodeBlock } from 'react-code-block';
277 | import { themes } from 'prism-react-renderer';
278 |
279 | function CodeBlockDemo({ code, language }) {
280 | return (
281 |
282 |
283 |
306 |
307 |
308 |
309 |
310 | ## Support for more languages
311 |
312 | Please follow the guide by `prism-react-renderer` for this – [github.com/FormidableLabs/prism-react-renderer#custom-language-support](https://github.com/FormidableLabs/prism-react-renderer#custom-language-support)
313 |
--------------------------------------------------------------------------------
/packages/docs/pages/usage/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "with-mdx": "With MDX",
3 | "with-react-server-components": "With Server Components",
4 | "shiki-support": "Shiki Support"
5 | }
6 |
--------------------------------------------------------------------------------
/packages/docs/pages/usage/shiki-support.mdx:
--------------------------------------------------------------------------------
1 | # Shiki Support
2 |
3 | React Code Block also supports rendering code highlighted using [Shiki](https://shiki.matsu.io/) library. Shiki uses the same highlighting engine that is used by VS Code, resulting in
4 | a very high-quality syntax highlighting and support for any VS Code theme.
5 |
6 | import { Steps, Tabs, Callout } from 'nextra/components';
7 |
8 |
9 |
10 | ### Installation
11 |
12 | Start by installing `shiki` as a dependency or a dev-dependency(depending on how you are using it) alongside `react-code-block`:
13 |
14 | ```bash hideLineNumbers
15 | npm i react-code-block
16 | npm i -D shiki
17 | ```
18 |
19 | ### Generate syntax-highlighted code
20 |
21 | Use Shiki to generate syntax-highlighted tokens from your code using the `codeToTokens` function.
22 |
23 | ```js
24 | import { codeToTokens } from 'shiki';
25 |
26 | // Runs preferably in a server-like environment
27 | const tokens = await codeToTokens(code, {
28 | language: 'js',
29 | theme: 'github-dark'
30 | });
31 | ```
32 | #### Where should the above code go?
33 | Because of the nature of Shiki library, typically it is used on the server-side(or build time) for generating syntax-highlighted code, and then a client-side code block component in React
34 | consumes this data to actually render the HTML on the webpage. Depending on your framework, there should be a way to run code in such environments.
35 |
36 |
37 |
38 | Use [React Server Components](https://shiki.matsu.io/packages/next#react-server-component) if you are using App Router, or `getServerSideProps` / `getStaticProps` functions in Pages Router.
39 |
40 | ```tsx filename="CodeBlockDemo.js"
41 | import { codeToTokens } from 'shiki';
42 |
43 | async function CodeBlockDemo({ code }) {
44 | const tokens = await codeToTokens(code, {
45 | language: 'js',
46 | theme: 'github-dark'
47 | });
48 |
49 | // Code from next section goes here.
50 | }
51 | ```
52 |
53 |
54 | Use [`.astro` components](https://docs.astro.build/en/basics/astro-components/) as they run only during build-time or server-side-rendering.
55 |
56 | ```astro filename="CodeBlockDemo.astro"
57 | ---
58 | import { codeToTokens } from 'shiki';
59 |
60 | const { code } = Astro.props;
61 |
62 | const tokens = await codeToTokens(code, {
63 | language: 'js',
64 | theme: 'github-dark'
65 | });
66 | ---
67 |
68 | // Code from next section goes here.
69 | ```
70 |
71 |
72 |
73 |
74 | #### How do I run it completely client-side?
75 | There are ways to run Shiki completely on the client-side like it's [mentioned in their docs](https://shiki.matsu.io/packages/next#react-client-component). An example is shown below.
76 | Be mindful of the bundle size and amount of JavaScript you are loading on client-side just for syntax highlighting.
77 |
78 | ```tsx
79 | import { codeToTokens, TokensResult } from 'shiki/bundle/web';
80 | import { useEffect } from 'react';
81 |
82 | function CodeBlockDemo({ code }) {
83 | const [tokens, setTokens] = useState(null);
84 |
85 | useEffect(() => {
86 | codeToTokens(code, {
87 | language: 'js',
88 | theme: 'github-dark',
89 | })
90 | .then(setTokens);
91 | }, [code]);
92 |
93 | if (!tokens) {
94 | return (
95 |
Loading...
96 | )
97 | }
98 |
99 | // Code from next section goes here.
100 | }
101 | ```
102 |
103 | The above process is async and would show a "Loading..." text to the user while syntax highlight is in process.
104 | To eliminate this, either [move the syntax highlighting code to a server-like environment](#where-should-the-above-code-go) or consider [using the Prism highlighter](/usage).
105 |
106 |
107 | ### Render the syntax-highlighted code
108 | Once you have the syntax-highlighted tokens from your code, you can now use React Code Block package to render the code. First, create a new file with a **Client Component** as shown. Notice how the import is from `react-code-block/shiki` here.
109 |
110 | ```tsx filename="CodeBlockRenderer.js"
111 | 'use client';
112 | import { CodeBlock } from 'react-code-block/shiki';
113 |
114 | function CodeBlockRenderer({ tokens }) {
115 | return (
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | );
127 | }
128 |
129 | export default CodeBlockRenderer;
130 | ```
131 |
132 | Now use the above component to render the syntax-highlighted tokens from the previous section.
133 |
134 |
135 |
136 |
137 | ```tsx filename="CodeBlockDemo.js" className="!mt-0"
138 | import { codeToTokens } from 'shiki';
139 | import CodeBlockRenderer from './CodeBlockRenderer';
140 |
141 | async function CodeBlockDemo({ code }) {
142 | const tokens = await codeToTokens(code, {
143 | language: 'js',
144 | theme: 'github-dark'
145 | });
146 |
147 | return
148 | }
149 | ```
150 |
151 |
152 | ```astro filename="CodeBlockDemo.astro" className="!mt-0"
153 | ---
154 | import { codeToTokens } from 'shiki';
155 | import CodeBlockRenderer from './CodeBlockRenderer';
156 |
157 | const { code } = Astro.props;
158 |
159 | const tokens = await codeToTokens(code, {
160 | language: 'js',
161 | theme: 'github-dark'
162 | });
163 | ---
164 |
165 |
166 | ```
167 |
168 |
169 |
170 | You can now customize the CodeBlock component however you like with features such as line numbers, line highlighting, etc. as documented [here](/usage#showing-line-numbers).
171 |
172 |
173 |
--------------------------------------------------------------------------------
/packages/docs/pages/usage/with-mdx.mdx:
--------------------------------------------------------------------------------
1 | # With MDX
2 |
3 | If you are using [MDX](https://mdxjs.com/) and want to integrate React Code Block with the code blocks defined in `.mdx` files, you can follow this guide. This is a common
4 | practice if you are building a blogging / documentation website over another React framework like Next.js, Remix, or Gatsby.
5 |
6 | import { Steps } from 'nextra/components';
7 |
8 | ## Basic setup
9 |
10 |
11 |
12 | ### Installation
13 |
14 | Start by installing `react-code-block` and its peer-dependency `prism-react-renderer` via npm:
15 |
16 | ```bash hideLineNumbers
17 | npm i react-code-block prism-react-renderer
18 | ```
19 |
20 | ### Configure your `MDXProvider`
21 |
22 | In the `MDXProvider` component you are using to render the parsed markdown data, add a new entry under `components` prop for `pre` tags.
23 |
24 | ```jsx lines={[7]}
25 | function MyBlogLayout({ children }) {
26 | return (
27 | // ...
28 |
34 | {children}
35 |
36 | // ...
37 | );
38 | }
39 | ```
40 |
41 | ### Define your CodeBlock component
42 |
43 | In the previous step, we defined all `pre` tags to render through `MyCodeBlock` component. Now we can build this component using the primitives exposed via React Code Block.
44 |
45 | ```jsx
46 | import { CodeBlock } from 'react-code-block';
47 |
48 | function MyCodeBlock({ children, className }) {
49 | return (
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | );
58 | }
59 | ```
60 |
61 | You can customize this component however you like with features such as line numbers, line highlighting, etc. as documented [here](../usage#showing-line-numbers).
62 |
63 | ### See it in action!
64 |
65 | In an MDX file, try writing a code snippet and see the changes.
66 |
67 | ````mdx filename="index.mdx"
68 | ```js
69 | function sayHello(name) {
70 | console.log('Hello', name);
71 | }
72 | ```
73 | ````
74 |
75 |
76 |
77 | ## Advanced setup
78 |
79 | If you have setup [line and word highlighting](../usage#line-highlighting), you may want to expose these as props in the `mdx` files. This guide goes over setting this up
80 | using the [`rehype-mdx-code-props`](https://github.com/remcohaszing/rehype-mdx-code-props) plugin.
81 |
82 |
83 |
84 | ### Install `rehype-mdx-code-props`
85 |
86 | ```bash hideLineNumbers
87 | npm i rehype-mdx-code-props
88 | ```
89 |
90 | ### Add the plugin to your MDX compiler setup
91 |
92 | This is specific to the framework you are using / setup you have for compiling MDX.
93 |
94 | - Next.js: https://nextjs.org/docs/pages/building-your-application/configuring/mdx#remark-and-rehype-plugins
95 | - Gatsby: https://www.gatsbyjs.com/plugins/gatsby-plugin-mdx/#mdxoptions
96 |
97 | ### Expose the props from your CodeBlock component
98 |
99 | Now you can expose all the props you want from your CodeBlock component that you can pass from mdx files.
100 |
101 | ```jsx lines={['6:8']} words={['/lines/11', '/words/11', '/showLineNumbers/14']}
102 | import { CodeBlock } from 'react-code-block';
103 |
104 | function MyCodeBlock({
105 | children,
106 | className,
107 | lines = [],
108 | words = [],
109 | showLineNumbers = false,
110 | }) {
111 | return (
112 |
113 |
114 |
122 |
123 |
124 | );
125 | }
126 | ```
127 |
128 | ### Start using the props from your `mdx` files!
129 |
130 | You can now pass the props in your code blocks which will get passed down to the `MyCodeBlock` component!
131 |
132 | ````mdx filename="index.mdx"
133 | ```js lines={[2]} showLineNumbers
134 | function sayHello(name) {
135 | console.log('Hello', name);
136 | }
137 | ```
138 | ````
139 |
140 | Note: To see [line highlighting](../usage#line-highlighting) and [word highlighting](../usage#line-highlighting) work correctly, you need to add additional styles for
141 | these states through the render props exposed by `CodeBlock.Code` and `CodeBlock.Token` components respectively.
142 |
143 |
144 |
--------------------------------------------------------------------------------
/packages/docs/pages/usage/with-react-server-components.mdx:
--------------------------------------------------------------------------------
1 | # With React Server Components
2 |
3 | Integrating React Code Block in a React Server Component environment is easy. If you are using Next.js 13+ and the [App Router](https://nextjs.org/docs/app),
4 | you can mark your CodeBlock component as a **Client Component** using `'use client'` directive and things should work as expected.
5 |
6 | ### Why mark it as a Client Component?
7 |
8 | Components exposed by React Code Block use React Context for sharing data, and it can only be used in Client Components. But you can still compose these Client Components
9 | in Server Components and enjoy its benefits of server rendering / not requiring client-side JavaScript(unless there are interactive elements in your code blocks).
10 |
11 | ### Example
12 |
13 | Create your own CodeBlock component and mark it as **Client Component**.
14 |
15 | ```jsx filename="MyCodeBlock.js" lines={[1]}
16 | 'use client';
17 | import { CodeBlock } from 'react-code-block';
18 |
19 | function MyCodeBlock({ code, language }) {
20 | return (
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | );
32 | }
33 |
34 | export default MyCodeBlock;
35 | ```
36 |
37 | Use your `` component normally in other Server / Client components.
38 |
39 | ```jsx lines={[6]}
40 | import MyCodeBlock from './MyCodeBlock';
41 |
42 | export default function Home() {
43 | return (
44 |