Skip to content

romainpi/astro-loader-storyblok

Repository files navigation

astro-loader-storyblok

types CI Build Version Dependencies Maturity License

A robust Astro content loader for Storyblok.

astro-loader-storyblok is a community-driven continuation of Storyblok’s archived Astro Content Layer integration, enabling smooth integration between Storyblok CMS and Astro content collections. Read more about the origins of this project here.

Features

  • Full Astro Content Layer API support - Compatible with Astro 5.0+
  • 🗂️ Stories and datasources - Comprehensive support for both Storyblok stories and datasources
  • 🚀 Optimized performance - Incremental updates and efficient caching
  • Automatic schema generation - Auto-generates Astro collection schemas for datasources
  • 🎯 Content type filtering - Load specific content types or all stories
  • 📊 Flexible sorting - Multiple sorting options for your content
  • 📦 TypeScript ready - Full TypeScript support with type definitions

Performance Features

  • Cache Version Optimization: Uses Storyblok's cache version (cv) to detect when content has changed, avoiding unnecessary API calls
  • Incremental Updates: Only fetches content that has changed since the last published date
  • Efficient Caching: Stores metadata about cache version and last published date to minimize API calls
  • Selective Loading: Load only specific content types to reduce payload size

Installation

npm install astro-loader-storyblok
# or
pnpm add astro-loader-storyblok
# or
yarn add astro-loader-storyblok

Quick Start

💡 Want to jump right in? Check out the playground example to see a working implementation before setting up your own project.

1. Configure your Astro content collection

Create or update your src/content/config.ts:

import { defineCollection } from "astro:content";
import { StoryblokLoaderStories } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: "your-storyblok-access-token",
  }),
});

export const collections = { stories };

2. Use in your Astro pages

---
// src/pages/blog/[...slug].astro
import { getCollection, getEntry } from "astro:content";

export async function getStaticPaths() {
  const stories = await getCollection("stories");
  return stories.map((story) => ({
    params: { slug: story.data.full_slug },
    props: { story },
  }));
}

const { story } = Astro.props;
---

<html>
  <head>
    <title>{story.data.name}</title>
  </head>
  <body>
    <h1>{story.data.content.title}</h1>
    <div set:html={story.data.content.body} />
  </body>
</html>

Advanced Usage (New in v0.2.0)

For more advanced use cases, you can use the new StoryblokLoader class which provides better performance through shared cache version management across multiple collections:

import { defineCollection } from "astro:content";
import { StoryblokLoader } from "astro-loader-storyblok";

// Create a shared loader instance
const storyblokLoader = new StoryblokLoader({
  accessToken: "your-storyblok-access-token",
});

// Define multiple collections that share the same cache version
const stories = defineCollection({
  loader: storyblokLoader.getStoriesLoader({
    contentTypes: ["article", "page"],
    storyblokParams: {
      version: "published",
      sort_by: "created_at:desc",
    },
  }),
});

const categories = defineCollection({
  loader: storyblokLoader.getDatasourceLoader({
    datasource: "categories",
  }),
});

export const collections = { stories, categories };

Benefits of the StoryblokLoader Class

  • Shared Cache Management: Multiple collections share the same cache version, reducing redundant API calls and preventing conflicts if changes are made to a Storyblok space while collections are being loaded by Astro.
  • Better Performance: Cache version is fetched once and reused across all loaders
  • Cleaner Architecture: Centralized configuration and better separation of concerns

Stories Loader

The StoryblokLoaderStories allows you to load stories from Storyblok into your Astro content collections.

Basic Configuration

import { defineCollection } from "astro:content";
import { StoryblokLoaderStories } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: "your-access-token",
  }),
});

Advanced Configuration

import { StoryblokLoaderStories, SortByEnum, type StorySortFunction } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: "your-access-token",

    // Filter by specific content types
    contentTypes: ["article", "page", "product"],

    // Use UUIDs instead of slugs as IDs
    useUuids: true,

    // Sort stories using the new sortBy property (takes precedence over storyblokParams.sort_by)
    sortBy: SortByEnum.CREATED_AT_DESC,

    // Or use a custom sort function (takes precedence over sortBy)
    customSort: (a, b) => {
      // Example: Sort by a custom priority field
      const priorityA = a.content?.priority || 0;
      const priorityB = b.content?.priority || 0;
      return priorityB - priorityA; // Higher priority first
    },

    // Additional Storyblok API options
    apiOptions: {
      region: "us", // 'eu' (default), 'us', 'ap', 'ca', 'cn'
      https: true,
      cache: {
        type: "memory",
      },
    },

    // Storyblok API parameters
    storyblokParams: {
      // Content version
      version: "draft", // "draft" or "published" (default)

      // Exclude specific slugs
      excluding_slugs: "home,about,contact",

      // Sort stories (lower precedence than sortBy/customSort)
      sort_by: SortByEnum.CREATED_AT_DESC,
    },
  }),
});

Datasource Loader

The StoryblokLoaderDatasource allows you to load data from Storyblok datasources into your Astro content collections. Datasources in Storyblok are useful for managing structured data like categories, tags, or any other reference data.

Basic Usage

import { defineCollection } from "astro:content";
import { StoryblokLoaderDatasource } from "astro-loader-storyblok";

const categories = defineCollection({
  loader: StoryblokLoaderDatasource({
    accessToken: "your-storyblok-access-token",
    datasource: "categories", // Your datasource slug in Storyblok
  }),
});

export const collections = { categories };

Datasource Configuration

const categories = defineCollection({
  loader: StoryblokLoaderDatasource({
    accessToken: "your-access-token",
    datasource: "categories",     // Datasource slug in Storyblok

    // Optionals:
    switchNamesAndValues: true,   // Use value as ID and name as body
    dimension: "es",              // Specify query dimension
    apiOptions: { region: "us" }, // Additional Storyblok API options
  }),
});

Using Datasource Data

---
// src/pages/categories.astro
import { getCollection } from "astro:content";

const categories = await getCollection("categories");
---

<html>
  <body>
    <h1>Categories</h1>
    <ul>
      {categories.map((category) => (
        <li key={category.id}>
          <strong>{category.id}</strong>: {category.body}
        </li>
      ))}
    </ul>
  </body>
</html>

Data Structure

By default, the loader uses the datasource entry's name as the collection entry ID and the value as the body content. You can switch this behavior using the switchNamesAndValues option.

API Reference

StoryblokLoaderStories Configuration

The StoryblokLoaderStories function accepts a single configuration object that combines both loader-specific configuration and Storyblok API parameters:

export interface StoryblokLoaderStoriesConfig {
  accessToken: string;
  apiOptions?: ISbConfig;
  contentTypes?: string[];
  useUuids?: boolean;
  sortBy?: string;
  customSort?: StorySortFunction;
  storyblokParams?: ISbStoriesParams;
}
Option Type Default Description
accessToken string Required Your Storyblok access token
apiOptions ISbConfig {} Additional Storyblok API configuration
contentTypes string[] undefined Array of content types to load
useUuids boolean false Use story UUIDs instead of slugs as IDs
sortBy string undefined Sort order for stories (overrides storyblokParams.sort_by)
customSort StorySortFunction undefined Custom sort function (overrides sortBy)
storyblokParams ISbStoriesParams {} Storyblok API query parameters (see below)

Storyblok API Parameters (storyblokParams):

The storyblokParams property accepts all standard Storyblok Stories API parameters:

Option Type Default Description
version "draft" | "published" "published" Content version to load
excluding_slugs string undefined Comma-separated list of slugs to exclude
sort_by string undefined Sort order for stories
starts_with string undefined Filter by slug prefix
by_slugs string undefined Filter by specific slugs

For a complete list of available parameters, see the Storyblok Stories API documentation.

Sorting Priority:

The loader supports multiple ways to sort stories, with the following precedence order (highest to lowest):

  1. customSort - Custom sort function for complex sorting logic
  2. sortBy - Simple string-based sorting parameter
  3. storyblokParams.sort_by - Legacy Storyblok API parameter

When multiple sorting options are provided, only the highest priority option will be used.

StoryblokLoaderDatasource Configuration

export interface StoryblokLoaderDatasourceConfig {
  accessToken: string;
  datasource: string;
  dimension?: string;
  switchNamesAndValues?: boolean;
  apiOptions?: ISbConfig;
}
Option Type Default Description
accessToken string Required Your Storyblok access token
datasource string Required The slug of your Storyblok datasource
dimension string undefined Filter entries by dimension (if configured in Storyblok)
switchNamesAndValues boolean false Use value as ID and name as body instead of the default
apiOptions ISbConfig {} Additional Storyblok API configuration

StorySortFunction Type

For advanced sorting scenarios, you can provide a custom sort function:

export type StorySortFunction = (a: ISbStoryData, b: ISbStoryData) => number;

The function should return:

  • A negative number if the first story should come before the second
  • A positive number if it should come after
  • Zero if they are equal

Sorting Options

The SortByEnum enum provides the following default sorting options for use in the sort_by parameter:

import { SortByEnum } from "astro-loader-storyblok";

// Available sorting options
SortByEnum.CREATED_AT_ASC             // "created_at:asc"
SortByEnum.CREATED_AT_DESC            // "created_at:desc"
SortByEnum.FIRST_PUBLISHED_AT_ASC     // "first_published_at:asc"
SortByEnum.FIRST_PUBLISHED_AT_DESC    // "first_published_at:desc"
SortByEnum.NAME_ASC                   // "name:asc"
SortByEnum.NAME_DESC                  // "name:desc"
SortByEnum.SLUG_ASC                   // "slug:asc"
SortByEnum.SLUG_DESC                  // "slug:desc"
SortByEnum.UPDATED_AT_ASC             // "updated_at:asc"
SortByEnum.UPDATED_AT_DESC            // "updated_at:desc"

// Usage example
const stories = defineCollection({
  loader: StoryblokLoaderStories(
    { accessToken: "your-token" },
    {
      version: "published",
      sort_by: SortByEnum.CREATED_AT_DESC,
    }
  ),
});

You may also specify a custom string for custom sorting options. For more details, refer to the Storyblok Stories API documentation.

Examples

📁 Live Example: See the playground/minimal-astro-project for a complete working example that you can run locally.

Loading Blog Posts

// src/content/config.ts
const blog = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    contentTypes: ["blog-post"],
    storyblokParams: {
      version: "published",
      sort_by: SortByEnum.CREATED_AT_DESC,
    },
  }),
});

Multi-region Setup

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    apiOptions: {
      region: "us", // for US region
    },
    storyblokParams: {
      version: "published",
    },
  }),
});

Development vs Production

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    storyblokParams: {
      version: import.meta.env.DEV ? "draft" : "published",
    },
  }),
});

Combined Stories and Datasources

import { defineCollection } from "astro:content";
import { StoryblokLoaderStories, StoryblokLoaderDatasource } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    contentTypes: ["article", "page"],
    storyblokParams: {
      version: "published",
    },
  }),
});

const categories = defineCollection({
  loader: StoryblokLoaderDatasource({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    datasource: "categories",
  }),
});

export const collections = { stories, categories };

Custom Sorting Examples

Priority-based Sorting

Sort stories by a custom priority field in your content:

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    contentTypes: ["article"],
    customSort: (a, b) => {
      const priorityA = a.content?.priority || 0;
      const priorityB = b.content?.priority || 0;
      return priorityB - priorityA; // Higher priority first
    },
  }),
});

Multi-level Sorting

First sort by category, then by date within each category:

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    customSort: (a, b) => {
      // First level: sort by category
      const categoryA = a.content?.category || "zzz";
      const categoryB = b.content?.category || "zzz";
      
      if (categoryA !== categoryB) {
        return categoryA.localeCompare(categoryB);
      }
      
      // Second level: sort by date (newest first within same category)
      const dateA = new Date(a.created_at || 0);
      const dateB = new Date(b.created_at || 0);
      return dateB.getTime() - dateA.getTime();
    },
  }),
});

Featured Content First

Show featured content at the top, then sort the rest by date:

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    customSort: (a, b) => {
      // Featured content first
      const featuredA = a.content?.featured || false;
      const featuredB = b.content?.featured || false;
      
      if (featuredA !== featuredB) {
        return featuredB ? 1 : -1; // Featured items come first
      }
      
      // Then sort by creation date (newest first)
      const dateA = new Date(a.created_at || 0);
      const dateB = new Date(b.created_at || 0);
      return dateB.getTime() - dateA.getTime();
    },
  }),
});

What's New

v1.0.0

Major Release 🎉🎉🎉

This is the first stable release of astro-loader-storyblok! After some testing and refinement, the loader is now "feature-complete".

⚡ Performance Improvements

  • Optimized cache version checking: Implemented promise-based cache version updates to prevent redundant API calls when multiple collections are loading simultaneously
  • Better collection synchronization: Fixed issues where pressing 's' to sync collections in development mode wouldn't properly trigger refetching (#4)

🔧 Enhanced Developer Experience

  • Better error context: More detailed error reporting with collection-specific context
  • Improved debugging: Enhanced debug logging output with better formatting and more informative messages
  • Playground: Includes a playground sample useful for testing this loader.

� New Sorting Features

  • Custom Sort Functions: New customSort property allows complex sorting logic using custom functions
  • Simplified Sorting: New sortBy property provides easier sorting configuration with priority over storyblokParams.sort_by
  • Sorting Precedence: Clear hierarchy of sorting options: customSort > sortBy > storyblokParams.sort_by
  • Maintained Sort Order: Improved sorting logic ensures proper order when adding new entries to cached collections

�🏗️ Code Quality & Maintenance

  • Comprehensive test coverage: Expanded test suite with edge cases, integration tests, and sorting functionality across multiple content types
  • Code organization: Removed redundant code and cleaned up internal implementations
  • Documentation updates: Refreshed examples and removed references to deprecated functionality

Breaking Changes

  • Removed deprecated configuration: The second parameter pattern StoryblokLoaderStories(config, storyblokParams) has been completely removed. Use the single configuration object with storyblokParams property instead.

🚀 Migration from v0.x

Old (no longer supported):

const stories = defineCollection({
  loader: StoryblokLoaderStories(config, { version: "draft" }),
});

New (v1.0.0+):

const stories = defineCollection({
  loader: StoryblokLoaderStories({
    ...config,
    storyblokParams: { version: "draft" },
  }),
});

v0.2.7

  • Changed the name appearing in Astro's logger (removed 'astro-' for consistency with other Astro integrations).

v0.2.4

  • Add FIRST_PUBLISHED_AT_ASC, FIRST_PUBLISHED_AT_DESC, PUBLISHED_AT_ASC, PUBLISHED_AT_DESC to SortByEnum.

v0.2.3

  • Fix: schema for Datasource

v0.2.2

  • Fix: proper overload for StoryblokLoaderStories()

v0.2.1

  • Add test suite
  • Add Github workflows

v0.2.0

🚀 Performance Improvements

  • Enhanced Cache Version System: Now uses Storyblok's cache version (cv) to detect content changes more efficiently, reducing unnecessary API calls
  • Smart Cache Validation: Automatically skips fetching when no changes are detected in your Storyblok space
  • Shared Cache Management: New StoryblokLoader class enables multiple collections to share the same cache version

🏗️ Architecture Improvements

  • Improved Code Organization: Split the monolithic loader into separate, focused modules:
    • StoryblokLoaderStories - Stories functionality
    • StoryblokLoaderDatasource - Datasource functionality
    • StoryblokLoader - Advanced class-based usage
  • Better Type Safety: Enhanced TypeScript definitions and schema validation for datasources

🛠️ Developer Experience

  • Better Debugging: Enhanced logging with collection context and debug information
  • Improved Error Messages: More detailed error reporting with better context
  • Migration Warnings: Clear deprecation warnings with migration guidance

Breaking Changes

Since v0.2.0:

Since v0.2.0

This section documents changes that may affect your configuration but are backward compatible through deprecation warnings.

⚠️ Configuration Structure Change (Deprecated)

What changed: The two-parameter configuration pattern is deprecated in favor of a single configuration object.

Impact: Your existing code will continue to work but will show deprecation warnings. < v0.2.0 configuration pattern will not work anymore.

// ⚠️ DEPRECATED: ABANDONED since v1.0.0
const stories = defineCollection({
  loader: StoryblokLoaderStories(config, { version: "draft" }),
});

// ✅ RECOMMENDED
const stories = defineCollection({
  loader: StoryblokLoaderStories({
    ...config,
    storyblokParams: { version: "draft" },
  }),
});

🚀 New Advanced Usage Pattern

What's new: Introduction of the StoryblokLoader class for better performance in multi-collection setups.

// ✅ NEW: Advanced usage with shared cache management
import { StoryblokLoader } from "astro-loader-storyblok";

const storyblokLoader = new StoryblokLoader({ accessToken: "token" });

const stories = defineCollection({
  loader: storyblokLoader.getStoriesLoader({
    contentTypes: ["article"],
    storyblokParams: { version: "published" },
  }),
});

const categories = defineCollection({
  loader: storyblokLoader.getDatasourceLoader({
    datasource: "categories",
  }),
});
Since v0.0.4:

Since v0.0.4

This section documents all breaking changes introduced since version v0.0.4. If you're upgrading from v0.0.4 or earlier, please review these changes carefully.

1. Function Name Changes

StoryblokLoaderStoryblokLoaderStories
  • What changed: The main loader function has been renamed from StoryblokLoader to StoryblokLoaderStories
  • Reason: Better clarity and consistency as the package now supports multiple loader types (Stories and Datasources)
// ❌ Old (v0.0.4)
import { StoryblokLoader } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoader({ accessToken: "token" }),
});

// ✅ New (v0.1.0+)
import { StoryblokLoaderStories } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoaderStories({ accessToken: "token" }),
});

2. Enum Name Changes

SortBySortByEnum
  • What changed: The sorting enum has been renamed from SortBy to SortByEnum
  • Reason: Better naming convention and consistency
// ❌ Old (v0.0.4)
import { SortBy } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoader({
    accessToken: "token",
    sortBy: SortBy.CREATED_AT_DESC,
  }),
});

// ✅ New (v0.1.0+)
import { SortByEnum } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoaderStories(
    { accessToken: "token" },
    { sort_by: SortByEnum.CREATED_AT_DESC }
  ),
});

3. Configuration Structure Changes

Flattened configuration → Separated loader config and Storyblok API parameters
  • What changed: The configuration is now split into two parameters: loader-specific config and Storyblok API parameters
  • Reason: Better separation of concerns and more flexible API that directly maps to Storyblok's API parameters
// ❌ Old (v0.0.4)
const stories = defineCollection({
  loader: StoryblokLoader({
    accessToken: "token",
    version: "draft",
    contentTypes: ["article"],
    excludingSlugs: "home,about",
    sortBy: SortBy.CREATED_AT_DESC,
    useUuids: true,
    apiOptions: { region: "us" },
  }),
});

// ✅ New (v0.1.0+)
const stories = defineCollection({
  loader: StoryblokLoaderStories(
    {
      // Loader-specific configuration
      accessToken: "token",
      contentTypes: ["article"],
      useUuids: true,
      apiOptions: { region: "us" },
    },
    {
      // Standard Storyblok API parameters
      version: "draft",
      excluding_slugs: "home,about",
      sort_by: SortByEnum.CREATED_AT_DESC,
    }
  ),
});

4. Property Name Changes

Snake_case for Storyblok API parameters
  • What changed: Some properties now use snake_case to match Storyblok's API exactly
  • Reason: Direct mapping to Storyblok API parameters for consistency and better IntelliSense
Old Property (v0.0.4) New Property (v0.1.0+) Parameter Location
excludingSlugs excluding_slugs Storyblok API params (2nd parameter)
sortBy sort_by Storyblok API params (2nd parameter)
version version Moved to Storyblok API params (2nd parameter)

5. Type Name Changes

Updated type definitions for better clarity
  • What changed: Several interface names have been updated to reflect the new structure
  • Reason: Better type organization and clarity
// ❌ Old (v0.0.4)
import type { StoryblokLoaderConfig } from "astro-loader-storyblok";

// ✅ New (v0.1.0+)
import type { 
  StoryblokLoaderStoriesConfig,
  StoryblokLoaderDatasourceConfig
} from "astro-loader-storyblok";

Migration Guide

⚠️ Deprecation Notice (v0.2.0)

The second parameter in StoryblokLoaderStories is deprecated. While still functional with automatic backward compatibility, it will be removed in a future major version ✅.

Old (deprecated but still works):

// ⚠️ This used to trigger a deprecation warning but will not work anymore
const stories = defineCollection({
  loader: StoryblokLoaderStories(config, { version: "draft" }),
});

New (recommended):

// ✅ Move storyblok parameters to config.storyblokParams
const stories = defineCollection({
  loader: StoryblokLoaderStories({
    ...config,
    storyblokParams: { version: "draft" },
  }),
});

Or use the helper function:

// ✅ Use the helper function for easier migration
import { createStoriesConfig } from "astro-loader-storyblok";

const stories = defineCollection({
  loader: StoryblokLoaderStories(
    createStoriesConfig(config, { version: "draft" }),
  )
});

The deprecation warning will guide you through the migration and provides automatic backward compatibility.


Migration from v0.0.4

To migrate from v0.0.4 to the latest version:

  1. Update import names:

    • StoryblokLoaderStoryblokLoaderStories
    • SortBySortByEnum
    • StoryblokLoaderConfigStoryblokLoaderStoriesConfig
  2. Restructure configuration:

    • Move version, excluding_slugs, sort_by to the second parameter
    • Keep accessToken, contentTypes, useUuids, apiOptions in the first parameter
  3. Update property names:

    • excludingSlugsexcluding_slugs
    • sortBysort_by
  4. Test your configuration: After making these changes, verify that your content loads correctly in both development and production environments.

Playground Example

Want to see it in action? Check out our minimal playground example in the playground/minimal-astro-project directory. This demonstrates a basic implementation that displays a table of stories from Storyblok. It can be used for testing and development.

To run the playground:

  1. Clone this repository and install dependencies:

    # Clone and setup
    git clone https://github.com/romainpi/astro-loader-storyblok.git
    cd astro-loader-storyblok
    pnpm install
  2. Set up your environment variables in the playground directory:

    cd playground/minimal-astro-project
    cp .env.example .env  # If available
    # Add your STORYBLOK_DELIVERY_PREVIEW_API_TOKEN to the .env file
  3. Start the development server: pnpm dev

  4. Open your browser to http://localhost:4321

The playground showcases:

  • Basic content collection configuration using the new StoryblokLoader class
  • Fetching and displaying stories in a simple table format
  • Environment variable setup for the Storyblok access token

TypeScript Support

This package is built with TypeScript and provides full type definitions, including the StorySortFunction type for
custom sorting.

For even better type safety, consider using storyblok-to-zod to generate Zod schemas for your Storyblok components.

import { z } from "astro:content";
import { StoryblokLoaderStories, type StorySortFunction } from "astro-loader-storyblok";
import { pageSchema } from "./types/storyblok.zod.ts";

// Example with Zod schema (when using storyblok-to-zod)
const stories = defineCollection({
  loader: StoryblokLoaderStories({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    storyblokParams: {
      version: "published",
    },
  }),
  schema: pageSchema,
});

Background

This Astro content loader is a community-driven successor to Storyblok’s archived Astro Content Layer integration. In September 2024, Storyblok had partnered with Astro for the launch of the Content Layer API and released an alpha version of a loader however, the implementation never made it to the mainline and was subsequently archived and remained in a premature state.

This package provides a complete, production-ready solution with full TypeScript support and works seamlessly with storyblok-to-zod for type-safe content schemas.

Verbose output / debugging

There are two ways of outputting debug messages from astro-loader-storyblok to console.

  1. Run astro with the --verbose flag in order to output all of Astro's and Vite's debug messages to console.

  2. Enable and filter only for messages from loader-storyblok with the DEBUG=astro:loader-storyblok* environment variable (more info). Example:

    DEBUG=astro:loader-storyblok* astro build

Feedback

Feedback and contributions are welcome! If you run into a problem, don't hesitate to open a GitHub issue.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT - see LICENSE.txt for details.

About

Astro content loader for Storyblok

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •