Skip to main content

definePlugin API

The definePlugin function is the entry point for extending Coralite's functionality. It allows you to inject server-side logic, register custom templates, and most importantly, bundle and configure client-side scripts that can be used by your components.

Configuration Options #

The definePlugin function accepts a configuration object with the following properties:

JavaScript
Code copied!
  import { definePlugin } from 'coralite'
  
  const myPlugin = definePlugin({
    name: 'my-plugin', // Required: Unique name for the plugin
  
    // Optional: Main server-side logic
    method: (options, context) => {
      // ... implementation
    },
  
    // Optional: Register custom components
    components: ['./path/to/component.html'],
  
    // Optional: Client-side script configuration
    client: {
      setup: async () => { /* ... */ },
      helpers: { /* ... */ },
      imports: [ /* ... */],
      config: { /* ... */ }
    },
  
    // Optional: Server-side lifecycle hooks
    onPageSet: async (data) => { /* ... */ },
    // ... other hooks
  })

Server-Side Hooks #

Plugins can hook into Coralite's build lifecycle to perform actions when pages or components are processed.

Client-Side Scripting #

The client property is powerful: it allows you to inject code that runs in the browser. This code is bundled with your application.

client.setup #

A client-side function that runs when the plugin is registered in the browser. Use it to prepare data or environment for the plugin in the frontend.

client.helpers #

Define helper functions that will be available to defineComponent scripts in the browser. To safely bridge global plugin configuration with local Web Component instances, Coralite requires client.helpers to be authored using a strict Two-Phase Currying System.

  1. Phase 1 (Global Context): The outermost function receives the globalContext (containing imports and global config).
  2. Phase 2 (Local Instance Context): It must return a second function that receives the local Web Component instance context ({ values, root, signal }). Here, root is the component's HTMLElement (or Document), and signal is an AbortSignal.
  3. Phase 3 (Execution): It finally returns the final value (which can be a function, object, or primitive) that is injected into the client's helpers object for use in the browser script.

Note on signal: The signal is tied natively to the component's mount lifecycle. It triggers .abort() automatically when an imperative component is unmounted from the DOM, making it perfect for cleaning up event listeners. For declarative components, signal is null.

JavaScript
Code copied!
  definePlugin({
    name: 'utils',
    client: {
      helpers: {
        // Phase 1: Receives Global Context
        formatDate(globalContext) {
          // Phase 2: Receives Local Instance Context
          return ({ values, root, signal }) => {
            // Phase 3: The actual helper function
            return (date) => {
              return new Date(date).toLocaleDateString()
            }
          }
        }
      }
    }
  })

Client Imports #

Use client.imports to make external libraries (npm packages, local files, or remote URLs) available to your client-side helpers. Coralite handles the bundling and injection for you.

Import Types #

Remote Import (ESM) #

Import a library directly from a CDN.

JavaScript
Code copied!
  imports: [
    {
      specifier: 'https://esm.sh/canvas-confetti@1.6.0',
      defaultExport: 'confetti'
    }
  ]

Local Import #

Import a local JavaScript module.

JavaScript
Code copied!
  definePlugin({
    name: 'analytics',
    client: {
      config: {
        trackingId: 'UA-123456-7',
        debug: true
      },
      // ...
    }
  })

JSON Import #

Import a JSON file as a module.

JavaScript
Code copied!
  imports: [
    {
      specifier: './data/config.json',
      defaultExport: 'config',
      attributes: { type: 'json' }
    }
  ]

Import Options #

Client Configuration #

The client.config object allows you to pass static configuration data from the server (where the plugin is defined) to the client (where helpers run). This is useful for API keys, theme settings, or feature flags.

JavaScript
Code copied!
  definePlugin({
    name: 'analytics',
    client: {
      config: {
        trackingId: 'UA-123456-7',
        debug: true
      },
      // ...
    }
  })

Context Injection #

Both client.imports and client.config are automatically injected into the globalContext object (Phase 1) passed to your helper factories.

Access them via:

JavaScript
Code copied!
  // Inside client.helpers
  helpers: {
    trackEvent: (globalContext) => {
      const { trackingId } = globalContext.config;
      const { analyticsLib } = globalContext.imports;
  
      return ({ values, root, signal }) => {
        return (eventName) => {
          analyticsLib.send(trackingId, eventName);
        }
      }
    }
  }

Complete Example: Confetti Plugin #

Let's build a plugin that triggers a confetti explosion using a remote library and allows configuration of particle count.

JavaScript
Code copied!
  import { definePlugin } from 'coralite'
  
  export default definePlugin({
    name: 'confetti-plugin',
    client: {
      // 1. Import the library
      imports: [
        {
          specifier: 'https://esm.sh/canvas-confetti@1.6.0',
          defaultExport: 'confetti'
        }
      ],
  
      // 2. Define default configuration
      config: {
        particleCount: 100,
        spread: 70
      },
  
      // 3. Create the curried helper
      helpers: {
        explode: (globalContext) => {
          // Phase 1: Access injected imports and config globally
          const confetti = globalContext.imports.confetti
          const config = globalContext.config
  
          return ({ values, root, signal }) => {
            // Phase 2: Local context (we don't need it for confetti, but must return it)
  
            return () => {
              // Phase 3: The actual execution
              if (!confetti) {
                console.warn('Confetti library not loaded')
                return
              }
  
              // Use the library with the config
              confetti({
                particleCount: config.particleCount,
                spread: config.spread,
                origin: { y: 0.6 }
              })
            }
          }
        }
      }
    }
  })
        
  
        <p><strong>Usage in a component:</strong></p>
        <coralite-code-html>
          <template id="celebration-button">
            <button ref="btn">Celebrate!</button>
          </template>
  
          <script type="module">
            import { defineComponent } from 'coralite'
  
            export default defineComponent({
              script: (context) => {
                const { helpers } = context
                const btn = helpers.refs('btn')
            
                // The fully curried 'explode' helper is now available
                const explode = helpers.explode
  
                btn.addEventListener('click', () => {
                  explode()
                })
              }
            })
          </script>
        </coralite-code-html>

Start Building with Coralite!

Use the scaffolding script to get jump started into your next project with Coralite

Copied commandline!