Skip to content

Latest commit

 

History

History
94 lines (71 loc) · 1.97 KB

README.md

File metadata and controls

94 lines (71 loc) · 1.97 KB

This is a Next.js project bootstrapped with create-next-app.

Modified to work with Shiki.

Getting Started

First, run the development server:

npm run dev

Open http://localhost:3000. You should see

Shiki Safari

Diffs

Refer to this commit for full diff: b2639c7.

Notably, you need to set serverComponentsExternalPackages in next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
+  experimental: {
+    serverComponentsExternalPackages: ['shiki', 'vscode-oniguruma']
+  }
}

module.exports = nextConfig

lib/shiki.ts

import type { Highlighter, Lang, Theme } from 'shiki'
import { renderToHtml, getHighlighter } from 'shiki'

let highlighter: Highlighter
export async function highlight(code: string, theme: Theme, lang: Lang) {
  if (!highlighter) {
    highlighter = await getHighlighter({
      langs: [lang],
      theme: theme
    })
  }

  const tokens = highlighter.codeToThemedTokens(code, lang, theme, {
    includeExplanation: false
  })
  const html = renderToHtml(tokens, { bg: 'transparent' })

  return html
}

pages/index.tsx

interface Props {
  highlightedHtml: string
}

export default function Home(props: Props) {
  return (
    <>
      <div
        dangerouslySetInnerHTML={{ __html: props.highlightedHtml }}
        style={{ fontFamily: 'var(--font-mono)', fontSize: '2rem' }}
      />
    <>
  )
}

export const getServerSideProps: GetServerSideProps<Props> = async () => {
  const html = await highlight(
    `console.log('hi next.js')`,
    'github-dark',
    'javascript'
  )

  return {
    props: {
      highlightedHtml: html
    }
  }
}

License

MIT © Pine Wu