# Smooth CDN Full Documentation

This file is a markdown dump of all routes currently implemented under `/docs` in the Smooth CDN web app.

## Route Index

- `/docs`
- `/docs/getting-started`
- `/docs/cdn`
- `/docs/cli`
- `/docs/api`
- `/docs/api-accelerator`
- `/docs/loader`
- `/docs/[slug]`

---

## /docs

### Smooth CDN documentation

Official Smooth CDN documentation. Explore guides, CLI usage, API reference, and integration patterns for Smooth CDN.

Available sections:

- Getting started
  Understand the core concepts of Smooth CDN and deploy your first production-ready assets in minutes.
- CDN reference
  Learn how asset URLs, formats, caching, access control, and error handling work across the Smooth CDN edge network.
- CLI reference
  Install and use the Smooth CDN CLI to authenticate, configure projects, upload assets, and automate deployments in CI/CD pipelines.
- API reference
  Manage projects, versions, assets, and access tokens programmatically using the Smooth CDN REST API.
- API Accelerator
  Understand the API Accelerator model and learn how the WordPress integration scans, syncs, protects, and filters JSON outputs.

---

## /docs/getting-started

### What is Smooth CDN?

Smooth CDN is a developer-friendly asset delivery platform designed to make managing and delivering production assets simple, predictable, and fast.

Instead of manually uploading files or exposing build directories, Smooth CDN introduces an explicit asset pipeline where assets are built locally, uploaded via CLI, and delivered through stable CDN URLs.

Smooth CDN is optimized for production assets such as scripts, styles, fonts, images, media files, and static resources used by applications and websites.

#### Key principles

- Easy by default: push assets with a single CLI command.
- Optimized delivery: CDN caching and edge distribution built-in.
- Developer-first workflow: CLI-driven, CI/CD-friendly, and automation-ready.
- Optional asset versioning: for better managing assets for apps or widgets.
- Optional access control: restrict premium assets using tokens when needed.

Smooth CDN separates asset build from asset delivery, allowing teams to treat assets as part of their deployment pipeline instead of static public files.

### Terminology

This section defines the core concepts used throughout the Smooth CDN documentation.

#### Core concepts

- Developer panel: dashboard to manage projects, assets, versions, access tokens, and logs.
- Customer panel: dashboard to manage granted accesses as end user.
- Project: a logical unit representing a single application, plugin, widget, or product using Smooth CDN.
- Asset: a single file uploaded to Smooth CDN and delivered via the edge network.
- CLI: the primary tool used to initialize projects, upload assets, and manage deployments.
- Version (optional): a project-level version used for controlled deployments and rollback.
- Access token (optional): a token that grants access to protected assets.
- CDN: the global edge network responsible for caching and delivering assets.
- CI/CD: automated pipelines used to build and deploy assets programmatically.

### Quick Start

This guide walks you through the basic Smooth CDN workflow: initializing a project, uploading assets, and using them in your application.

#### 1. Application structure

In this example, we use a simple build output structure.

```text
quick-start/
├─ dist/
│  ├─ app.js
│  ├─ app.css
│  └─ logo.png
```

Smooth CDN works with any framework or bundler. The only requirement is the final build output directory containing the files you want to deliver.

#### 2. Login

Authenticate the CLI with your Smooth CDN account:

```bash
scdn login
```

#### 3. Initialize a project

Initialize Smooth CDN project in your application root:

```bash
scdn init
```

This command initiates a wizard to create a `.scdn.json` configuration file and connects your local project with Smooth CDN.

#### 4. Upload assets

Upload your build output to Smooth CDN:

```bash
scdn push
```

All files from your configured source directories are uploaded and instantly available via CDN.

#### 5. Use assets

Reference assets using stable CDN URLs:

```html
<link rel="stylesheet" href="https://cdn.smoothcdn.com/username/quick-start/app.css" />
<script defer src="https://cdn.smoothcdn.com/username/quick-start/app.js"></script>

<img alt="Logo" src="https://cdn.smoothcdn.com/username/quick-start/logo.png" />
```

`username` is your user slug, available in the developer panel.

For projects with type `versioned`, URLs include version, for example:

```text
https://cdn.smoothcdn.com/username/quick-start/latest/logo.png
```

For `basic` projects, URLs do not contain a version segment.

---

## /docs/cdn

### Overview

Smooth CDN delivers assets through a predictable and optimized request pipeline. Requests are resolved deterministically without hidden runtime logic.

- Resolve the requested user and project.
- Resolve the target version.
- Resolve the requested asset path.
- Apply format negotiation when supported, for example images and audio.
- Serve the asset with optimized cache headers.

Uploads, configuration, and access rules are managed outside the CDN layer. The CDN focuses purely on fast and predictable delivery.

### Asset URL structure

Assets are delivered using stable and human-readable URLs.

#### Pattern

```text
https://cdn.smoothcdn.com/<user-slug>/<project-slug>/<version>/<asset-path>
```

- `<user-slug>`: owner identifier
- `<project-slug>`: project identifier
- `<version>`: specific version or `latest` for `versioned` projects; skip for other project types
- `<asset-path>`: full relative file path

You can also specify a custom subdomain for your project on paid plans:

```text
https://<project-subdomain>.smoothcdn.com/<version>/<asset-path>
```

You can list all available assets in a project using:

```text
https://cdn.smoothcdn.com/<user-slug>/<project-slug>/<version>/list
```

### Supported asset formats

Smooth CDN allows common web asset types. Unsupported file types are rejected at the delivery layer.

#### Allowed extensions

- Scripts: `.js`, `.mjs`
- Styles: `.css`
- Fonts: `.woff2`, `.woff`, `.ttf`, `.otf`
- Images: `.png`, `.jpg`, `.jpeg`, `.webp`, `.avif`, `.svg`
- Documents: `.pdf`, `.md`, `.doc`, `.docx`, `.xls`, `.xlsx`, `.ppt`, `.pptx`, `.odt`, `.ods`, `.odp`
- Data: `.json`, `.txt`
- Audio: `.mp3`, `.ogg`, `.wav`
- Video: `.mp4`, `.mov`, `.avi`, `.webm`, `.mkv`

#### Asset delivery and format optimization

Smooth CDN does not only store uploaded assets. The platform also prepares optimized variants and tries to serve the best available format for the current request while keeping the same stable asset URL.

- Images are optimized into `.webp` and `.avif` variants when possible.
- Audio files are optimized into `.m4a` variants when possible.
- Video files are optimized into `.m4v` variants when possible.
- Smooth CDN uses request information such as supported response formats to choose the best variant it can return from the same asset URL.

If you need the originally uploaded file instead of the optimized delivery variant, append `?original=1` to the asset URL.

```text
https://cdn.smoothcdn.com/<user-slug>/<project-slug>/<version>/<asset-path>?original=1
```

### Using assets

Assets can be referenced directly in HTML, CSS, or JavaScript using CDN URLs.

```html
<link rel="stylesheet" href="https://cdn.smoothcdn.com/user/project/app.css" />
<script defer src="https://cdn.smoothcdn.com/user/project/app.js"></script>

<img src="https://cdn.smoothcdn.com/user/project/logo.png" alt="Logo" />
```

You can also use the developer panel or the CLI command `scdn get-snippet` to generate a production-ready snippet for a selected asset.

### Access control

Smooth CDN can optionally restrict access to assets. By default, assets are public and optimized for global delivery.

#### Token-based access

Require a token for asset delivery. Recommended for premium or private assets.

Authorization header:

```http
Authorization: Bearer <token>
```

Query parameter:

```text
https://cdn.smoothcdn.com/<user>/<project>/<version>/<asset>?t=<token>
```

Token-based access is intended for server-side usage and controlled distribution.

### Error responses

The CDN returns standard HTTP status codes for delivery errors.

- `404 Not Found`: asset does not exist
- `403 Forbidden`: access denied
- `415 Unsupported Media Type`: file type is not allowed
- `429 Too Many Requests`: rate limited
- `5xx`: edge or internal failure

---

## /docs/cli

### Installation

The Smooth CDN CLI requires Node.js and an active Smooth CDN account.

#### Requirements

- Smooth CDN account: create an account at `/register`
- Node.js >= 18.17.0, recommended: Node.js 20 LTS

#### Install CLI

Install the Smooth CDN CLI globally using npm:

```bash
npm install -g @smoothcdn/cli
```

After installation, the `scdn` command will be available globally.

### Authentication

The Smooth CDN CLI authenticates the user and stores an access token locally. All subsequent commands use this token to communicate with the Smooth CDN API.

#### Login

To authenticate with your Smooth CDN account, run:

```bash
scdn login
```

The login process opens a browser window where you can securely sign in to your account.

Re-running the login command replaces the current session and access token.

#### Environment variable

You can store your API token in the `SCDN_TOKEN` environment variable to authenticate CLI commands in non-interactive environments.

```bash
SCDN_TOKEN=your_token scdn status
```

### Configuration

The Smooth CDN CLI uses a local configuration file (`.scdn.json`) to define project details, asset sources, and version if applicable.

This file is created and maintained automatically when running `scdn init` or `scdn load` and is required for all asset-related commands.

#### Configuration file

The configuration file must be located in the root directory of your project and named `.scdn.json`.

```json
{
  "project": "My New Project",
  "projectSlug": "my-new-project",
  "version": "1.0.0",
  "blockBots": false,
  "blockHeadless": false,
  "sources": [
    "./build/app/**/*.{js,css}",
    "./build/images/**"
  ],
  "excludes": [
    "./build/app/tmp/*"
  ],
  "protected": [
    "./build/app/pro/*.{js,css}"
  ],
  "imageVariants": {
    "mobile": 360,
    "tablet": 720,
    "desktop": 1600
  },
  "replacePath": {
    "/dist/": "/",
    "/build/": "/assets/"
  }
}
```

#### Project and version

The top-level project fields identify the Smooth CDN project and define the active version used for deployments.

- `project`: human-readable project name
- `projectSlug`: URL-safe project identifier
- `blockBots`: blocks known bot user agents
- `blockHeadless`: blocks headless browser environments
- `version`: active version used when pushing assets; applicable for projects with type `versioned`

There are also properties `projectId` and `userSlug` that are automatically stored during `scdn init` or `scdn load`.

#### Asset sources and excludes

Asset discovery is based on glob patterns defined per project. Only matched files are uploaded during deployment.

- `sources`: glob patterns defining which files are included
- `excludes`: glob patterns defining files that should be ignored
- `protected`: glob patterns defining files that should be flagged as protected and can be accessed only with an access token

Source, exclude, and protected patterns are evaluated using standard glob matching.

#### Assets path adjustment

If you want to rewrite uploaded asset paths, add the `replacePath` field to `.scdn.json`.

#### Image variants

If you want to create multiple image variants, add the `imageVariants` field to `.scdn.json`. The CLI will automatically generate and upload resized variants for images, linked to the original asset.

### Commands

The following commands are available in the Smooth CDN CLI. All commands operate based on the local `.scdn.json` configuration file.

#### Log in

Authenticates the user and stores an access token locally.

```bash
scdn login
```

#### Log out

Removes stored access token.

```bash
scdn logout
```

#### Initialize project

Initializes a new Smooth CDN project and creates a `.scdn.json` file.

```bash
scdn init
```

#### Load project

Loads an existing Smooth CDN project into the local configuration.

```bash
scdn load
```

#### Pull project config

Pulls the current Smooth CDN user and project status into the local `.scdn.json` file.

```bash
scdn pull-config
```

#### Push project config

Pushes project settings from `.scdn.json` to Smooth CDN.

This command does not publish or switch deployment versions. Use `scdn publish-version` for version publishing.

```bash
scdn push-config
```

#### Create version

Creates a new project version. Versioning is optional and can be skipped for simple workflows.

If no version is provided, the default version from `.scdn.json` will be used.

Optionally add `--blank` to create a blank version without any assets from the previous version.

```bash
scdn create-version <version>
```

#### Publish version

Publishes a version and makes it available via CDN URLs.

If no version is provided, the default version from `.scdn.json` will be published.

```bash
scdn publish-version <version>
```

Publishing a version via CLI also sets it as `latest` for the project.

#### Push assets

Uploads assets to Smooth CDN based on the current configuration.

The same command can publish frontend bundles, PDFs, audio files, and supported video files from one project config.

Use `--concurrency <number>` to set parallel upload workers. Default: `4`.

Use `--optimize=remote` to queue asset optimization on the Smooth CDN side. This is the default.

Use `--optimize=local` to optimize assets in the CLI before upload.

```bash
scdn push
```

#### Sync assets

Cross-checks local assets against the ones on Smooth CDN and removes remote assets that do not exist locally.

The same command can publish frontend bundles, PDFs, audio files, and supported video files from one project config.

Use `--force` to sync published versions too.

```bash
scdn sync
```

#### Get snippet for asset

Output an HTML snippet for a selected asset based on user preferences.

```bash
scdn get-snippet
```

#### Inspect asset paths

Validates asset paths and displays the list of assets before deployment.

```bash
scdn check-assets
```

#### Grant access

Grants direct access to protected assets.

```bash
scdn grant-access
```

#### Revoke access

Revokes previously granted access.

```bash
scdn revoke-access
```

#### Show account summary

Displays account status, including current user, plan, and limits.

```bash
scdn status
```

### CI/CD usage

Smooth CDN CLI can be integrated into CI/CD pipelines to automate asset uploads during your build or deployment process.

This allows you to treat assets as part of your deployment pipeline instead of manually uploading files or committing built assets to your repository.

#### Why use CI/CD with Smooth CDN?

- Automated uploads: assets are pushed on every build or release.
- Consistent environments: the same pipeline runs locally and in CI.
- No secrets in frontend: authentication happens in the pipeline.

#### Authentication

In CI environments, authenticate the CLI using the `SCDN_TOKEN` environment variable.

You can generate an API token in `/panel/account/api-keys`.

```bash
export SCDN_TOKEN="your_api_token"
```

Add the following workflow file in `.github/workflows/deploy-scdn.yml`:

```yaml
name: Upload assets to Smooth CDN

on:
  push:
    branches: [main]

jobs:
  upload-assets:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "npm"

      - name: Install Smooth CDN CLI
        run: npm install -g @smoothcdn/cli

      - name: Install dependencies
        run: npm ci

      - name: Build assets
        run: npm run build

      - name: Upload assets to Smooth CDN
        env:
          SCDN_TOKEN: ${{ secrets.SCDN_TOKEN }}
        run: |
          scdn create-version
          scdn push
          scdn publish-version
```

Store your API token as a repository secret named `SCDN_TOKEN`.

GitHub secrets can be added at:

```text
https://github.com/[login]/[repo-name]/settings/secrets/actions/new
```

---

## /docs/api

### Authorization

Smooth CDN API uses Bearer token authentication.

Each request to the API must include a valid API key in the `Authorization` header.

#### Creating an API key

You can generate a new API key in the dashboard:

```text
https://smoothcdn.com/panel/account/api-keys/new
```

API keys are tied to your account and grant access to all API resources available to the user.

#### Using the API key

Include your API key in the Authorization header using the `Bearer` scheme:

```http
Authorization: Bearer <YOUR_API_KEY>
```

#### Example request

```bash
curl https://api.smoothcdn.com/projects -H "Authorization: Bearer <YOUR_API_KEY>"
```

#### Missing or invalid API key

If the Authorization header is missing or the API key is invalid, the API will respond with status `401 Unauthorized`:

```json
{
  "error": "unauthorized"
}
```

### Projects

Projects are the top-level containers in Smooth CDN. Each project groups related versions, assets, and access rules.

Each project has a type: `basic` or `versioned`.

All project operations require a valid API key with authorization access.

#### List projects

Returns a list of all projects available to the authenticated user.

```text
GET https://api.smoothcdn.com/projects
```

#### Get project

Returns a single project by its identifier.

```text
GET https://api.smoothcdn.com/projects/<project-id>
```

#### Create project

Creates a new project.

```text
POST https://api.smoothcdn.com/projects
```

Request body:

```json
{
  "name": "My Project",
  "slug": "my-project", // optional - by default it'll be slugified name
  "type": "versioned", // project type: "basic" or "versioned" (default: "basic")
  "version": "1.0.0", // initial version of project if its type is "versioned" - 1.0.0 by default
  "customSubdomain": "my-project", // optional custom subdomain passed for project - available on paid plans only
  "blockBots": "false",
  "blockHeadless": "false"
}
```

#### Update project

Updates an existing project.

```text
PATCH https://api.smoothcdn.com/projects/<project-id>
```

Request body:

```json
{
  "name": "Updated Project Name",
  "slug": "updated-project-name",
  "latestVersion": "1.0.1", // which version to flag as "latest"
  "customSubdomain": "my-project", // optional custom subdomain passed for project - available on paid plans only
  "blockBots": "false",
  "blockHeadless": "false"
}
```

#### Delete project

Permanently deletes a project and all related resources.

```text
DELETE https://api.smoothcdn.com/projects/<project-id>
```

Deleting a project permanently removes all associated data.

### Versions

Versions allow you to manage different published states of a project. Only one version can be set as latest for a project.

Versions are scoped to a specific project.

#### List versions

Returns all versions for a given project.

```text
GET https://api.smoothcdn.com/projects/<project-id>/versions
```

#### Create version

Creates a new version for the project.

The version value must follow semantic versioning format `MAJOR.MINOR.PATCH`, for example `1.0.0`.

```text
POST https://api.smoothcdn.com/projects/<project-id>/versions
```

Request body:

```json
{
  "version": "1.0.0"
}
```

Versions are always created as `drafts`.

#### Update version

Set version as published or draft.

```text
PATCH https://api.smoothcdn.com/projects/<project-id>/versions/<version>
```

Request body:

```json
{
  "isVersionPublished": "<boolean>" // whether selected version is available to be used from CDN
}
```

To set a version as latest, use the Update project route.

#### Delete version

Deletes a version from the project.

```text
DELETE https://api.smoothcdn.com/projects/<project-id>/versions/<version>
```

Deleting a version permanently removes all associated data.

### Assets

Assets represent files served through Smooth CDN. Each asset belongs to a specific project and optional version for projects with type `versioned`.

#### List assets

Returns assets for the given project.

```text
GET https://api.smoothcdn.com/projects/<project-id>/assets
```

#### Create asset

Uploads a new asset. This endpoint is routed directly to the CDN edge layer and has a different payload structure than standard REST routes.

```text
POST https://api.smoothcdn.com/upload
```

Request body:

```json
{
  "projectId": "<project-id>", // required - project identifier sent in multipart body
  "asset": "<file>", // file content to be uploaded
  "version": "1.0.0", // which version to assign asset
  "path": "/dist/app/", // additional info about asset path
  "sub_assets[]": "<file>", // optional derived files uploaded together with the main asset
  "protected": "0", // optional: 1 marks asset as protected
  "skipVariants": "0", // optional: 1 skips project image variant generation for this asset
  "force": "0" // optional: force upload even if version is published
}
```

#### Create assets bulk

Uploads multiple assets in one request. This endpoint is routed directly to the CDN edge layer.

```text
POST https://api.smoothcdn.com/upload/bulk
```

Request body:

```json
{
  "projectId": "<project-id>", // required - project identifier sent in multipart body
  "assets": "<file>", // file content to be uploaded (repeat field for each file)
  "version": "1.0.0", // which version to assign assets
  "path": "/dist/app/", // additional info about assets path
  "protected": "0", // optional: 1 marks assets as protected
  "skipVariants": "0", // optional: 1 skips project image variant generation for these assets
  "force": "0" // optional: force upload even if version is published
}
```

#### Protect asset

Update protected flag on an asset.

```text
PATCH https://api.smoothcdn.com/projects/<project-id>/assets/<asset-id>
```

Request body:

```json
{
  "protected": "1" // 1 to mark asset as protected, 0 to mark asset as public
}
```

#### Bulk protect assets

Updates protected flag for multiple assets in one request.

```text
PATCH https://api.smoothcdn.com/projects/<project-id>/assets/bulk
```

Request body:

```json
{
  "asset_ids": ["<asset-id-1>", "<asset-id-2>"], // array of asset identifiers
  "protected": "1" // 1 to mark assets as protected, 0 to mark assets as public
}
```

#### Delete asset

Permanently deletes a single asset.

```text
POST https://api.smoothcdn.com/delete
```

Request body:

```json
{
  "projectId": "<project-id>", // project identifier
  "file": "logo.png", // asset filename to delete
  "path": "/images/", // optional asset directory, defaults to /
  "version": "v1", // required for versioned projects
  "force": "1" // optional: allow delete even if version is published
}
```

#### Bulk delete assets

Permanently deletes multiple assets from the same path in one request. For different paths, send separate requests.

```text
POST https://api.smoothcdn.com/delete/bulk
```

Request body:

```json
{
  "projectId": "<project-id>", // project identifier
  "assets": "app.js", // asset filename to delete (repeat field for each asset)
  "path": "/build/", // optional shared asset directory, defaults to /
  "version": "v1", // required for versioned projects
  "force": "1" // optional: allow delete even if version is published
}
```

Deleting an asset permanently removes all associated data.

### Accesses

Accesses are a list of tokens assigned to users with a list of granted protected assets.

#### List accesses

Returns all access tokens defined for the given project.

```text
GET https://api.smoothcdn.com/projects/<project-id>/accesses
```

#### Grant access

Grants access to assets.

```text
POST https://api.smoothcdn.com/projects/<project-id>/accesses/grant
```

Request body:

```json
{
  "assets": ["/dist/app/app.js"],
  "email": "mail@example.com",
  "expiresAt": "<datetime>" // null or empty for endless access
}
```

#### Revoke access

Revokes previously granted access.

```text
POST https://api.smoothcdn.com/projects/<project-id>/accesses/<access-id>/revoke
```

---

## /docs/api-accelerator

### Overview

Smooth API Accelerator generates JSON outputs from a source system and publishes them to Smooth CDN for faster delivery and lower origin load.

The source system remains the content and API source of truth. API Accelerator is responsible for scanning routes, deciding which ones should be synced, generating JSON files, and serving them through CDN URLs.

The current production integration is WordPress. The same model can be extended to other source systems later, but this page describes the current WordPress plugin behavior.

#### Core model

- Discover routes that can be synced.
- Keep synced routes in a dedicated group separate from the rest of detected endpoints.
- Generate one or more JSON files per synced route.
- Serve those files from `https://cdn.smoothcdn.com/<user-slug>/<project-slug>/...`.
- Optionally upload synced JSONs as protected assets.

### WordPress

The WordPress plugin `Smooth API Accelerator` turns selected WP REST API endpoints into JSON files hosted on Smooth CDN.

Download path mentioned on the page:

```text
https://wordpress.org/plugins/smooth-api-accelerator/
```

#### Installation

1. Download the plugin from `https://wordpress.org/plugins/smooth-api-accelerator/`.
2. Install and activate it in WordPress.
3. Open `Smooth API Accelerator -> Settings` in wp-admin.

#### Login and connection

The plugin supports two connection modes: an existing Smooth CDN account or guest mode.

1. Choose the connection mode in `Settings`.
2. Use `Log in to Smooth CDN` for account mode, or switch to guest mode and accept the policy.
3. After connection, the plugin stores the API key and creates or attaches a Smooth CDN project of type `api_accelerator`.

If the status payload does not return another value, guest mode falls back to a default limit of `50` JSON files.

#### Endpoint discovery and route selection

The endpoint screen keeps two tables:

- `Synced endpoints`
- `Other endpoints`

Current flow:

1. `Run scan now` discovers GET endpoints and refreshes the local endpoint registry.
2. Newly detected endpoints appear in `Other endpoints`.
3. `Sync selected` moves selected entries into the synced group and queues an immediate background sync for those routes.
4. After that selection, the routes appear in `Synced endpoints`.
5. `Sync endpoints now` runs a full sync for all currently synced endpoints.
6. `Unsync selected` removes selected entries from the synced group and removes their remote JSON files from Smooth CDN.

`Sync selected` does not wait for the normal hourly schedule. The plugin queues a fast single WP-Cron event for the selected routes, usually with a short delay. Execution still depends on WP-Cron and the next request that triggers it, but it does not wait for the regular hourly cron.

#### Automatic refresh after content changes

The plugin automatically scans and syncs related routes after content changes affecting:

- posts
- terms and taxonomies

When a post changes, the plugin can refresh:

- the endpoint for that specific post
- the collection endpoint for that post type
- related taxonomy collection endpoints
- related term item endpoints

When a term changes, the plugin can refresh:

- the taxonomy collection endpoint
- the specific term endpoint
- related post collection endpoints
- related single post endpoints

These refreshes are also scheduled through WP-Cron with short-delay single events instead of waiting for the standard automatic scan interval.

#### Settings

The current WordPress plugin exposes these settings:

- `Add blocks field`: adds a normalized `blocks` field when block parsing is possible.
- `Remove content field`: appears only when `Add blocks field` is enabled and removes `content` only if `blocks` was actually added.
- `Protected assets`: uploads synced JSON files as protected assets instead of public assets.
- `Collection sync page size`: available values `10`, `25`, `50`, `100`; default `50`.
- `Auto scan and sync`: schedules the automatic full scan and sync recurrence: hourly, daily, or weekly.

Changing any of these settings forces sync invalidation and a faster full refresh:

- `Protected assets`
- `Add blocks field`
- `Remove content field`
- `Collection sync page size`

After such a change, the plugin clears sync markers for previously synced routes and queues a faster full scan and sync through an immediate single WP-Cron event instead of waiting for the regular schedule.

#### Blocking original WordPress REST API

In `Settings` you can configure whether original WordPress REST GET endpoints should remain available:

- `No`: do not block original `wp-json` GET routes.
- `Yes`: block all eligible REST GET routes for non-logged-in users.
- `Only synced ones`: block only routes that are already synced to Smooth CDN.

#### Blocks output

When `Add blocks field` is enabled, the plugin adds a normalized `blocks` field to supported post-like payloads.

Current block shape:

- `block_name`
- `attrs`
- `innerContent`
- `inner_blocks`

The synced JSON does not use the old output shape with `blockName`, `innerBlocks`, or `innerHTML`.

```json
{
  "id": 42,
  "title": { "rendered": "Example page" },
  "blocks": [
    {
      "block_name": "core/paragraph",
      "attrs": {},
      "innerContent": [
        "<p>Hello world</p>"
      ],
      "inner_blocks": []
    }
  ]
}
```

Practical note for `core/navigation`: if the block contains `ref` or legacy `navigationMenuId`, the plugin expands `inner_blocks` from the referenced `wp_navigation` post to avoid syncing an empty `core/navigation` wrapper.

#### Protected JSONs and file limits

Enable `Protected assets` when synced JSONs should not be exposed as public files. In that mode use a token-aware consumer to read them.

Reference from the docs points to:

```text
/docs/cdn#access-control
```

File limits are counted as physical JSON files. Paginated collections count as multiple files: one metadata file plus every page file.

#### Filtering requested JSONs

Synced JSON files can be filtered at request time with the `_fields` query parameter. Array payloads can also be filtered with normal query params such as `id`, `slug`, or other top-level keys.

Return only selected fields:

```text
https://cdn.smoothcdn.com/<user-slug>/<project-slug>/wp/v2/posts/page-1.json?_fields=id,slug,title
```

Filter array items and select fields:

```text
GET https://cdn.smoothcdn.com/<user-slug>/<project-slug>/wp/v2/posts/page-1.json?slug=hello-world&_fields=id,slug,title
```

Field filtering works on top-level keys. Dot notation is normalized to the root field.

#### Pre-send hook

Use `scdn_api_accelerator_pre_send_json` to adjust payloads right before JSON encoding and upload. Returning `WP_Error` stops sync for the current output file.

The hook runs for regular endpoint JSONs and also for:

- collection metadata files
- individual collection page files

The `context` array can contain:

- `trigger`
- `http_status`
- `route_template`
- `handler_args`
- `repository_item`
- `sync_file_kind` for collection outputs
- `page_no` for collection page files
- `total_pages` for collection metadata and collection page files
- `per_page` for collection metadata and collection page files

```php
add_filter( 'scdn_api_accelerator_pre_send_json', function( $data, $route, $context ) {
    if ( '/wp/v2/posts' === $route && ( $context['sync_file_kind'] ?? '' ) === 'collection_page' && is_array( $data ) ) {
        foreach ( $data as $index => $item ) {
            if ( ! is_array( $item ) ) {
                continue;
            }

            unset( $data[ $index ]['class_list'], $data[ $index ]['meta'] );
        }
    }

    if ( '/wp/v2/posts' === $route && ( $context['sync_file_kind'] ?? '' ) === 'collection_manifest' ) {
        $data['generated_for'] = 'posts';
    }

    return $data;
}, 10, 3 );
```

#### Unsync selected

`Unsync selected` does more than removing a local flag.

- It deletes synced JSON files from Smooth CDN.
- For collections, this includes the metadata file and all paginated collection pages.
- The local repository entry is reset to a detected state.

After unsync, the route goes back to `Other endpoints` instead of staying in the synced group.

#### Purge endpoints

`Purge endpoints` is a destructive maintenance action available in `Settings`.

- It deletes synced JSON files from Smooth CDN.
- Then it clears local endpoint data stored by the plugin.
- It also clears plugin scheduling and stored plugin state.

Use this action only when you want to wipe synced endpoint data and start from a clean state.

### JavaScript SDK

The JavaScript SDK is the recommended way to consume synced API Accelerator JSONs in apps that need route-aware resolution, field filtering, query filters, pagination, or protected asset access.

#### Installation

```bash
npm install @smoothcdn/api-accelerator-sdk
```

#### Basic usage

Create a client with your Smooth CDN slugs and fetch data by route:

```javascript
import { createApiClient } from "@smoothcdn/api-accelerator-sdk";

const client = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project"
});

const posts = await client.fetch("/wp/v2/posts");
```

#### Fields, filtering, and pagination

Use `fields` to map to `_fields`, `where` to append top-level query filters, and `page` when you want a specific collection page.

```javascript
const postsPage2 = await client.fetch("/wp/v2/posts", {
  fields: ["id", "title", "slug"],
  where: {
    slug: "hello-world"
  },
  page: 2
});
```

Use `page` for paginated collection files.

#### Joins

Use `join` to concatenate JSON files into a more dynamic collection.

```javascript
const postsWithAuthors = await client.fetch("/wp/v2/posts", {
  join: {
    author: "/wp/v2/users/[author]"
  }
});
```

#### Query with token

For protected JSONs, pass a token when creating the client.

```javascript
import { createApiClient } from "@smoothcdn/api-accelerator-sdk";

const client = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project",
  token: process.env.SMOOTHCDN_TOKEN
});

const privatePosts = await client.fetch("/wp/v2/posts", {
  page: 1
});
```

#### Framework adapters

The SDK also provides framework-specific adapters for common frontend runtimes.

Next.js:

```typescript
import { createApiClient } from "@smoothcdn/api-accelerator-sdk/next";

const next = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project",
  token: process.env.SMOOTHCDN_TOKEN
});

export async function getStaticProps() {
  return next.createStaticProps("/wp/v2/pages", { revalidate: 60 });
}

export async function getFeaturedPost() {
  return next.getRouteData("/wp/v2/posts", {
    fields: ["id", "title"],
    where: { id: 123 },
    cache: "force-cache",
    next: {
      revalidate: 300,
      tags: ["posts", "featured-post"]
    }
  });
}
```

Nuxt:

```typescript
import { createApiClient } from "@smoothcdn/api-accelerator-sdk/nuxt";

const nuxt = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project",
  token: process.env.SMOOTHCDN_TOKEN
});

export default defineComponent({
  setup() {
    const requestFetch = useRequestFetch();
    return nuxt.useRouteDataWithAutoKey(useAsyncData, "/wp/v2/posts", {
      fetch: requestFetch,
      asyncData: {
        dedupe: "defer",
        lazy: true
      }
    });
  }
});
```

Astro:

```typescript
import { createApiClient } from "@smoothcdn/api-accelerator-sdk/astro";

const astro = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project"
});

const loadPosts = astro.createLoader("/wp/v2/posts", {
  fields: ["id", "title"]
});

const posts = await loadPosts({ fetch });
```

SvelteKit:

```typescript
import { createApiClient } from "@smoothcdn/api-accelerator-sdk/sveltekit";

const sveltekit = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project"
});

export const load = sveltekit.createLoad("/wp/v2/posts", {
  fields: ["id", "title"],
  depends: ["smooth:posts"],
  cacheControl: "public, max-age=60"
});
```

Remix:

```typescript
import { json } from "@remix-run/node";
import { createApiClient } from "@smoothcdn/api-accelerator-sdk/remix";

const remix = createApiClient({
  userSlug: "example-user",
  projectSlug: "my-project",
  token: process.env.SMOOTHCDN_TOKEN
});

export const loader = remix.createJsonLoader(json, "/wp/v2/posts", {
  fields: ["id", "title"],
  where: { id: 123 },
  useRequestSignal: true
});
```

---

## /docs/loader

This route currently calls `notFound()` immediately and does not render public documentation content.

Practical meaning for this dump:

- route exists in `src/app/docs/loader/page.tsx`
- it resolves to a 404 state
- it does not contribute any end-user docs body

---

## /docs/[slug]

This dynamic route is a client-side redirect helper.

Behavior:

- it reads the slug route
- it replaces the current route with `/docs/getting-started`
- it does not render standalone documentation content

Practical meaning for this dump:

- no extra docs body is defined here
- unknown or legacy slug-based docs paths are redirected to `/docs/getting-started`
