CDN Development Guide
Building with Callaloo via CDN offers a rapid, no-build development experience. This guide outlines best practices and architectural patterns to keep your "no-build" applications clean, maintainable, and robust.
Architectural Patterns
Template Decoupling
Keep your HTML clean by separating Vue templates into their own <template> tags. This allows your JavaScript to focus on logic and state management while your HTML handles the structure.
<!-- index.html -->
<div id="app"></div>
<template id="app-template">
<cl-card>
<cl-text>Hello from the template!</cl-text>
</cl-card>
</template>
<script>
const App = {
template: '#app-template',
setup() {
/* ... */
}
};
</script>The Provider Wrapper
Even in a CDN setup, you should wrap your core application in a Root component that provides global services like theming and toast notifications. This ensures these services are available throughout your app via Vue's Provide/Inject mechanism.
const Root = {
template: `
<cl-theme-provider>
<cl-toast-provider>
<app />
</cl-toast-provider>
</cl-theme-provider>
`,
components: { app: App }
};
const app = Vue.createApp(Root);Working with Global Globals
Accessing Callaloo Exports
In a CDN environment, everything is available on the window.Callaloo object. This includes components, composables, and constants.
const { CLButton, CLColors, CLIconNames, useToast } = window.Callaloo;Global vs. Local Registration
Callaloo provides a default export that registers all components globally. This is convenient for CDN usage:
const app = Vue.createApp(Root);
app.use(window.Callaloo.default);
app.mount('#app');Styling Strategies
Hybrid Layouts
While Callaloo handles UI primitives (buttons, inputs, etc.), you can combine it with TailwindCSS for macro-layout (grid, flexbox, spacing) and responsive design.
<header class="flex items-center justify-between p-4 bg-white border-b">
<cl-heading :type="CLHeadingTypes.XL">Dashboard</cl-heading>
<cl-button :variant="CLColorVariants.Ghost">Profile</cl-button>
</header>Prefer Parent Wrappers for Layout
Avoid applying structural or layout-related utility classes (like w-full, mt-4, flex-1) directly to Callaloo components. Instead, wrap the component in a parent element (e.g., a div) and apply the layout classes to that wrapper. This keeps the component's internal styles clean and prevents layout logic from interfering with the component's intended visual structure.
<!-- Avoid this -->
<cl-button class="w-full mt-4">Submit</cl-button>
<!-- Prefer this -->
<div class="w-full mt-4">
<cl-button>Submit</cl-button>
</div>Using Callaloo Constants
Always use the provided constants (CLColors, CLSizes, CLIconNames, etc.) to ensure consistency with the Callaloo design system. These are accessible from the window.Callaloo object.
Interaction Best Practices
State-Driven UI
Control complex components like Drawers, Modals, and Accordions using simple Vue ref or reactive state.
const isDrawerOpen = Vue.ref(false);
const openDrawer = () => (isDrawerOpen.value = true);
const closeDrawer = () => (isDrawerOpen.value = false);Composable Usage
Callaloo composables like useToast work seamlessly in CDN environments as long as they are called within a cl-toast-provider.
setup() {
const { showToast } = useToast();
// ...
}Third-Party Integration
When integrating third-party libraries (e.g., ApexCharts, Leaflet), initialize them inside the onMounted lifecycle hook to ensure the DOM is ready.
onMounted(() => {
const chartElement = document.getElementById('my-chart');
if (chartElement && window.ApexCharts) {
new ApexCharts(chartElement, options).render();
}
});Accessibility
Building with a CDN doesn't excuse a lack of accessibility. Callaloo components are built with accessibility in mind, but you should still follow general web accessibility standards:
- Use semantic HTML (
<main>,<nav>,<header>). - Provide
aria-labelfor buttons that only contain icons. - Use skip links for keyboard-heavy interfaces.