The hapi ecosystem provides a large amount of plugins and they extend the default framework’s functionality. One of these plugins is vision
, which adds template rendering support for engines like handlebars.
Enhancing your web views with a client-side framework is common these days. When choosing Vue.js and handlebars for your hapi based project, you might run into trouble with your templates, because both —Vue.js and handlebars— use a mustache style {{ }}
template syntax.
This tutorial shows you how to combine handlebars and Vue.js within your hapi app.
hapi Series Overview
- What You’ll Build
- Prepare Your Project: Stack & Structure
- Environment Variables and Storing Secrets
- Set Up MongoDB and Connect With Mongoose
- Sending Emails in Node.js
- Load the User’s Profile Picture From Gravatar Using Virtuals in Mongoose
- Implement a User Profile Editing Screen
- Generate a Username in Mongoose Middleware
- Displaying Seasons and Episodes for TV Shows with Mongoose Relationship Population
- Implementing Pagination for Movies
- Implement a Watchlist
- Create a Full Text Search with MongoDB
- Create a REST API with JSON Endpoints
- Update Mongoose Models for JSON Responses
- API Pagination for TV Shows
- Customize API Endpoints with Query Parameters
- Always Throw and Handle API Validation Errors
- Advanced API Validation With Custom Errors
- Create an API Documentation with Swagger
- Customize Your Swagger API Documentation URL
- Describe Endpoint Details in Your Swagger API Documentation
- 10 Tips on API Testing With Postman
- JWT Authentication in Swagger API Documentation
- API Versioning with Request Headers
- API Login With Username and Password to Generate a JWT
- JWT Authentication and Private API Endpoints
- Refresh Tokens With JWT Authentication
- Create a JWT Utility
- JWT Refresh Token for Multiple Devices
- Check Refresh Token in Authentication Strategy
- Rate Limit Your Refresh Token API Endpoint
- How to Revoke a JWT
- Invalidate JWTs With Blacklists
- JWT Logout (Part 1/2)
- JWT “Immediate” Logout (Part 2/2)
- A Better Place to Invalidate Tokens
- How to Switch the JWT Signing Algorithm
- Roll Your Own Refresh Token Authentication Scheme
- JWT Claims 101
- Use JWT With Asymmetric Signatures (RS256 & Co.)
- Encrypt the JWT Payload (The Simple Way)
- Increase JWT Security Beyond the Signature
- Unsigned JSON Web Tokens (Unsecured JWS)
- JWK and JWKS Overview
- Provide a JWKS API Endpoint
- Create a JWK from a Shared Secret
- JWT Verification via JWKS API Endpoint
- What is JOSE in JWT
- Encrypt a JWT (the JWE Way)
- Authenticate Encrypted JWTs (JWE)
- Encrypted and Signed JWT (Nested JWT)
- Bringing Back JWT Decoding and Authentication
- Bringing Back JWT Claims in the JWT Payload
- Basic Authentication With Username and Password
- Authentication and Remember Me Using Cookies
- How to Set a Default Authentication Strategy
- Define Multiple Authentication Strategies for a Route
- Restrict User Access With Scopes
- Show „Insufficient Scope“ View for Routes With Restricted Access
- Access Restriction With Dynamic and Advanced Scopes
- hapi - How to Fix „unknown authentication strategy“
- Authenticate with GitHub And Remember the Login
- Authenticate with GitLab And Remember the User
- How to Combine Bell With Another Authentication Strategy
- Custom OAuth Bell Strategy to Connect With any Server
- Redirect to Previous Page After Login
- How to Implement a Complete Sign Up Flow With Email and Password
- How to Implement a Complete Login Flow
- Implement a Password-Reset Flow
- Views in hapi 9 (and above)
- How to Render and Reply Views
- How to Reply and Render Pug Views (Using Pug 2.0)
- How to Create a Dynamic Handlebars Layout Template
- Create and Use Handlebars Partial Views
- Create and Use Custom Handlebars Helpers
- Specify a Different Handlebars Layout for a Specific View
- How to Create Jade-Like Layout Blocks in Handlebars
- Use Vue.js Mustache Tags in Handlebars Templates
- How to Use Multiple Handlebars Layouts
- How to Access and Handle Request Payload
- Access Request Headers
- How to Manage Cookies and HTTP States Across Requests
- Detect and Get the Client IP Address
- How to Upload Files
- Quick Access to Logged In User in Route Handlers
- How to Fix “handler method did not return a value, a promise, or throw an error”
- How to Fix “X must return an error, a takeover response, or a continue signal”
- Query Parameter Validation With Joi
- Path Parameter Validation With Joi
- Request Payload Validation With Joi
- Validate Query and Path Parameters, Payload and Headers All at Once on Your Routes
- Validate Request Headers With Joi
- Reply Custom View for Failed Validations
- Handle Failed Validations and Show Errors Details at Inputs
- How to Fix AssertionError, Cannot validate HEAD or GET requests
The Problem
Vue.js and handlebars use a template syntax that’s based on mustache style brackets: {{ template }}
. When rendering views on server side with hapi and handlebars, all syntax templates will be compiled and Vue.js won’t be able to pick up the related tags, because they’re already gone due to handlebars’ compilation process.
Let’s illustrate the problem with a simple example: you’ve a form input field that binds to a Vue.js model. The typed text should be displayed below the input as a preview.
The markup may look like this:
<div class="vue">
<form>
<fieldset>
<label for="name">Name</label>
<input type="text" id="name" v-model="name">
</fieldset>
</form>
<p>
Name is: {{ name }}
</p>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
new Vue({
el: '.vue',
data: {
name: ''
}
})
</script>
The input
field has a v-model="name"
attribute which connects to Vue’s data.name
property.
Below the form, there’s a {{ name }}
tag that should display the user input. When rendering this template with reply.view('template')
in hapi, the {{ name }}
tag won’t be available, because handlebars compiles this tag already and sends the HTML to the client. Vue.js won’t be able to pick up the tag anymore, it’s already gone (due to handlebars).
Escape Handlebars Syntax Templates That Should Be Picked Up by Vue.js
Related to the code snippet above, you want handlebars to ignore the {{ name }}
tag and let Vue.js associate with it. To combine handlebars and Vue.js syntax templates, you need to escape the templates that Vue.js should pick up.
before
<p>
Name is: {{ name }}
</p>
after
<p>
Name is: \{{ name }}
</p>
All syntax templates prefixed with a backslash will be ignored by handlebars and left within the template. Vue.js is now able to connect with those tags and implement its reactivity.
This way you can control which templates should be rendered with handlebars and left out for Vue.js
Outlook
Within this tutorial you’ve learned how to combine the handlebars rendering process and also using Vue.js as a frontend framework.
Even though both tools use mustache style brackets for the templating, make sure to escape the ones that handlebars should leave for Vue.js and the rendering chain (handlebars first, Vue.js second) will work for you.
We’re happy to hear your thoughts and comments. Please don’t hesitate to use the comments below or find us on Twitter @futurestud_io. Let us know what you think!
Enjoy coding & make it rock!