Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Commonmark Shiki Highlighter Laravel Package

spatie/commonmark-shiki-highlighter

League/CommonMark code block renderer that highlights fenced code using Shiki PHP. Includes extra Antlers and Blade grammars in addition to Shiki’s 100+ languages. Ideal for Laravel setups (see spatie/laravel-markdown). Requires JS shiki v1.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/commonmark-shiki-highlighter
    

    Requires league/commonmark (≥v2.0) and spatie/shiki-php (≥v1.0).

  2. Basic Usage:

    use League\CommonMark\CommonMarkConverter;
    use Spatie\CommonmarkShikiHighlighter\ShikiHighlighter;
    
    $converter = new CommonMarkConverter();
    $converter->getEnvironment()->addBlockRenderer(
        'code',
        new ShikiHighlighter()
    );
    
    $markdown = <<<MARKDOWN
    ```php
    echo "Hello, world!";
    

    MARKDOWN;

    echo $converter->convert($markdown);

    
    
  3. First Use Case:

    • Convert Markdown with syntax-highlighted code blocks in a Laravel Blade template or API response.
    • Example: Render documentation or user-generated content with colored code snippets.

Implementation Patterns

Core Workflow

  1. Integration with CommonMark:

    • Register ShikiHighlighter as a block renderer for code blocks in your CommonMarkConverter instance.
    • Example in a Laravel service provider:
      public function boot()
      {
          $converter = app(CommonMarkConverter::class);
          $converter->getEnvironment()->addBlockRenderer('code', new ShikiHighlighter());
      }
      
  2. Dynamic Configuration:

    • Customize theme/language via environment variables or config:
      $highlighter = new ShikiHighlighter([
          'theme' => 'github-dark',
          'languages' => ['php', 'javascript'],
      ]);
      
  3. Caching Highlighted Code:

    • Cache results for performance (e.g., in a Laravel cache driver):
      $highlighter = new ShikiHighlighter(['cache' => true]);
      
  4. Laravel-Specific Integration:

    • Use with spatie/laravel-markdown for seamless Blade/Markdown support:
      use Spatie\Markdown\MarkdownRenderer;
      
      $renderer = new MarkdownRenderer();
      $renderer->withCommonMarkConverter($converter); // Pre-configured with ShikiHighlighter
      

Advanced Patterns

  • Fallback Languages:

    • Handle unsupported languages by falling back to plain text:
      $highlighter = new ShikiHighlighter(['fallback' => true]);
      
  • Custom Themes:

    • Load themes dynamically from a directory:
      $highlighter = new ShikiHighlighter(['themePath' => storage_path('themes')]);
      
  • Async Processing:

    • Offload highlighting to a queue (e.g., Laravel Queues) for long-running documents.

Gotchas and Tips

Pitfalls

  1. Shiki Dependencies:

    • Ensure shiki-php is installed (requires Node.js for theme compilation). Run:
      composer require spatie/shiki-php
      vendor/bin/shiki install
      
  2. Language Detection:

    • Shiki may misidentify languages (e.g., php vs. html). Explicitly specify languages in code blocks:
      ```php
      // Explicit language
      
  3. Performance:

    • Highlighting large code blocks can be slow. Cache results aggressively or use async processing.
  4. Theme Compatibility:

    • Not all themes support all languages. Test with your target languages/themes.

Debugging

  • Logs:

    • Enable Shiki debug mode for verbose output:
      putenv('SHIKI_DEBUG=1');
      
  • Fallbacks:

    • Check if fallback is enabled when code blocks render as plain text.

Extension Points

  1. Custom Renderers:

    • Extend ShikiHighlighter to modify output (e.g., wrap in <pre> tags):
      class CustomHighlighter extends ShikiHighlighter {
          public function renderBlock(CodeBlock $block): string {
              return '<pre>' . parent::renderBlock($block) . '</pre>';
          }
      }
      
  2. Language Overrides:

    • Override language detection logic in ShikiHighlighter:
      protected function getLanguage(string $language): ?string {
          return $language === 'custom' ? 'php' : null;
      }
      
  3. Theme Management:

    • Dynamically load themes from a database or API:
      $highlighter = new ShikiHighlighter(['themeResolver' => fn() => $this->getThemeFromDb()]);
      

Tips

  • Laravel Blade: Use @markdown directive with spatie/laravel-markdown for seamless syntax highlighting in Blade templates.

  • Testing: Mock ShikiHighlighter in tests to avoid Node.js dependencies:

    $highlighter = Mockery::mock(ShikiHighlighter::class)->shouldReceive('renderBlock')->andReturn('<code>mock</code>');
    
  • CI/CD: Pre-install Shiki themes in CI to avoid runtime setup:

    composer require spatie/shiki-php
    vendor/bin/shiki install --themes github-dark
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport