npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

meowww-storyblok-proxy

v0.0.21

Published

Storyblok Proxy

Readme

meowww-storyblok-proxy

npm version

A powerful Nuxt module that provides a comprehensive proxy between your Nuxt app and the Storyblok API. It handles API routes, asset requests, authentication, caching, and webhook processing with Storyblok access tokens.

✨ Features

  • 🔄 API Proxy: Seamless proxying of all Storyblok API requests
  • 🖼️ Asset Handling: Proxied asset requests with signed URLs and image operations
  • Smart Caching: Configurable caching strategies with SWR support
  • 🔐 Secure: Server-side token handling (never exposed to client)
  • 📄 Auto-Pagination: Automatic pagination for large datasets
  • 🎣 Webhook Support: Built-in webhook handling for content updates
  • 🧩 TypeScript: Full TypeScript support with comprehensive type definitions
  • 🎨 Composables: Ready-to-use composables for common operations

Installation

npm install meowww-storyblok-proxy
# or
yarn add meowww-storyblok-proxy
# or
pnpm add meowww-storyblok-proxy

Add the module to your nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['meowww-storyblok-proxy'],
  storyblokProxy: {
    accessToken: process.env.STORYBLOK_TOKEN,
    assetToken: process.env.STORYBLOK_ASSET_TOKEN,
    nuxtBase: 'https://yourdomain.com', // Required: Your app's base URL
    version: 'published', // or 'draft'
  },
})

Configuration

All options can be configured under the storyblokProxy key in nuxt.config.ts. Default values are shown below.

interface ModuleOptions {
  /** Enable debug logging */
  debug: boolean
  /** Base route for the proxy (default: '/cms') */
  routeBase: string
  /** Sub-route for assets (default: '/_assets') */
  assetBase: string
  /** Base URL of the application (including protocol and host) */
  nuxtBase: string
  /** Storyblok Content Delivery API token */
  accessToken: string
  /** Storyblok Asset token for secured media */
  assetToken: string
  /** Webhook URL path for Storyblok webhooks */
  webhookUrl: string
  /** Secret for webhook verification */
  webhookSecret: string
  /** Content version ('draft' or 'published') */
  version: 'draft' | 'published'
  /** Storyblok API region */
  region: 'eu' | 'us' | 'ap' | 'ca' | 'cn'
  /** Enable automatic pagination for API calls */
  autoPaginate: boolean
  /** Cache configuration */
  cache: {
    /** Cache strategy for API routes */
    type: 'private' | 'public' | 'client' | 'disabled'
    /** Cache duration in seconds */
    maxAge: number
    /** Enable stale-while-revalidate */
    swr: boolean
    /** Asset cache configuration */
    assets: {
      /** Cache strategy for assets */
      type: 'private' | 'public' | 'client' | 'disabled'
      /** Cache duration in seconds */
      maxAge: number
      /** Enable stale-while-revalidate */
      swr: boolean
    }
  }
  /** Map of storyblok image operations, 'header' => '500x0' */
  imageOperations?: Record<string, string>
}

General Options

| Option | Type | Default | Description | | ---------------- | -------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | debug | boolean | false | Enables debug logs for troubleshooting. | | routeBase | string | '/cms' | Base route for the proxy. All Storyblok API requests are served through this path. | | assetBase | string | '/_assets' | Sub-route for Storyblok assets (e.g., images). | | nuxtBase | string | '' | Base URL of the application (including protocol and host). Example: http://localhost:3000. This value is used to build the internal endpoint for the installed @storyblok/nuxt plugin (endpoint: ${options.nuxtBase}${options.routeBase}`). | | accessToken | string | '' | Storyblok Content Delivery API token. | | assetToken | string | '' | Storyblok Asset token for secured media. | | webhookUrl | string | '' | Webhook URL path for Storyblok webhooks (e.g., /webhook). | | webhookSecret | string | '' | Secret for webhook verification. | | version | 'draft' \| 'published' | 'draft' | Defines whether draft or published content should be loaded. | | region | 'eu' \| 'us' \| 'ap' \| 'ca' \| 'cn' | 'eu' | Storyblok API region, depending on your space. | | autoPaginate | boolean | false | Enable automatic pagination for API calls to fetch all results. |

Cache Options

| Option | Type | Default | Description | | --------------------- | ----------------------------------------- | ----------- | --------------------------------------- | | cache.type | 'private' \| 'public' \| 'client' \| 'disabled' | 'private' | Cache strategy for API routes. | | cache.maxAge | number | 60 | Time in seconds to cache API responses. | | cache.swr | boolean | true | Enables stale-while-revalidate. | | cache.assets.type | 'private' \| 'public' \| 'client' \| 'disabled' | 'client' | Cache strategy for assets. | | cache.assets.maxAge | number | 60 | Time in seconds to cache assets. | | cache.assets.swr | boolean | true | Enables SWR for assets. |

Cache Strategies

  • private: Cache on the server only (default for API routes)
  • public: Cache on both server and client
  • client: Cache on the client only (default for assets)
  • disabled: No caching

Routes

When enabled, the module registers the following routes:

  • Content API: ${routeBase}/** → Proxied requests to Storyblok Content API
  • Links API: ${routeBase}/_links → Proxy for the Storyblok Links API
  • Assets: ${routeBase}${assetBase}/** → Proxy for Storyblok assets
  • Webhooks: ${routeBase}${webhookUrl} → Webhook endpoint (if configured)

Example Configuration

export default defineNuxtConfig({
  modules: ['meowww-storyblok-proxy'],
  storyblokProxy: {
    debug: true,
    routeBase: '/cms',
    assetBase: '/_assets',
    nuxtBase: 'http://localhost:3000',
    accessToken: process.env.STORYBLOK_TOKEN,
    assetToken: process.env.STORYBLOK_ASSET_TOKEN,
    webhookUrl: '/webhook',
    webhookSecret: process.env.STORYBLOK_WEBHOOK_SECRET,
    version: 'draft',
    region: 'eu',
    autoPaginate: true,
    cache: {
      type: 'private',
      maxAge: 120,
      swr: true,
      assets: {
        type: 'public',
        maxAge: 300,
        swr: true,
      },
    },
  },
})

Usage

This module automatically installs @storyblok/nuxt. You can use the composables it provides to fetch content.

Fetching a Story

<script setup lang="ts">
const story = await useStoryblok('home')
</script>

<template>
  <div>
    <h1>{{ story.content.title }}</h1>
    <p>{{ story.content.intro }}</p>
  </div>
</template>

Using the Proxy

Because the module rewrites the API endpoint, requests will automatically go through your Nuxt server:

// Instead of calling api.storyblok.com directly
// The request goes through: /cms/...
const story = await useStoryblok('about')

Fetching Links

<script setup lang="ts">
const links = await useStoryblokProxyLinks()
</script>

<template>
  <nav>
    <NuxtLink 
      v-for="link in links" 
      :key="link.id" 
      :to="link.slug"
    >
      {{ link.name }}
    </NuxtLink>
  </nav>
</template>

Fetching Assets

<template>
  <!-- Assets are proxied through /cms/_assets/... -->
  <img 
    :src="useStoryblokProxyAsset(storyblok_image.filename, '0x300')" 
    alt="Storyblok Asset" 
  />
</template>

Server-Side API Calls

You can also use the proxy utilities directly in server-side code:

// server/api/custom.ts
import { call, cachedCall, asset, cachedAsset, config } from '#storyblok-proxy'

export default defineEventHandler(async () => {
  // Direct API call
  const url = new URL('/stories', 'http://localhost')
  const stories = await call(url, config.autoPaginate)
  
  // Cached API call
  const cachedStories = await cachedCall(url, config.autoPaginate)
  
  // Asset handling
  const assetUrl = new URL('/f/123456/image.jpg', 'https://a.storyblok.com')
  const assetData = await cachedAsset(assetUrl, '0x300')
  
  return { stories, assetData }
})

Notes

  • The module automatically installs and configures @storyblok/nuxt.
  • Tokens (accessToken, assetToken) are stored securely and never exposed to the client.
  • The version option is available through the storyblok-proxy-config.mjs file for client-side access.
  • All API calls are automatically proxied through your Nuxt server for better performance and security.
  • Caching is handled by Nitro's built-in caching system with configurable strategies.
  • Webhook support allows for real-time content updates and cache invalidation.
  • Server-side utilities are available through the #storyblok-proxy virtual module.

Development

Building

npm run build

Testing

npm run test

Development Mode

npm run dev

Contributing

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


Made with ❤️ by [email protected]