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

@b10cks/nuxt

v3.2.1

Published

b10cks Nuxt client SDK

Readme

@b10cks/nuxt

Nuxt 4 module for integrating b10cks, the open-source headless CMS with a composable block-based content API.

Installation

npm install @b10cks/nuxt @b10cks/vue @b10cks/client @b10cks/richtext

Setup

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@b10cks/nuxt'],
  b10cks: {
    accessToken: 'your-access-token',
    apiUrl: 'https://api.b10cks.com/api',
    componentsDir: '~/b10cks',
    // Optional: offset applied when a selected block is scrolled into view, so
    // selection clears a fixed app header (number → px, or a string like '5rem').
    scrollOffset: 80,
    // Optional: restrict the preview bridge handshake to known editor origins.
    allowedOrigins: ['https://app.b10cks.com'],
  },
})

scrollOffset can also be set purely in CSS — :root { --b10cks-scroll-offset: 80px }.

Usage

Each composable returns the same object as Nuxt's useAsyncData() — destructure data, pending, error, and refresh as needed.

// Single content entry by slug
const { useContent } = useB10cksApi()
const { data: page, error } = await useContent('home')
if (error.value) throw error.value

// With query params (language, vid, etc.)
const { data: page } = await useContent('home', {
  language_iso: 'de',
  vid: 'published', // or 'draft'
})
// List of content entries — params accepts the same filter object as dataApi.getContents()
const { useContents } = useB10cksApi()

// Plain params
const { data: items } = await useContents({ language_iso: 'en', vid: 'published' })

// Typed filter object (no wire-format string hacks needed)
const { data: people } = await useContents({
  language_iso: 'en',
  vid: 'published',
  filter: {
    canonical_id: { in: ['id-1', 'id-2'] },
  },
})
// Redirects and config
const { useRedirects, useB10cksConfig } = useB10cksApi()
const redirects = await useRedirects()
const { data: config, pending, error, refresh } = await useB10cksConfig()

The helpers use Nuxt's useAsyncData() under the hood, so requests participate in SSR payload serialization and are not refetched during hydration. Each helper derives a stable async-data key from its inputs — no manual key needed.

B10cksComponent and directives

B10cksComponent, v-editable, and v-editable-field are available globally after registering the module. componentsDir in the config tells the module where your block components live; it auto-registers them by block name.

<template>
  <!-- Renders the component matching content.block from componentsDir -->
  <B10cksComponent
    v-if="content"
    :block="{ id: content.id, block: content.block, ...content.content }"
    :content="content"
  />
</template>
<!-- Mark a block as selectable; it also live-updates in place while editing -->
<div v-editable="block">…</div>

<!-- Inline-edit a simple string field -->
<h1 v-editable-field="{ id: block.id, field: 'header' }">{{ block.header }}</h1>

<!-- Rich text / complex fields: deep-select so the editor opens its own editor -->
<B10cksRichText
  :document="block.body"
  v-editable-field="{ id: block.id, path: ['body'], mode: 'select' }"
/>

For whole-tree reactive updates while editing — including nested and rich text fields — wrap your content in usePreviewContent (auto-imported by the module):

<script setup lang="ts">
const { useContent } = useB10cksApi()
const { data } = await useContent('home')
// Pass a getter (or ref) so the preview resets when content is refetched
// on a route/locale change instead of keeping the first tree.
const content = usePreviewContent(() => data.value.content)
</script>

<template>
  <B10cksComponent :block="content" />
</template>

If you need to override Nuxt's cache identity behavior, pass a custom key as a third argument to any composable.

Page translations

usePageTranslations maintains a reactive locale → path map built from an IBContent entry and its translations array. Use it to drive language-switcher links without any extra API calls.

<script setup lang="ts">
const { useContent } = useB10cksApi()
const { translations, setFromContent, clear } = usePageTranslations()

const { data: content } = await useContent(slug, { language_iso: locale })
if (content.value) setFromContent(content.value)

onBeforeRouteLeave(() => clear())
</script>

<template>
  <!-- translations.value: { en: '/en/about', de: '/de/ueber-uns' } -->
  <NuxtLink
    v-for="(path, lang) in translations"
    :key="lang"
    :to="path"
  >{{ lang }}</NuxtLink>
</template>

setFromContent uses buildLocalizedPath from @b10cks/client internally, so paths are always correctly normalized and locale-prefixed. setTranslations lets you set the map manually when you need full control.

Rich text usage

Use B10cksRichText to render a b10cks RichTextDocument (a TipTap/ProseMirror-style JSON document) on the server and client with a dependency-free renderer.

<script setup lang="ts">
const { useContent } = useB10cksApi()
const { data: page, pending } = await useContent<{ body?: Record<string, unknown> }>('home')
</script>

<template>
  <div v-if="pending">Loading…</div>

  <B10cksRichText
    v-else
    :document="page?.content?.body"
    class="prose"
  />
</template>

If you need to render HTML manually, you can use renderRichText:

import { renderRichText } from '@b10cks/nuxt'

const html = renderRichText(document)

Migrating from v2: renderRichText and B10cksRichText are re-exported from @b10cks/vue/rich-text via @b10cks/nuxt. Imports from @b10cks/nuxt continue to work — no import path change required for Nuxt consumers.

License

MIT