Our Work
See some of our best, most challenging projects.
See some of our best, most challenging projects.
We have 10+ years of Craft CMS development experience.
One of our popular blog posts comparing Craft and WordPress.
We love to work with maps. Learn more about Mapbox in this post.
Vue.js really shines in single-page webapps and webpages that are rendered mostly on the client-side. When there's little interaction with the server, or if server interactions can happen asynchronously, you shouldn't run into too many problems with using Vue.js for your forms. However, sometimes you'll need to load a dynamic form already populated with data from the server.
An example of the former is an empty contact form: none of the inputs have values (which come from the server) in them when the page first loads. An example of the latter is an account edit form: it has to get the user's data from the server and populate the form's fields with that data from the start so that the user can edit it. That's where the roadblock lies.
To quote the docs:
v-model
will ignore the initialvalue
,checked
orselected
attributes found on any form elements. It will always treat the current active instance data as the source of truth. You should declare the initial value on the JavaScript side, inside thedata
option of your component.
That means that any data that's already in the form input components on page load (server-side rendered) gets completely ignored by Vue. That firstName
field's value, fetched by your CMS? (Our CMS of choice is currently Craft CMS, for reference) Non-existent in the eyes of Vue. The user's communications preferences checkboxes, also gone. It's very hard to have an "edit account" form when you can't access the user's account information in order to edit it.
There are a few options, and none of them are great.
mounted
and feed those values to your component's data
object.data
property, and the possibility for error in that process increases with each field.data
attributes on the elements themselves, fetch them during the component's mounted
event, and update the component's props with their values.We prefer to go with Option 2, since it's the most straightforward approach.
Sure! Here's a simplified form, with data attributes that hold the input fields' values that are fetched from the server. A couple of notes here:
{{ }}
) as their delimiters. For that reason, we pass Vue a delimiters
parameter to tell Vue to ignore its standard double curly braces and instead use a different delimiter.<div id="accountForm">
<form method="post" accept-charset="UTF-8">
<label>Field One</label>
<input type="text" name="fields[fieldOne]" id="fieldOne" data-value="{{ currentUser.fieldOne }}" v-model="fieldOne">
<label>Field Two</label>
<input type="text" name="fields[fieldTwo]" id="fieldTwo" data-value="{{ currentUser.fieldTwo }}" v-model="fieldTwo">
<label>Field Three</label>
<input type="text" name="fields[fieldThree]" id="fieldThree" data-value="{{ currentUser.fieldThree }}" v-model="fieldThree">
</form>
</div>
import { createApp } from 'vue/dist/vue.esm-bundler.js';
var accountFormApp = createApp({
delimiters: ['${', '}'],
data() {
return {
fieldOne: '',
fieldTwo: '',
fieldThree: ''
}
},
mounted() {
this.fieldOne = document.getElementById('fieldOne').getAttribute('data-value');
this.fieldTwo = document.getElementById('fieldTwo').getAttribute('data-value');
this.fieldThree = document.getElementById('fieldThree').getAttribute('data-value');
}
});
accountFormApp.mount('#accountForm');
Tl;dr: you can't get a form input's default value to be used by v-model
if that value was fetched from the server on page load. You can put that value in a data attribute and add it to your component's data object, instead. It's a surprising limitation, but once you're aware of it and know your options, it's not difficult to work around.
Shopify's Dawn theme homepage may get an SEO warning for an empty h1 header element. This is a missed opportunity to help search engines understand what your page is about. Small edits to the theme code can fix this technical SEO issue.
Shopify's default Dawn theme displays empty alt tags for collection images. This post explains how to fix blank alt tags for Shopify collection images to improve your Shopify store's accessibility and SEO.
Feastables, from YouTube star MrBeast, is a food brand making and selling "MrBeast Bars" through a fun Shopify store. Customers buy bars to enjoy really good chocolate and get chances to win prizes.