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.
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.
- Async Support:
setupis async, allowing you toawaitdata before rendering. - Data Flow: The object returned by
setupis merged into the component'svaluescontext. - Usage: These values are available to the template (e.g.,
{{ remoteData }}), slots, tokens, and the client-sidescript.
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:
- Attributes passed to the component instance (props)
- Data returned from the
setupfunction
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.
<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.
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.