Skip to content

Getting Started

Installation

1. Install via Composer

First, install the addon via Composer:

bash
composer require weloveyou/statamic-theme-extensions

This installs both the Statamic addon and makes the npm package available in the addon's vendor folder. The npm package and PHP backend are versioned together to ensure compatibility.

2. Install npm Package

Navigate to your theme folder and install the npm package:

bash
npm install vendor/weloveyou/statamic-theme-extensions

Requirements:

  • Node.js >= 20
  • npm >= 10

Troubleshooting Node Modules

If you encounter issues with node modules or dependency conflicts, reset your node_modules:

bash
rm package-lock.json
rm -rf node_modules
npm install

This ensures a clean installation of all dependencies.

Script Placement

For optimal performance, place your script tag in the <head> section:

html
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Your Site</title>

    <script type="module" src="/path/to/your-app.js"></script>
</head>

Why in the head?

  • Script downloads start immediately (parallel with HTML parsing)
  • Faster time-to-interactive for your application
  • Module scripts are automatically deferred and won't block rendering

How Module Scripts Work

Scripts with type="module" have special loading behavior:

  • Automatically deferred: Module scripts never block HTML parsing, even when placed in <head>
  • Execute after DOM is ready: They run when the document reaches 'interactive' state (DOM fully parsed)
  • Guaranteed execution order: Multiple module scripts always execute in document order, regardless of which downloads first
  • No defer attribute needed: Module scripts are deferred by default

This means you can safely place module scripts in <head> for optimal performance without worrying about blocking page rendering or DOM availability.

Basic Usage

Initialize the theme extensions by calling RunThemeExtensions with your configuration. Each extension is optional and only loads when explicitly configured:

ts
import { RunThemeExtensions } from 'wly-statamic-theme-extensions';
import { registerComponents } from '@/vue/components';
import type { App } from 'vue';

RunThemeExtensions({
    // Vue.js integration
    vue: {
        onBootstrap: (app: App<Element>) => {
            registerComponents(app);
        },
        i18n: {
            // i18n configuration
        },
    },

    // Alpine.js integration
    alpine: {
        enableLivewire: true,
        components: {
            // Custom Alpine components
        },
    },

    // Isotope layout engine
    isotope: {
        // Isotope configuration
    },

    // Mmenu.js mobile navigation (v9)
    menu: {
        options: {
            theme: 'light',
            slidingSubmenus: true,
        },
        configurations: {
            offCanvas: {
                page: {
                    selector: '#page',
                },
            },
        },
    },

    // Auto-initialization tools (Lazysizes, Autosize)
    tools: {
        // Tools configuration
    },
});

Each extension has dedicated documentation pages with detailed configuration options. Visit the respective sections in the documentation to learn more.

DOM Ready State

RunThemeExtensions automatically wraps all extensions in an onReady callback with the default 'interactive' state. This means all extensions and plugins will execute after the DOM is fully parsed, even though module scripts already provide this guarantee.

Custom Plugins

The plugins property allows you to hook custom initialization functions into the theme extensions lifecycle. This is useful for integrating external libraries or adding custom initialization logic.

Example:

ts
import { RunThemeExtensions } from 'wly-statamic-theme-extensions';
import { VideoEmbedder } from 'some-video-package';

RunThemeExtensions({
    plugins: [
        VideoEmbedder,
        () => console.log('Custom initialization'),
        () => initializeAnalytics(),
    ],
    alpine: {
        // ...
    },
});

Plugin Behavior:

  • Plugins are simple functions with signature () => void
  • Execute in the order they're defined
  • Run after the DOM is ready ('interactive' state)
  • Execute before the built-in extensions (vue, alpine, isotope, menu, tools)

This allows plugins to set up dependencies or perform initialization that other extensions may rely on.