RouteConfig
The RouteConfig interface defines how Scully processes routes with dynamic parameters. Each route in your Angular application that contains dynamic segments needs a configuration to tell Scully how to generate all possible route variants.
Interface Definition
interface RouteConfig {
[route: string]: RoutesTypes;
}
type RoutesTypes =
| RouteTypeJson
| RouteTypeContentFolder
| RouterTypeDefault
| RouteTypeUnknown;
Route Types
Scully supports several route types, each designed for different use cases.
RouteTypes Enum
enum RouteTypes {
json = 'json',
contentFolder = 'contentFolder',
default = 'default'
}
Default Route Type
For routes without dynamic parameters or with custom handling.
Interface
interface RouterTypeDefault {
type: RouteTypes.default;
postRenderers?: (string | symbol)[];
}
Example
{
routes: {
'/about': {
type: 'default'
},
'/contact': {
type: 'default',
postRenderers: ['customRenderer']
}
}
}
JSON Route Type
For routes that get their dynamic data from an API endpoint.
Interface
type RouteTypeJson = {
type: RouteTypes.json;
postRenderers?: (string | symbol)[];
} & {
[paramName: string]: {
url: string;
property: string;
headers?: HeadersObject;
resultsHandler?: (raw: any) => any[];
agent?: any;
};
};
interface HeadersObject {
expectedContentType?: string;
[headerName: string]: string;
}
Properties
- url: API endpoint URL to fetch data from. Can use template variables like
${userId}
- property: Property name in the response that contains the parameter value
- headers: Optional HTTP headers for the request
- resultsHandler: Optional function to transform the API response
- agent: Optional custom HTTP agent
Example: Single Parameter
{
routes: {
'/user/:userId': {
type: 'json',
userId: {
url: 'https://api.example.com/users',
property: 'id'
}
}
}
}
Example: Multiple Parameters
{
routes: {
'/user/:userId/post/:postId': {
type: 'json',
userId: {
url: 'https://api.example.com/users',
property: 'id',
resultsHandler: (raw) => raw.filter(user => user.active)
},
postId: {
url: 'https://api.example.com/posts?userId=${userId}',
property: 'id'
}
}
}
}
{
routes: {
'/product/:id': {
type: 'json',
id: {
url: 'https://api.example.com/products',
property: 'id',
headers: {
'Authorization': 'Bearer token123',
'expectedContentType': 'application/json'
}
}
}
}
}
Content Folder Route Type
For routes that generate pages from markdown or other content files.
Interface
type RouteTypeContentFolder = {
postRenderers?: (string | symbol)[];
type: RouteTypes.contentFolder;
} & {
[paramName: string]: {
folder: string;
};
};
Properties
- folder: Path to the folder containing content files
Example: Blog Posts
{
routes: {
'/blog/:slug': {
type: 'contentFolder',
slug: {
folder: './blog'
}
}
}
}
Example: Multiple Content Folders
{
routes: {
'/docs/:category/:page': {
type: 'contentFolder',
page: {
folder: './docs'
}
}
}
}
Example: With Post Renderers
{
routes: {
'/blog/:slug': {
type: 'contentFolder',
postRenderers: ['toc', 'highlightCode'],
slug: {
folder: './blog'
}
}
}
}
Unknown Route Type
For custom route plugins.
Interface
type RouteTypeUnknown = {
postRenderers?: (string | symbol)[];
type: string;
} & {
[paramName: string]: any;
};
Example
{
routes: {
'/custom/:id': {
type: 'myCustomPlugin',
postRenderers: ['seoOptimizer'],
customOption: 'value'
}
}
}
Post Renderers
All route types support post renderers, which are plugins that process the HTML after it has been rendered.
{
routes: {
'/blog/:slug': {
type: 'contentFolder',
postRenderers: [
'seoHrefOptimise',
'tocPlugin',
'addMetaTags'
],
slug: {
folder: './blog'
}
}
}
}
Complete Example
import { ScullyConfig, RouteTypes } from '@scullyio/scully';
export const config: ScullyConfig = {
projectName: 'my-site',
routes: {
// Static route
'/home': {
type: RouteTypes.default
},
// Blog from content folder
'/blog/:slug': {
type: RouteTypes.contentFolder,
postRenderers: ['toc', 'highlightCode'],
slug: {
folder: './content/blog'
}
},
// User profiles from API
'/user/:id': {
type: RouteTypes.json,
id: {
url: 'https://api.example.com/users',
property: 'id',
resultsHandler: (users) => users.filter(u => u.published),
headers: {
'Authorization': 'Bearer token123'
}
}
},
// Nested dynamic routes
'/category/:category/product/:productId': {
type: RouteTypes.json,
category: {
url: 'https://api.example.com/categories',
property: 'slug'
},
productId: {
url: 'https://api.example.com/products?category=${category}',
property: 'id'
}
}
}
};
Important Notes
Routes with dynamic parameters that have no configuration will be logged and skipped during processing. This means no static files will be generated for unconfigured dynamic routes.
When using multiple parameters in a route, parameters can reference each other using template syntax: ${paramName}
Unhandled vs Handled Routes
Scully categorizes routes into two types:
- Unhandled Routes: Routes without dynamic parameters or routes that don’t need special processing
- Handled Routes: Routes with dynamic parameters that require a route configuration
All handled routes must have a corresponding configuration in the routes object, otherwise they will not be rendered.