Skip to content

rubix-studios-pty-ltd/payload-typesense

Repository files navigation

PayloadCMS + Typesense Plugin

Rubix Studios' Typesense integration for Payload CMS is built for production search workflows, with a lightweight, modular structure and optional support for advanced capabilities such as vector querying.

The plugin is actively maintained by Rubix Studios.

npm version Release

Installation

pnpm add @rubixstudios/payload-typesense
// payload.config.ts
import { buildConfig } from 'payload/config'
import { typesenseSearch } from '@rubixstudios/payload-typesense'

export default buildConfig({
  plugins: [
    typesenseSearch({
      typesense: {
        apiKey: 'xyz',
        nodes: [
          {
            host: 'localhost',
            port: 8108,
            protocol: 'http',
          },
        ],
      },
      collections: {
        posts: {
          enabled: true,
          searchFields: ['title', 'content'],
          facetFields: ['category', 'status'],
          displayName: 'Blog Posts',
          icon: '📝',
          syncLimit: 500, // Overrides the default sync limit of 1000
        },
      },
      // This feature is experimental
      vectorSearch: {
        enabled: true, // Enables vector-based semantic search
        embedFrom: ['title', 'content'], // Omit to fall back to collection searchFields
        embeddingModel: 'azure/text-embedding-ada-002',
        modelConfig: {
          api_key: 'your-api-key',
          url: 'https://modelendpoint.com/openai',
        },
    }),
  ],
})
import { HeadlessSearchInput } from '@rubixstudios/payload-typesense'

export function GlobalSearchPage() {
  return (
    <HeadlessSearchInput
      baseUrl="http://localhost:3000"
      theme="modern" // Available themes: "modern" | "dark"
      placeholder="Search everything..."
      onResultClick={(result) => {
        console.log('Selected document:', result.document)
      }}
    />
  )
}

export function CollectionSearch() {
  return (
    <HeadlessSearchInput
      baseUrl="http://localhost:3000"
      collections={['posts', 'products']}
      placeholder="Search posts and products..."
      onResultClick={(result) => {
        console.log('Selected document:', result.document)
      }}
    />
  )
}

export function VectorSearch() {
  return (
    <HeadlessSearchInput
      baseUrl="http://localhost:3000"
      vector={true} // Vector search enabled
      collections={['posts', 'products']}
      placeholder="Search posts and products..."
      onResultClick={(result) => {
        console.log('Selected document:', result.document)
      }}
    />
  )
}

Features

  • Performance
    Sub-millisecond search responses with optimized request handling.
  • Flexible Search
    Single-collection, multi-collection, or universal search using one component.
  • Vector Search
    Optional semantic search using embeddings, with graceful fallback to keyword search.
  • Modern UI
    Headless, responsive implementation compatible with Tailwind CSS.
  • Real-Time Synchronisation
    Continuous indexing and sync with Payload CMS.
  • Efficient Caching
    In-memory caching with configurable TTL and race-condition safeguards.
  • Production Ready
    Robust error handling, deployment-safe defaults, and platform compatibility.
  • Tree-Shakable Architecture
    Modular design enabling smaller bundles and selective feature usage.

Endpoints

  • GET /api/search - Universal search across all collections
  • GET /api/search/{collection} - Search specific collection
  • POST /api/search/{collection} - Advanced search with filters
  • GET /api/search/{collection}/suggest - Search suggestions
  • GET /api/search/collections - Collection metadata
  • GET /api/search/health - Health check

Components

  • HeadlessSearchInput: Single component supporting all search patterns:
  • Collections: collections={['posts', 'products']} - Smart filtering with universal search
  • Universal Search: No collection props - Search across all collections
  • Complete UI Control: Customizable rendering with comprehensive theme system

Themes

The plugin includes a powerful theme system with 2 pre-built themes and unlimited customization:

Pre-built

// Modern theme (default)
<HeadlessSearchInput theme="modern" />

// Dark theme
<HeadlessSearchInput theme="dark" />

Custom

const customTheme = {
  theme: 'modern',
  colors: {
    inputBorderFocus: '#10b981',
    inputBackground: '#f0fdf4',
    resultsBackground: '#f0fdf4',
  },
  spacing: {
    inputPadding: '1rem 1.25rem',
    inputBorderRadius: '1.5rem',
  },
  enableAnimations: true,
  enableShadows: true,
}

<HeadlessSearchInput theme={customTheme} />

Theme Features

  • 2 Pre-built Themes: Modern, Dark
  • Unlimited Customization: Override any color, spacing, typography, or animation
  • Performance Options: Disable animations/shadows for better performance
  • Responsive Design: Automatic mobile optimization
  • CSS Variables: Advanced styling with CSS custom properties
  • TypeScript Support: Full type safety for all theme configurations

Production

  • Race Condition Protection: ensureCollection prevents startup crashes
  • Type Safety: Proper Payload CMS types prevent runtime errors
  • Document Validation: Filters malformed data before sync
  • Graceful Degradation: Silent failures don't break Payload operations

Developer

  • Smaller Components: Easier to understand and maintain
  • Maintainable: Single Responsibility Principle enforced
  • Well-Documented: Clear separation of concerns

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For support or inquiries:

Author

Rubix Studios
https://rubixstudios.com.au

Acknowledgments

About

A production-ready search plugin that integrates Typesense with Payload CMS, offering fast, typo-tolerant search with real-time synchronization.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors