@coldsurf/shared-utils

v1.5.0

Published

Shared utilities for COLDSURF services.

Readme

@coldsurfers/shared-utils

Shared utilities for COLDSURF services.

Install

zod is a required peer dependency.

pnpm

pnpm add @coldsurfers/shared-utils zod

npm

npm install @coldsurfers/shared-utils zod

yarn

yarn add @coldsurfers/shared-utils zod

bun

bun add @coldsurfers/shared-utils zod

Optional peers

Install only when you use related utilities.

pnpm add jwt-decode schema-dts

Feature -> dependency map

  • decodeJwt (utils.jwt) uses jwt-decode at runtime.
  • buildSeoTags / createSeo (metadata) uses schema-dts types for JSON-LD typing.
  • createNextMetadata (@coldsurfers/shared-utils/next) uses the next Metadata type only (no runtime dependency).

SEO — Next.js App Router (/next)

createNextMetadata is the Next App Router twin of createSeoHead (/react): it binds a SiteConfig once and maps the framework-agnostic SEO engine output into Next's nested Metadata object. Since Metadata has no JSON-LD field, structured data is emitted separately through buildSeoScripts.

// app/lib/metadata.ts
import {
  createNextMetadata,
  buildSeoScripts,
  type SiteConfig,
} from '@coldsurfers/shared-utils/next';

const SITE: SiteConfig = {
  name: 'COLDSURF',
  baseUrl: 'https://blog.coldsurf.io',
  keywords: ['공연', 'indie'],
  icons: { icon: '/icons/favicon.ico', shortcut: '/icons/favicon.ico', apple: '/icons/apple-touch-icon.png' },
  publisher: { name: 'COLDSURF', url: 'https://coldsurf.io', sameAs: ['https://coldsurf.io'] },
  editor: { name: 'imcoldsurf' },
};

export const seo = createNextMetadata(SITE);

// app/[series]/[slug]/layout.tsx
export function generateMetadata(): Metadata {
  return seo({
    path: '/log/some-post',
    title: 'Some Post',
    description: 'A post',
    article: { publishedTime, author: ['Writer A', 'Writer B'] }, // multiple writers supported
    robots: 'noindex, nofollow', // optional per-route override
  });
}

// JSON-LD — inject in the layout (Metadata cannot carry <script>)
const scripts = buildSeoScripts(
  { path: '/log/some-post', title, description, jsonLd: [{ type: 'WebSite' }, { type: 'Article' }] },
  SITE,
);
// scripts.map((s) => <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: s }} />)

next is an optional peer dependency — install it only when you use the /next adapter. The adapter imports the Metadata type only; there is no runtime next dependency.

What to install by use case

  • You only use date/slug/uuid/number/parser/file/location/uri utils:
pnpm add @coldsurfers/shared-utils zod
  • You use decodeJwt:
pnpm add @coldsurfers/shared-utils zod jwt-decode
  • You use buildSeoTags / createSeo / createSeoHead with schema-dts types:
pnpm add @coldsurfers/shared-utils zod schema-dts
  • You use both JWT + metadata helpers:
pnpm add @coldsurfers/shared-utils zod jwt-decode schema-dts
  • You use the Next.js metadata adapter (createNextMetadata / buildSeoScripts):
pnpm add @coldsurfers/shared-utils zod schema-dts next