Skip to main content

Advanced Client-Side JavaScript

Coralite's component system allows you to bundle client-side logic directly with your HTML templates using the defineComponent helper. This guide explains how to create interactive components, manage data flow, and access DOM elements.

The defineComponent Helper #

The defineComponent function is the core of Coralite's component logic. It separates server-side data preparation from client-side interactivity.

javascript
Code copied!
  import { defineComponent } from 'coralite'
  
  export default defineComponent({
    client: {
      // Server-side: Asynchronous data preparation
      async setup() {
        // Simulate fetching data or reading a file
        const data = await fetch('https://api.example.com/data').then(r => r.json())
  
        return {
          remoteData: data
        }
      },
  
      // Client-side: Runs in the browser
      script({ values }) {
        console.log('Component mounted with props:', values)
        console.log('Remote data from setup:', values.remoteData)
      }
    }
  })

Server-Side Setup #

The setup function runs during the build process (server-side). Its primary purpose is to perform asynchronous operations that prepare data for your component, such as fetching content from an API or reading files from the disk.

Note: You do not need to use setup just to pass props (attributes) to the client-side script. All attributes passed to the component are automatically available in the values object within the script context.

Client-Side Script #

The script function is extracted, compiled, and executed in the browser. It allows you to add interactivity to your component instance.

Note: Since this code runs in the browser, it cannot access server-side Node.js modules directly. However, it receives the data returned by setup via the values argument.

Accessing Data #

The first argument to the script function is the context object, which contains values. This object holds the merged data from:

  1. Attributes passed to the component instance (props)
  2. Data returned from the setup function

Accessing DOM Elements (Refs) #

Coralite provides a refs helper to easily select elements within your component instance. Add the ref="name" attribute to any HTML element in your template, and access it using refs('name') in your script.

HTML
Code copied!
<template id="my-counter">
  

  <button type="button" ref="btn">Count is {{ start }}</button>
</template>

<script type="module">  
  import { defineComponent } from 'coralite'
  
  export default defineComponent({
    client: {
      script: ({ values, helpers }) => {
        const button = helpers.refs('btn')
        // Access the 'start' attribute directly from values
        let count = parseInt(values.start) || 0
  
        button.textContent = `Count is ${count}`
  
        button.addEventListener('click', () => {
          count++
          button.textContent = `Count is ${count}`
        })
      }
    }
  })
</script>

Using External Libraries #

Because the client-side script is isolated, you cannot use static import statements for client-side dependencies directly within the script function body. Instead, you can define them inside the imports array in the client object to bundle them at build-time.

javascript
Code copied!
  export default defineComponent({
    client: {
      // Statically declare imports at build time
      imports: [
        {
          specifier: 'https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.module.mjs',
          defaultExport: 'confetti'
        }
      ],
      // The configured imports become available on the helpers object
      script: ({ values, helpers }) => {
        const button = helpers.refs('celebrate-btn')
        button.addEventListener('click', () => {
          helpers.imports.confetti()
        })
      }
    }
  })

Defining imports within the client object tells Coralite to bundle them. The default, namespace, or named exports you configure will be available within the helpers.imports object.

Import Capabilities & Structure #

The client.imports configuration works identically in both dynamic components (via defineComponent) and plugins (via createPlugin). Coralite's Script Manager supports a wide variety of import patterns:

Start Building with Coralite!

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