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

@duffcloudservices/cms

v0.1.1

Published

Vue 3 composables and Vite plugins for DCS CMS integration

Readme

@duffcloudservices/cms

Vue 3 composables and Vite plugins for DCS (Duff Cloud Services) CMS integration.

Installation

# Using pnpm
pnpm add @duffcloudservices/cms

# Using npm
npm install @duffcloudservices/cms

# Using yarn
yarn add @duffcloudservices/cms

Peer Dependencies

This package requires:

  • vue ^3.4.0
  • @unhead/vue ^1.9.0

Quick Start

1. Configure Vite Plugins

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { dcsContentPlugin, dcsSeoPlugin } from '@duffcloudservices/cms/plugins'

export default defineConfig({
  plugins: [
    vue(),
    dcsContentPlugin(),
    dcsSeoPlugin()
  ]
})

For VitePress:

// .vitepress/config.ts
import { defineConfig } from 'vitepress'
import { dcsContentPlugin, dcsSeoPlugin } from '@duffcloudservices/cms/plugins'

export default defineConfig({
  vite: {
    plugins: [
      dcsContentPlugin(),
      dcsSeoPlugin()
    ]
  }
})

2. Set Environment Variables

# .env
VITE_SITE_SLUG=your-site-slug

# Optional: for runtime overrides (premium tier)
VITE_API_BASE_URL=https://portal.duffcloudservices.com
VITE_TEXT_OVERRIDE_MODE=commit  # 'commit' (default) or 'runtime'

3. Use Composables

<script setup lang="ts">
import { useTextContent, useSEO } from '@duffcloudservices/cms'

// Text content with defaults
const { t } = useTextContent({
  pageSlug: 'home',
  defaults: {
    'hero.title': 'Welcome to Our Site',
    'hero.subtitle': 'Build amazing things with us',
    'cta.primary': 'Get Started'
  }
})

// SEO configuration
const { applyHead } = useSEO('home')
applyHead()
</script>

<template>
  <section class="hero">
    <h1>{{ t('hero.title') }}</h1>
    <p>{{ t('hero.subtitle') }}</p>
    <button>{{ t('cta.primary') }}</button>
  </section>
</template>

Composables

useTextContent

Provides text content management with build-time injection and optional runtime overrides.

import { useTextContent } from '@duffcloudservices/cms'

const {
  t,                    // (key: string, fallback?: string) => string
  texts,                // ComputedRef<Record<string, string>>
  overrides,            // Ref<Record<string, string>>
  isLoading,            // Ref<boolean>
  error,                // Ref<string | null>
  refresh,              // () => Promise<void>
  hasOverride,          // (key: string) => boolean
  hasBuildTimeContent,  // boolean
  mode                  // 'commit' | 'runtime'
} = useTextContent({
  pageSlug: 'home',
  defaults: {
    'hero.title': 'Default Title'
  },
  fetchOnMount: true,  // default: true (only matters in runtime mode)
  cacheTtl: 60000      // default: 60000ms
})

Content Resolution Order:

  1. Runtime API overrides (premium tier only)
  2. Build-time content from .dcs/content.yaml
  3. Hardcoded defaults passed to the composable

useSEO

Provides SEO configuration with meta tags, Open Graph, Twitter Cards, and JSON-LD.

import { useSEO } from '@duffcloudservices/cms'

const {
  config,         // ComputedRef<ResolvedPageSeo>
  applyHead,      // (overrides?: HeadOverrides) => void
  getSchema,      // () => object[]
  getCanonical,   // () => string
  hasBuildTimeSeo // boolean
} = useSEO('home', '/') // pageSlug, optional pagePath

// Apply all meta tags
applyHead()

// Or with overrides
applyHead({
  title: 'Custom Title',
  description: 'Custom description',
  schemas: [...getSchema(), customSchema]
})

useReleaseNotes

Fetches release notes from the DCS Portal API.

import { useReleaseNotes } from '@duffcloudservices/cms'

const {
  releaseNote,  // Ref<ReleaseNote | null>
  isLoading,    // Ref<boolean>
  error,        // Ref<string | null>
  refresh       // () => Promise<void>
} = useReleaseNotes('1.2.0')  // or 'latest'

useSiteVersion

Gets the current site version for footer badges.

import { useSiteVersion } from '@duffcloudservices/cms'

const {
  version,          // Ref<string | null>
  isLoading,        // Ref<boolean>
  releaseNotesUrl   // ComputedRef<string>
} = useSiteVersion()

Vite Plugins

dcsContentPlugin

Injects .dcs/content.yaml at build time.

import { dcsContentPlugin } from '@duffcloudservices/cms/plugins'

dcsContentPlugin({
  contentPath: '.dcs/content.yaml',  // default
  debug: false                        // default
})

dcsSeoPlugin

Injects .dcs/seo.yaml at build time.

import { dcsSeoPlugin } from '@duffcloudservices/cms/plugins'

dcsSeoPlugin({
  seoPath: '.dcs/seo.yaml',  // default
  debug: false                // default
})

Configuration Files

.dcs/content.yaml

version: 1
lastUpdated: "2025-01-01T00:00:00Z"
updatedBy: "portal"

global:
  nav.home: Home
  nav.about: About
  footer.copyright: © 2025 My Company

pages:
  home:
    hero.title: Welcome to Our Site
    hero.subtitle: Build amazing things
    cta.primary: Get Started
  about:
    hero.title: About Us
    hero.subtitle: Learn more about our mission

.dcs/seo.yaml

version: 1
lastUpdated: "2025-01-01T00:00:00Z"

global:
  siteName: My Site
  siteUrl: https://example.com
  locale: en_US
  defaultTitle: My Site
  defaultDescription: Build amazing things with us
  titleTemplate: "%s | My Site"
  
  social:
    twitter: mycompany
    linkedin: my-company
  
  images:
    logo: https://example.com/logo.png
    ogDefault: https://example.com/og-image.jpg

pages:
  home:
    title: Welcome
    description: Build amazing things with our platform
    noTitleTemplate: true
    openGraph:
      type: website
    twitter:
      card: summary_large_image
  
  about:
    title: About Us
    description: Learn more about our company and mission

TypeScript Support

All composables and plugins are fully typed. Import types as needed:

import type {
  TextContentConfig,
  TextContentReturn,
  SeoConfiguration,
  PageSeoConfig,
  ReleaseNote
} from '@duffcloudservices/cms'

Migration from Manual Setup

If you're migrating from manually copied composables:

// Before:
import { useTextContent } from '@/lib/use-text-content'

// After:
import { useTextContent } from '@duffcloudservices/cms'

The API is the same, so no other code changes are needed.

License

MIT