Skip to main content
Version: Laravel 3.x (current)



The theming system is still experimental. It won't change significantly, but we're looking for ways to make it simpler and more consistent. We're open to your suggestions!

Scribe v3 comes with support for themes, allowing you to customize how your docs look. Scribe currently only comes with one theme, default, but you can create a new theme. Let's see how.

Anatomy of a theme

A theme consists of:

  • an index.blade.php file that takes the API details and renders to HTML. For custom themes, this file has to be in resources/views/vendor/scribe/themes/{themeName}/.
  • any accompanying CSS and JS files. You can place these anywhere in your codebase, as long as you reference them correctly from the theme file (keeping in mind the actual path your docs/ page will be visited from).

When you run php artisan scribe:generate, Scribe will use the theme template to generate the HTML. For inbuilt themes, it will also copy any CSS and JS files to your app's public directory. For custom themes, you'll have to manage that part yourself.

Creating a new theme

To create a new theme (let's call this theme nasty), place the index.blade.php in resources/views/vendor/scribe/themes/nasty/. Next, we change the value of theme in our config:

    'theme' => 'nasty',

Now we write the theme. Writing a theme file can be a lot of work, so we recommend using the default theme as a starting point. Here's a very simple theme file:

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{!! $metadata['title'] !!}</title>

<link rel="stylesheet" href="../docs/css/nasty.css">

<link rel="stylesheet"
<script src="//"></script>

<div class="content">
{!! $intro !!}

{!! $auth !!}


Our theme file is a regular Blade/HTML page. We can do whatever we wish in here, and use Blade constructs as normal. Let's see what's going on here:

First, we're using the $metadata object that's passed to our theme. This object has the following structure:

'title' => 'The title of the API',
'example_languages' => ['bash', 'javascript'], // Your `example_languages` config
'logo' => 'logo_url', // Your `logo` config
'last_updated' => '2021-09-12', // Current date string
'auth' => [
'location' => 'header', // or 'query', or 'body'
'prefix' => 'Bearer ', // or 'Basic ' or ''
// Plus the rest of your `auth` config
'try_it_out' => [ // Your `try_it_out` config
'enabled' => true,
'base_url' => '',
// List of HTML links to be placed at the bottom of the sidebar (including Postman collection and OpenAPI links)
'links' => ['<a href="">Documentation powered by Scribe ✍</a>'],

Next, we reference a stylesheet, nasty.css, which we've placed in our public/docs folder, as well as the highlight.js CSS and JS for syntax highlighting.

Then, in the <body>, we output the $index and $auth information. Those variables hold basic HTML containing the text for the introduction and authentication sections.

In addition to these variables, the theme file has access to the following variables:

  • $baseUrl: the base URL to be displayed in the docs
  • $tryItOut: the try_it_out section from your config file
  • $append: the HTMl from any .scribe/ file added by the user
  • $groupedEndpoints: the endpoints in the API, organized by groups. Each item in this array is an array with the following shape:
    'name' => 'The group name',
    'description' => 'The description',
    'endpoints' => [
    // Array of Knuckles\Camel\Output\OutputEndpointData

Finally, you'll notice that at the end, we include "scribe::themes.default.groups". This means our theme just changed the outer page structure, and falls back to the default theme to render the actual endpoints and groups. This is a great way to modify an existing theme. If we wanted to create a totally new theme, then we would replace the include directive with our own custom Blade that would loop over the groups and render endpoints.

Now when you run php artisan scribe:generate, Laravel will load your custom theme instead of the default.

If you need a starting point or more guidance to create your own theme, you should look at the included theme files.


The Knuckles\Scribe\Tools\WritingUtils class contains some helpful utilities that might save you some work; for instance, printing query parameters as a key-value hash.

Customising all templates

If you really want to customise all the templates Scribe uses for generating, you can publish the vendor views:


php artisan vendor:publish --tag=scribe-views

When you do this, your resources/views/vendor/scribe/ folder should have this structure:

|-- badges/
|-- base.blade.php
|-- auth.blade.php
|-- http-method.blade.php
|-- body-parameters.blade.php
|-- field-details.blade.php
|-- intro.blade.php
|-- auth.blade.php
|-- example-requests/
|-- default/
|-- index.blade.php
|-- groups.blade.php
|-- endpoint.blade.php

The components folder contains some Blade components used in the themes. For instance, you can display a badge using the base.blade.php component:

any .blade.php file
@component('scribe::components.badges.base', [
'colour' => "darkred",
'text' => 'requires authentication'

The partials folder contains the example request templates. If you want these alone, you can run php artisan vendor:publish --tag=scribe-examples instead.

The markdown folder contains the templates for the intermediate Markdown files that will be generated in your .scribe folder (, and If you want these alone, you can run php artisan vendor:publish --tag=scribe-markdown instead.

  • In the intro.blade.php, you have access to: -$description (the API description),
    • $introText (the text for the introductory section), and
    • $baseUrl (the URL to be displayed in the docs).
  • In the auth.blade.php file, you have
    • $isAuthed (true if the API has auth enabled),
    • $authDescription (generated by Scribe from your auth config), and
    • $extraAuthInfo(the auth.extra_info section in your config)

The themes folder contains the templates for the included themes. If you want these alone, you can run php artisan vendor:publish --tag=scribe-themes instead.