Skip to main content
The SlideCode component provides syntax-highlighted code blocks powered by highlight.js. Language is automatically inferred from the file extension in the title prop.

Basic Code Slide

Here’s a simple code slide with syntax highlighting:
slides.tsx
import { Slide, SlideBadge, SlideTitle, SlideCode } from 'nextjs-slides';

<Slide key="code">
  <SlideBadge>SlideCode</SlideBadge>
  <SlideTitle className="text-3xl sm:text-4xl md:text-5xl">
    Syntax highlighting
  </SlideTitle>
  <SlideCode title="slide.tsx">{`<Slide>
  <SlideBadge>SlideCode</SlideBadge>
  <SlideTitle>Syntax highlighting</SlideTitle>
  <SlideCode title="example.tsx">{code}</SlideCode>
</Slide>`}</SlideCode>
  <SlideNote>
    Language inferred from title extension (.ts, .tsx, .js, .jsx) · Theme via
    --sh-* and --nxs-code-* CSS variables · Whitespace is auto-trimmed
  </SlideNote>
</Slide>
Supported languages: JavaScript (.js, .jsx), TypeScript (.ts, .tsx), HTML/XML (.html, .xml). Unrecognized extensions fall back to TypeScript highlighting.

Code with Title

The title prop adds a filename label above the code block:
<SlideCode title="example.tsx">{`function Greeting({ name }: Props) {
  return (
    <div className="greeting">
      <h1>Hello, {name}!</h1>
      <button onClick={() => alert('Hi')}>
        Say hi
      </button>
    </div>
  );
}`}</SlideCode>

Multiple Code Blocks

You can stack multiple code blocks on a single slide:
slides.tsx
<Slide key="multiple-code" align="left">
  <SlideBadge>Components</SlideBadge>
  <SlideTitle>Component and Hook</SlideTitle>
  
  <SlideCode title="Button.tsx">{`export function Button({ onClick, children }) {
  return (
    <button onClick={onClick} className="btn">
      {children}
    </button>
  );
}`}</SlideCode>

  <SlideCode title="useCounter.ts">{`import { useState } from 'react';

export function useCounter(initial = 0) {
  const [count, setCount] = useState(initial);
  return { count, increment: () => setCount(c => c + 1) };
}`}</SlideCode>
</Slide>

Side-by-Side Code

Use SlideColumns to show code blocks side by side:
slides.tsx
import {
  Slide,
  SlideBadge,
  SlideTitle,
  SlideSubtitle,
  SlideColumns,
  SlideCode,
  SlideNote,
} from 'nextjs-slides';

<Slide key="columns" align="left">
  <SlideBadge>SlideColumns</SlideBadge>
  <SlideTitle className="text-3xl sm:text-4xl md:text-5xl">
    Title + two columns
  </SlideTitle>
  <SlideSubtitle>
    Inline two-column grid for use inside Slide, when you need a spanning
    title above the columns
  </SlideSubtitle>
  <SlideColumns
    left={
      <SlideCode title="slide.tsx">{`<Slide>
  <SlideTitle>Two columns</SlideTitle>
  <SlideColumns
    left={...}
    right={...}
  />
</Slide>`}</SlideCode>
    }
    right={
      <SlideCode title="slide.tsx">{`<SlideColumns
  left={<SlideCode>...</SlideCode>}
  right={<SlideList>...</SlideList>}
/>`}</SlideCode>
    }
  />
  <SlideNote>
    Props: left, right, className · Unlike SlideSplitLayout, this is a child
    component, not a full-viewport slide
  </SlideNote>
</Slide>

Different Languages

<SlideCode title="component.tsx">{`interface Props {
name: string;
age: number;
}

export function User({ name, age }: Props) {
return <div>{name} is {age} years old</div>;
}`}</SlideCode>

Full-Width Code with Split Layout

Use SlideSplitLayout for full-viewport split between description and code:
slides.tsx
import {
  SlideSplitLayout,
  SlideBadge,
  SlideTitle,
  SlideSubtitle,
  SlideCode,
} from 'nextjs-slides';

<SlideSplitLayout
  key="split-code"
  left={
    <>
      <SlideBadge>Pattern</SlideBadge>
      <SlideTitle className="text-3xl sm:text-4xl md:text-5xl">
        Explanation + source
      </SlideTitle>
      <SlideSubtitle>
        Use SlideSplitLayout to pair explanatory content with code examples
      </SlideSubtitle>
    </>
  }
  right={
    <SlideCode title="Counter.tsx">{`'use client';
import { useState } from 'react';

export function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(c => c + 1)}>
      Count: {count}
    </button>
  );
}`}</SlideCode>
  }
/>
SlideSplitLayout is a full-viewport component. Do not nest it inside <Slide>. Use <SlideColumns> inside <Slide> instead if you need a title above the columns.

Complete Code Presentation Example

Here’s a complete example showing a code-focused presentation:
app/slides/slides.tsx
import {
  Slide,
  SlideBadge,
  SlideCode,
  SlideColumns,
  SlideHeaderBadge,
  SlideNote,
  SlideSplitLayout,
  SlideSubtitle,
  SlideTitle,
} from 'nextjs-slides';

export const slides: React.ReactNode[] = [
  // Title
  <Slide key="title" align="left">
    <SlideHeaderBadge>React Hooks Workshop</SlideHeaderBadge>
    <SlideTitle>useState Deep Dive</SlideTitle>
    <SlideSubtitle>Understanding React's fundamental hook</SlideSubtitle>
  </Slide>,

  // Basic example
  <Slide key="basic">
    <SlideBadge>Basics</SlideBadge>
    <SlideTitle>Simple Counter</SlideTitle>
    <SlideCode title="Counter.tsx">{`import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}`}</SlideCode>
  </Slide>,

  // Side by side comparison
  <Slide key="comparison" align="left">
    <SlideBadge>Best Practices</SlideBadge>
    <SlideTitle>Updater Functions</SlideTitle>
    <SlideColumns
      left={
        <SlideCode title="❌ Avoid">{`// Can miss updates
setCount(count + 1);
setCount(count + 1); // Still +1!`}</SlideCode>
      }
      right={
        <SlideCode title="✅ Prefer">{`// Always correct
setCount(c => c + 1);
setCount(c => c + 1); // Now +2!`}</SlideCode>
      }
    />
    <SlideNote>
      Use updater functions when new state depends on previous state
    </SlideNote>
  </Slide>,
];

Styling Code Blocks

Customize code block appearance using CSS variables:
globals.css
@theme inline {
  /* Code block container */
  --nxs-code-bg: #1e1e1e;
  --nxs-code-border: #333;
  --nxs-code-text: #d4d4d4;
  
  /* Syntax highlighting */
  --sh-keyword: #569cd6;    /* if, const, function */
  --sh-string: #ce9178;     /* "strings" */
  --sh-property: #9cdcfe;   /* object.property */
  --sh-class: #4ec9b0;      /* ClassName */
  --sh-entity: #dcdcaa;     /* functionName */
  --sh-tag: #569cd6;        /* <div> */
  --sh-comment: #6a9955;    /* // comments */
}
See the Custom Styling guide for more details.

Next Steps

Interactive Demos

Combine code with live interactive demos

Layout Components

Learn about SlideColumns and SlideSplitLayout

Custom Styling

Customize syntax highlighting themes

Content Components

Explore all content primitives

Build docs developers (and LLMs) love