Skip to main content
The JSON plugin fetches data from external JSON APIs and uses that data to generate routes dynamically. This is ideal for creating pages based on data from RESTful APIs, databases, or any JSON endpoint.

Overview

The JSON plugin allows you to:
  • Fetch data from external JSON APIs
  • Generate routes based on API responses
  • Handle nested route parameters
  • Support custom headers and HTTP agents
  • Transform API responses with custom handlers

Configuration

To use the JSON plugin, configure it in your scully.config.ts file:
import { ScullyConfig } from '@scullyio/scully';

export const config: ScullyConfig = {
  routes: {
    '/user/:userId': {
      type: 'json',
      userId: {
        url: 'https://api.example.com/users',
        property: 'id'
      }
    }
  }
};

Configuration Options

Each route parameter requires a configuration object with the following properties:
url
string
required
The URL endpoint to fetch JSON data from. Supports ES6 template strings for dynamic URLs based on previous parameters.
property
string
The property path to extract from the JSON response. If not specified, the entire response is used.
headers
object
Custom HTTP headers to include in the request.
agent
object
Custom HTTP agent configuration for the request.
resultsHandler
function
A custom function to transform the API response before processing.
resultsHandler: (data) => {
  // Transform data
  return data.results;
}

Usage Examples

Basic Example

Generate routes from a simple user API:
export const config: ScullyConfig = {
  routes: {
    '/blog/:postId': {
      type: 'json',
      postId: {
        url: 'https://api.example.com/posts',
        property: 'id'
      }
    }
  }
};
This will fetch posts from the API and create routes like:
  • /blog/1
  • /blog/2
  • /blog/3

Nested Parameters

Create routes with multiple dynamic segments:
export const config: ScullyConfig = {
  routes: {
    '/user/:userId/post/:postId': {
      type: 'json',
      userId: {
        url: 'https://api.example.com/users',
        property: 'id'
      },
      postId: {
        url: 'https://api.example.com/users/${userId}/posts',
        property: 'id'
      }
    }
  }
};
The postId URL uses template string syntax to reference the userId from the previous parameter.

Custom Headers

Add authentication or custom headers:
export const config: ScullyConfig = {
  routes: {
    '/product/:productId': {
      type: 'json',
      productId: {
        url: 'https://api.example.com/products',
        property: 'id',
        headers: {
          'Authorization': 'Bearer YOUR_TOKEN',
          'Content-Type': 'application/json'
        }
      }
    }
  }
};

Results Handler

Transform API responses before route generation:
export const config: ScullyConfig = {
  routes: {
    '/article/:slug': {
      type: 'json',
      slug: {
        url: 'https://api.example.com/articles',
        property: 'slug',
        resultsHandler: (response) => {
          // Extract data from paginated response
          return response.data.items;
        }
      }
    }
  }
};

How It Works

  1. Route Parsing: Scully identifies route parameters (segments starting with :)
  2. Data Fetching: For each parameter, the plugin fetches data from the configured URL
  3. Data Extraction: If a property is specified, it extracts that property from each item
  4. Route Generation: Routes are generated for all possible combinations of parameter values
  5. Template Rendering: Subsequent parameters can use previous parameter values in their URLs

When to Use

Use the JSON plugin when you need to:
  • Generate pages from external API data
  • Create dynamic routes based on database content
  • Build pages for products, users, posts, or any entity from a REST API
  • Integrate with third-party services that provide JSON endpoints
The JSON plugin runs during the build process. Make sure your API endpoints are accessible during the Scully build.

Error Handling

If the plugin fails to fetch data or encounters an error:
  • An error message is logged with the route information
  • The route is returned without generated variations
  • The build continues with other routes
Ensure all required parameters are configured. Missing parameter configurations will cause the route to be skipped with an error message.

Content Folder Plugin

Generate routes from local content files

Router Plugin

Default router plugin for static routes

Build docs developers (and LLMs) love