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

@dbosoft/nextjs-site-marketing

v1.0.3

Published

Marketing page templates, sections, content components, and landing page system for dbosoft sites

Readme

@dbosoft/nextjs-site-marketing

Marketing page templates, sections, forms, contact handling, and landing page system for dbosoft product websites.

Installation

pnpm add @dbosoft/nextjs-site-marketing

This is a workspace package — add "@dbosoft/nextjs-site-marketing": "workspace:*" to your package.json.

Peer Dependencies

react >=19, react-dom >=19, next >=16, @heroicons/react >=2,
@headlessui/react >=2, @dbosoft/react-uicore >=1, clsx >=2,
prism-react-renderer >=2, prismjs >=1, fathom-client >=3, redis >=4

Dependencies

  • @dbosoft/nextjs-site-core (workspace)

Subpath Exports

| Import | Description | |--------|-------------| | ./types | Shared types: CTAButton, Badge, MaxWidth, etc. | | ./sections | Page sections: HeroSection, SuperHeroSection, CTASection, FinalCTA, ChallengeSection, BenefitsList, CategoryGrid, TechStackGrid, CodeExampleSection, WorkflowSection | | ./layouts | Page layouts: StandardPageLayout, SolutionPageLayout | | ./common/code | Code rendering: CodeFence, CollapsibleCodeFence, TerminalFrame | | ./common/sections | Structural: SectionWrapper, SectionDivider | | ./forms | Form components: DetailedContactForm, SimpleContactForm, NewsletterSignup, EmailCollectionForm, ContactCTA, formStyles | | ./lib/forms | Form utilities: validateEmail, sanitizeInput, checkHoneypot, withRateLimit, checkServerRateLimit | | ./lib/contact | Contact types + server handler: handleContactSubmission, ContactHandlerConfig, CONTACT_CONFIGS | | ./lib/landing | Landing page analytics: bot detection, engagement tracking, Fathom integration | | ./lib/redis | Redis client + sliding window rate limiter | | ./ui | UI components: Button, ScrollReveal | | ./css/prism | Prism syntax highlighting CSS |

Setup

1. Tailwind Content Paths

Content paths for @dbosoft packages are handled automatically by resolveDbosoftContent() in your Tailwind config (see @dbosoft/nextjs-site-core setup).

2. Prism CSS

Import the syntax highlighting styles:

@import '@dbosoft/nextjs-site-marketing/css/prism';

Usage

Page Sections

import { HeroSection, FinalCTA } from '@dbosoft/nextjs-site-marketing/sections'

<HeroSection
  title="Your Product"
  subtitle="Description of what it does"
  theme="auto"
  ctaButtons={[
    { text: 'Get Started', href: '/signup', variant: 'primary' },
    { text: 'Learn More', href: '/docs', variant: 'secondary' },
  ]}
/>

<FinalCTA
  title="Ready to get started?"
  subtitle="Try it free today."
  primaryButtonText="Sign Up"
  primaryButtonHref="/signup"
/>

Page Layouts

import { StandardPageLayout } from '@dbosoft/nextjs-site-marketing/layouts'

<StandardPageLayout
  hero={{ title: 'Page Title', subtitle: 'Subtitle' }}
  sections={[/* ... */]}
/>

Contact Forms

All form components accept a contactApiEndpoint prop — no hardcoded API paths.

import { DetailedContactForm, SimpleContactForm, NewsletterSignup } from '@dbosoft/nextjs-site-marketing/forms'

// Full form with name, email, company, message
<DetailedContactForm
  contactType="sales-inquiry"
  pathname="/pricing"
  contactApiEndpoint="/api/contact"
/>

// Quick email + message form
<SimpleContactForm
  contactType="demo-request"
  pathname="/demo"
  contactApiEndpoint="/api/contact"
/>

// Email-only signup (inline, standalone, or minimal variants)
<NewsletterSignup
  variant="inline"
  contactApiEndpoint="/api/contact"
/>

Contact API Handler

The server-side handler processes form submissions with validation, rate limiting, and webhook forwarding. Your API route becomes a thin wrapper:

// app/api/contact/route.ts
import { NextRequest } from 'next/server'
import { handleContactSubmission } from '@dbosoft/nextjs-site-marketing/lib/contact'

export async function POST(request: NextRequest) {
  return handleContactSubmission(request, {
    product: 'your-product',
  })
}

Code Blocks

import { CodeFence, TerminalFrame } from '@dbosoft/nextjs-site-marketing/common/code'

<CodeFence language="bash">npm install maxback</CodeFence>

<TerminalFrame title="Terminal">
  <CodeFence language="bash">maxback --version</CodeFence>
</TerminalFrame>

Customization

ContactHandlerConfig

The handleContactSubmission function accepts a config object:

interface ContactHandlerConfig {
  /** Product identifier sent with webhook data */
  product: string

  /** Webhook URL (falls back to CONTACT_WEBHOOK_URL env var) */
  webhookUrl?: string

  /** Override rate limits per contact type */
  rateLimits?: Record<string, { limit: number; window: number }>

  /** Override success messages per contact type */
  successMessages?: Record<string, string>

  /** Transform webhook payload before sending (return null to skip webhook) */
  onBeforeWebhook?: (data) => any | null

  /** Post-processing after successful submission */
  onSuccess?: (data, contactId) => void | Promise<void>
}

Example with custom rate limits and a Customer.io integration:

handleContactSubmission(request, {
  product: 'maxback',
  rateLimits: {
    'sales-inquiry': { limit: 2, window: 86400 },
  },
  successMessages: {
    'sales-inquiry': 'Thanks! We\'ll reply within 4 hours.',
  },
  onBeforeWebhook: (data) => ({
    ...data,
    priority: data.contactType === 'enterprise-support' ? 'high' : 'normal',
  }),
  onSuccess: async (data, contactId) => {
    await customerIO.track(data.eMail, { event: 'contact_submitted', contactId })
  },
})

Contact Types

Built-in contact types with default rate limits and success messages:

| Type | Rate Limit | Window | |------|-----------|--------| | demo-request | 1 | 24 hours | | enterprise-support | 1 | 7 days | | beta-access | 2 | 24 hours | | consultation | 2 | 24 hours | | sales-inquiry | 3 (default) | 1 hour | | newsletter | 3 (default) | 1 hour |

Environment Variables

| Variable | Purpose | |----------|---------| | CONTACT_WEBHOOK_URL | Webhook endpoint for contact form submissions | | REDIS_URL | Redis connection string for rate limiting |

Form Theming

All form components use semantic design token classes:

  • bg-surface-base, text-content-primary, border-border — adapt to light/dark mode
  • Override via Tailwind theme or CSS variables
  • No hardcoded dark-mode colors in any form component

CodeFence Customization

CodeFence supports custom token renderers for site-specific syntax (e.g., linking product-specific identifiers):

import { CodeFence } from '@dbosoft/nextjs-site-marketing/common/code'
import type { TokenRenderer } from '@dbosoft/nextjs-site-marketing/common/code'

const customRenderer: TokenRenderer = (token, defaultRender) => {
  if (token.content.startsWith('gene:')) {
    return <a href={`/genes/${token.content}`}>{token.content}</a>
  }
  return defaultRender(token)
}

<CodeFence language="yaml" tokenRenderers={{ plain: customRenderer }}>
  {content}
</CodeFence>