• Stars
    star
    145
  • Rank 254,144 (Top 6 %)
  • Language
    TypeScript
  • Created almost 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Vite support for Handlebars

vite-plugin-handlebars

Vite support for Handlebars

Why?

I really like Vite as a simple static site bundler. It can handle bundling multiple HTML files, which is great, but lacks the ability out-of-the-box to share parts of those HTML files.

While a JS framework like React or Vue could be used to solve this problem, this is heavy-handed for a simple site that could be completely pre-rendered without a JS run-time of any kind.

Handlebars provides what we need to be able to stitch together multiple HTML files, interpolate variables, etc.

Installation

Start by installing the package like you would any other

yarn add -D vite-plugin-handlebars

It can then be added to your Vite configuration as a plugin:

// vite.config.js
import handlebars from 'vite-plugin-handlebars';

export default {
  plugins: [handlebars()],
};

Configuring the plugin is covered later in this guide.

Requirements

  • This plugin is intended to work with Vite 2
  • This plugin requires Node 14 or higher (due to usage of fs/promises)

Configuration

Defining Context

If you want to make use of Handlebars Context to inject variables into your HTML file, you'll need to define their values in the context object passed to the handlebars plugin:

<!-- index.html -->
<h1>{{title}}</h1>
// vite.config.js
import handlebars from 'vite-plugin-handlebars';

export default {
  plugins: [
    handlebars({
      context: {
        title: 'Hello, world!',
      },
    }),
  ],
};

This will result in <h1>Hello, world!</h1> in your output HTML file.

You can also provide a (asynchronous) function, either as the context key or any of the keys within the object, which will be evaluated to create the value that will be made available inside your page. This function is called with an identifier parameter based on the HTML file path which makes it possible to provide unique data to each HTML page in a multipage application setup.

// vite.config.js
import handlebars from 'vite-plugin-handlebars';

const pageData = {
  '/index.html': {
    title: 'Main Page',
  },
  '/nested/subpage.html': {
    title: 'Sub Page',
  },
};

export default {
  plugins: [
    handlebars({
      context(pagePath) {
        return pageData[pagePath];
      },
    }),
  ],
};

Partials

If you want to make use of partials in your HTML files, you must define the partialDirectory option for the handlebars plugin.

// vite.config.js
import { resolve } from 'path';
import handlebars from 'vite-plugin-handlebars';

export default {
  plugins: [
    handlebars({
      partialDirectory: resolve(__dirname, 'partials'),
    }),
  ],
};

If you want to use multiple partial folders, an array can be submitted.

Each file in these directories (.html or .hbs) will become registered as a partial. The name of the file is used to invoke it. So, with the above configuration and the following files:

<!-- partials/header.hbs -->
<header><a href="/">My Website</a></header>
<!-- index.html -->
{{> header }}

<h1>The Main Page</h1>

Your output website content would become:

<header><a href="/">My Website</a></header>

<h1>The Main Page</h1>

Make sure to review the quirks section for information on potentially-unexpected behavior.

Helpers

Custom helpers can be registered using the helpers configuration option:

// vite.config.js
import { resolve } from 'path';
import handlebars from 'vite-plugin-handlebars';

export default {
  plugins: [
    handlebars({
      helpers: {
        capitalize: (value) => value.toUpperCase(),
      },
    }),
  ],
};

For more information on helpers, see the Handlebars documentation.

Other Handlebars Options

All other Handlebars configuration options can also be passed through.

Each of these can also be passed through to the handlebars plugin:

// vite.config.js
import handlebars from 'vite-plugin-handlebars';

export default {
  plugins: [
    handlebars({
      compileOptions: {
        // Example config option: avoid auto-indenting partials
        preventIndent: true,
      },
      runtimeOptions: {
        // Example config option: define custom private @variables
        data: {
          foo: 'bar',
        },
      },
    }),
  ],
};

Disabling Browser Refresh on Partial Change

By default, any time a partial changes, your browser window will be full reloaded. If you want to disable this behavior, you can set reloadOnPartialChange to false:

// vite.config.js
import handlebars from 'vite-plugin-handlebars';

export default {
  plugins: [
    handlebars({
      reloadOnPartialChange: false,
    }),
  ],
};

Built-In Helpers

resolve-from-root

You can resolve a file path relative to the Vite root using the resolve-from-root helper. This assists with injecting other files, like linking to a CSS file, within a partial.

<!-- partials/head.hbs -->
<link rel="stylesheet" href="{{resolve-from-root 'css/global.css'}}" />

Quirks

  • Assets included in a partial using a relative path will probably not work how you would first expect; the relative path is left alone, making it relative to the output file, not the partial itself. It's recommended that you use the resolve-from-root helper to ensure paths are resolved from the project root, rather than relative to a particular file.

More Repositories

1

ember-steps

Declaratively create wizards, tabbed UIs, and more
JavaScript
89
star
2

alfred-switch-audio-source

Alfred workflow to switch audio device
Python
85
star
3

dotfiles

My Neovim, ZSH, Tmux and dev tools setup, with installation scipts
Lua
82
star
4

tldr-alfred

Alfred workflow for TLDR
JavaScript
78
star
5

yaml-merge

A super simple tool for merging YAML files
JavaScript
50
star
6

ember-react-components

Render React components in Ember
JavaScript
47
star
7

Do_Things

An Alfred Workflow for Interacting with Things.app
30
star
8

ember-cli-stencil

Automatic discovery of Stencil.js components for your Ember application
JavaScript
27
star
9

use-task

A React hook for running and cancelling asynchronous tasks
TypeScript
25
star
10

ember-context

Consume values from elsewhere in your Ember application
JavaScript
20
star
11

ripgrep-js

A Node.js wrapper around ripgrep
TypeScript
18
star
12

tree-sitter-glimmer

A TreeSitter grammar for Glimmer (HBS) templates
C
17
star
13

ember-emotion

Use emotion styling in Ember.js
JavaScript
16
star
14

postcss-retina-bg-img

Automatically add retina background images
JavaScript
12
star
15

ember-esbuild

Ember tooling for ESBuild
JavaScript
12
star
16

qunit-wait-for

Wait for a QUnit Assertion
TypeScript
11
star
17

actions-ember-testing

GitHub Action for running Ember Tests
Dockerfile
11
star
18

ember-provider

JavaScript
10
star
19

vim-ember-cli

Vim Plugin for the Ember CLI
Vim Script
10
star
20

ember-rx

RxJS 6 integration for Ember.js
JavaScript
9
star
21

alfred-go-links

Open and bookmark go/ links through Alfred
Ruby
8
star
22

ember-cli-polyfill-io

Ember CLI addon for including polyfill.io in your Ember application
JavaScript
8
star
23

ember-resize-observer-modifier

Use ResizeObserver through an Ember Modifier
JavaScript
8
star
24

ember-intersection-observer-modifier

Use IntersectionObserver through an Ember Modifier
JavaScript
7
star
25

courier

Quick coding environments in VSCode, based on Parcel
TypeScript
6
star
26

ember-stream-helper

Base class for creating helpers that emit values over time
JavaScript
6
star
27

ember-concurrency-wrap-in-task

Ember helper for wrapping a function in an ember-concurrency task
JavaScript
5
star
28

ember-mutation-observer-modifier

Use MutationObserver through an Ember Modifier
JavaScript
5
star
29

ember-wc-utils

Utilities for working with WebComponents in Ember
JavaScript
5
star
30

d_ui

Terminal rendering for Deno
TypeScript
4
star
31

ember-superstatic

Ember.js + Superstatic
JavaScript
4
star
32

ember-unused-component-detector

Locate components that are never used
TypeScript
4
star
33

embroider-vite

Vite Packager for Embroider
JavaScript
4
star
34

peep

Ember CLI plugin for Phoenix
Elixir
3
star
35

ember-ionicons

JavaScript
3
star
36

ember-drafts

Manage draft state for objects
JavaScript
2
star
37

file-fixture-factory

Declaratively create real file system fixtures in Node.js
TypeScript
2
star
38

ember-mixinify-class

Turn an ES6 class into an Ember Mixin
JavaScript
2
star
39

ember-hash-params

Setting/getting params in browser hash
JavaScript
2
star
40

service-locator

Generic Service Locator pattern implementation for ES6
JavaScript
2
star
41

ember-iframe-resizer-modifier

Ember modifier for iframe-resizer
JavaScript
2
star
42

codenames

An implementation of the Codenames card game, in the browser
TypeScript
2
star
43

ember-data-example--nested-resources

An example Ember app with nested API Endpoints for Ember Data usage
JavaScript
2
star
44

language-handlebars

Handlebars support for the Atom editor
CoffeeScript
1
star
45

madlibs

A tiny library for creating partial functions
TypeScript
1
star
46

eslint-config

My personal ESLint config
JavaScript
1
star
47

skatejs-examples

Examples of using Skate.js
JavaScript
1
star
48

dotty

Script system configuration in Node.js
JavaScript
1
star
49

___gatsby-dynamic-routing-bug

Demonstrate bug in Gatsby dynamic routing
CSS
1
star
50

middleman-ember-starter

A Middleman Template for getting started with Ember and Bower
Ruby
1
star
51

ember-runtime-config

Configure an Ember application with server-side environment variables
JavaScript
1
star
52

stylelint-plugin-css-modules

A stylelint plugin for CSS Modules
JavaScript
1
star
53

testdouble-qunit

Verify testdouble stubs with QUnit
TypeScript
1
star
54

demo-ts-esm

A demo of TypeScript and Native ESM
TypeScript
1
star
55

alexlafroscia.com

My Personal Website
TypeScript
1
star
56

broccoli-flow

JavaScript
1
star
57

svg-jar-finder

Locate icons used with `ember-svg-jar`
JavaScript
1
star
58

json-api-formatter

Golang structs -> JSON:API formatted JSON
Go
1
star
59

OpenInTweetbot

A Google Chrome extension for opening Twitter pages in Tweetbot
JavaScript
1
star
60

eventual-result

A `Result` and `Option` implementation that works with `Promise`
TypeScript
1
star
61

redux-transform-stream

A TransformStream for Redux
TypeScript
1
star
62

ember-moveable

JavaScript
1
star
63

giteasy

GitHub, made easy.
JavaScript
1
star