Syntax highlighting development guidelines (repository blob viewer)

This guide outlines best practices and implementation details for syntax highlighting in the repository source code viewer. GitLab uses two syntax highlighting libraries:

The source code viewer uses this dual approach to ensure broad language support and optimal performance when viewing files in the repository.

Components Overview

The syntax highlighting implementation consists of several key components:

  • blob_content_viewer.vue: Main component for displaying file content
  • source_viewer.vue: Handles the rendering of source code
  • highlight_mixin.js: Manages the highlighting process and WebWorker communication
  • highlight_utils.js: Provides utilities for content chunking and processing

Performance Principles

Display content as quickly as possible

We optimize the display of content through a staged rendering approach:

  1. Immediately render the first 70 lines in plaintext (without highlighting)
  2. Request the WebWorker to highlight the first 70 lines
  3. Request the WebWorker to highlight the entire file

Maintain optimal browser performance

To maintain optimal browser performance:

  • Use a WebWorker for the highlighting task so that it doesn’t block the main thread
  • Break highlighted content into chunks and render them as the user scrolls using the IntersectionObserver API

Adding Syntax Highlighting Support

There are two ways to add syntax highlighting support for new languages:

  1. Using existing third-party language definitions
  2. Creating custom language definitions in our codebase

The method you choose depends on whether the language already has a Highlight.js compatible definition available.

For Languages with Third-Party Definitions

We can add third-party dependencies to our package.json and import the dependency in highlight_js_language_loader.

Example:

  • Add the dependency to package.json:
// package.json

//...
  "dependencies": {
    "@gleam-lang/highlight.js-gleam": "^1.5.0",
//...
  • Import the language in highlight_js_language_loader.js:
// highlight_js_language_loader.js

//...
  gleam: () => import(/* webpackChunkName: 'hl-gleam' */ '@gleam-lang/highlight.js-gleam'),
//...

If the language is still displayed as plaintext, you might need to add language detection based on the file extension in highlight_mixin.js:

if (name.endsWith('.gleam')) {
  language = 'gleam';
}

For Languages Without Existing Definitions

New language definitions can be added to our codebase under ~/vue_shared/components/source_viewer/languages/.

To add support for a new language:

  1. Create a new language definition file following the Highlight.js syntax.
  2. Register the language in highlight_js_language_loader.js.
  3. Add file extension mapping in highlight_mixin.js if needed.

Here are two examples of custom language implementations:

  1. Svelte
  2. CODEOWNERS