JavaScript Templates

Using JavaScript files in the templates directory with template directives

JavaScript files placed in the templates/ directory are processed through the Elements template engine, allowing you to inject component properties, conditionals, and dynamic values directly into your JavaScript code. This enables you to create interactive components with configuration driven by user properties.

Overview

JavaScript template files provide:

  • Property insertion - Use component properties in JavaScript code

  • Conditional code - Include or exclude JavaScript based on conditions

  • Per-instance configuration - Each component instance gets its own configuration

  • Portal injection - Place scripts in specific page locations using @portal

File Location

com.yourcompany.component/
├── templates/
│   ├── index.html
│   ├── script.js         # Component JavaScript
│   └── include/
│       └── ...

Basic Usage

JavaScript files can use standard JavaScript syntax along with Elements template directives:

Property Insertion

Insert component properties directly into JavaScript values:

Portal Injection

A common pattern is to use @portal to inject JavaScript into specific page locations, typically bodyEnd:

Then in your HTML template:

See the @portal documentation for more details.

Examples from Core Components

Accordion Component (Alpine.js)

The Accordion uses a portal to define Alpine.js component logic once:

Each accordion instance then uses this component with its own properties:

The Gallery component includes lightbox functionality:

Conditional JavaScript

Use @if directives to conditionally include code:

Processing Behavior

Per-Instance Processing

JavaScript template files are processed once per component instance. Each instance gets its own <script> tag with processed code:

Inline Scripts

Processed JavaScript is inserted inline into the page within <script> tags, not as external files.

Templates vs Assets

Choose the right location for your JavaScript:

Use templates/ JavaScript When:

  • Code needs component property values

  • Code is instance-specific

  • Code needs conditional logic

  • Configuration varies per instance

Example:

Use assets/ JavaScript When:

  • Code is static library code

  • Code is shared across all instances

  • Code is a large framework (Alpine.js, GSAP, etc.)

  • You want better caching and performance

Example:

Combining Both

A common pattern is to define classes in assets/ and instantiate them in templates/:

Best Practices

Use includeOnce for Libraries

When defining reusable functions or classes, use includeOnce:

Avoid Inline Event Handlers

Instead of inline handlers in HTML:

Use proper event listeners in JavaScript:

Escape String Values

Be careful with user-provided strings that might contain quotes:

In hooks.js:

Minimize Template JavaScript

Keep template JavaScript minimal and focused on configuration:

Use Proper Scope

Avoid polluting global scope:

Handle Timing

Ensure DOM is ready before accessing elements:

Common Patterns

Alpine.js Integration

Define Alpine components with property-based configuration:

GSAP Animations

Configure GSAP animations with user properties:

Data Attributes

Set data attributes for JavaScript access:

Limitations

No ES Modules

Template JavaScript doesn't support ES module syntax:

Limited Preprocessing

Template JavaScript files don't support TypeScript, Babel, or other preprocessors. Use the Elements template language for logic.

Execution Context

Template JavaScript runs in the page context, not in a controlled environment. Ensure code is safe and handles errors appropriately.

Last updated

Was this helpful?