The package makes using JavaScript to generate HubSpot module fields.json
files on local development straightforward.
- Requirements
- Why is it needed?
- Installation
- Example fields.js file
- Usage : Field Types
- Usage: Groups
- Usage: Helper Methods
- Advanced Usage
- About iGoMoon
- Contributing
- License
This is a webpack plugin designed to be a companion for (but not dependant on) the Hubspot Webpack Plugin created by our friends at HubSpot (Found here: @hubspot/webpack-cms-plugins).
If you're here, then you probably love HubSpot almost as much as we do, and when creating and maintaining the fields.json
files for modules, they can quickly become long, arduous to read and difficult to update over time. "Fields JS" gives you the ease of working with webpack with your HubSpot modules.
How does it work?
Within your modules, you create a fields.js
file in place of fields.json
and during compilation, the plugin will convert your fields.js
files to fields.json
that can be uploaded to your HubSpot Account. After copying to the dist folder, the plugin will search your "dist" folder for fields.js
and then replace those with transformed fields.json
files.
npm install @igomoon/hubspot-fields-js --save-dev
- Set up a hubspot.config.yml using the HubSpot CMS local development instructions.
- Add the hubspot-fields-js plugin to your webpack.config.js.
-
Options
-
src
: The starting directory to search for field.js files eg. "./src" -
extraDirsToWatch
: an array of relative paths to directories that will trigger a recompilation. Useful for FieldJS partials -
ignore
: An array of relative paths to ignore when searching for field.js files
-
-
Options
Example webpack.config.js
const HubSpotAutoUploadPlugin = require("@hubspot/webpack-cms-plugins/HubSpotAutoUploadPlugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
// STEP 1 : Include the Fields JS Plugin
const { FieldsPlugin } = require("@igomoon/hubspot-fields-js");
module.exports = ({ account, autoupload }) => ({
entry: "./src/index.js",
output: {
filename: "js/main.js",
},
module: {
rules: [
//...
]
},
plugins: [
// STEP 2 : Add to the top of your plugins
new FieldsPlugin({
src: "",
extraDirsToWatch : ["./src/fields"],
ignore: []
}),
new HubSpotAutoUploadPlugin({
autoupload,
account,
src: "dist",
dest: "my-project",
}),
new CopyWebpackPlugin([
{ from: "src/images", to: "images" },
{ from: "src/modules", to: "modules" },
{ from: "src/templates", to: "templates" },
]),
],
});
- Run webpack as normal to compile your project and convert
fields.js
tofields.json
.
Example fields.js
within a module.
const { Field } = require("@igomoon/hubspot-fields-js");
module.exports = [
Field.text()
.name("title","Title")
.default("Text"),
Field.richText()
.name("text","Text")
.default("<p>This is just some placeholder text in a rich text field</p>")
];
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#blog
Field.blog()
.name("blog_field","Blog Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#boolean
Field.boolean()
.name("boolean_field","Boolean Field")
Setting additional options with set
helper method
Field.boolean()
.name("boolean_field","Boolean Field")
.set("display","toggle")
.default(false)
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#choice
Field.choice()
.name("choice_field","Choice Field")
.choices([])
Setting additional options with set
helper method
Field.choice()
.name("choice_field","Choice Field")
.choices([
["choice-1", "Choice 1"]
])
.set("display","select")
.default("choice-1")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#color
Field.color()
.name("color_field","color Field")
.default("#ffffff")
Setting additional options with set
helper method
Field.color()
.name("color_field","color Field")
.set("default",{
"color": "#ffffff",
"opacity": 80
})
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#cta
Field.cta()
.name("cta_field","CTA Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#crm-object
Field.crmObject()
.name("crmobject_field","CRM Object Field")
Setting additional options with set
helper method
Field.crmObject()
.name("crmobject_field","CRM Object Field")
.set("object_type","CONTACT")
.set("properties_to_fetch",[])
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#date
Field.date()
.name("date_field","Date Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#date-and-time
Field.dateTime()
.name("datetime_field","Date and Time Field")
Setting additional options with set
helper method
Field.dateTime()
.name("datetime_field","Date and Time Field")
.set("step",30)
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#email
Field.email()
.name("email_field","Email Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#embed
Field.embed()
.name("embed_field","Embed Field")
Setting additional options with set
helper method
Field.embed()
.name("embed_field","Embed Field")
.set("supported_source_types",[ "oembed", "html" ])
.set("supported_oembed_types",[ [ "photo", "video", "link", "rich" ] ])
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#file
Field.file()
.name("file_field","File Field")
Setting additional options with set
helper method
Field.file()
.name("file_field","File Field")
.set("picker","document")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#followup-email
Field.followUpEmail()
.name("followupemail_field","Followup Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#font
Field.font()
.name("font_field","Font Field")
Setting additional options with set
helper method
Field.font()
.name("font_field","Font Field")
.set("load_external_fonts", true)
.set("default",{
"size": 12,
"font": "Merriweather",
"font_set": "GOOGLE",
"size_unit": "px",
"color": "#000",
"styles": {}
})
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#form
Field.form()
.name("form_field","Form Field")
.default("form_id")
Setting additional options with set
helper method
Field.form()
.name("form_field","Form Field")
.set("default",{
"response_type": "inline",
"message": "Thanks for submitting the form."
})
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#hubdb-row
Field.hubdbRow()
.name("hubdbrow_field","HubDB Row Field")
.set("table_name_or_id","4357464")
.default("row_id")
Setting additional options with set
helper method
Field.hubdbRow()
.name("hubdbrow_field","HubDB Row Field")
.set("table_name_or_id","4357464")
.set("columns_to_fetch",[])
.set("display_columns",[])
.set("display_format","%0 - %1")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#hubdb-table
Field.hubdbTable()
.name("hubdbtable_field","HubDB Table Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#icon
Field.icon()
.name("icon_field","Icon Field")
Setting additional options with set
helper method
Field.icon()
.name("icon_field","Icon Field")
.set("icon_set", "fontawesome-5.14.0")
.set("default",{
"name" : "accessible-icon",
"unicode" : "f368",
"type" : "REGULAR"
})
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#image
Field.image()
.name("image_field","Image Field")
.default("image_field","Image Field")
Setting additional options with set
helper method
Field.icon()
.name("image_field","Image Field")
.set("responsive",true)
.set("resizable",true)
.set("show_loading",false)
.set("default",{
"size_type" : "auto",
"src" : "",
"alt" : null,
"loading": "disabled"
})
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#link
Field.link()
.name("link_field","Link Field")
.default("https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields")
Setting additional options with set
helper method
Field.link()
.name("link_field","Link Field")
.set("supported_types",["EXTERNAL", "CONTENT", "FILE", "EMAIL_ADDRESS", "BLOG"])
.set("default",{
"url" : {
"content_id" : null,
"type" : "EXTERNAL",
"href" : ""
},
"open_in_new_tab" : false,
"no_follow" : false
})
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#logo
Field.logo()
.name("logo_field","Logo Field")
.default("https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields")
Setting additional options with set
helper method
Field.logo()
.name("logo_field","Logo Field")
.set("default",{
"override_inherited_src" : false,
"src" : null,
"alt" : null
})
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#menu
Field.menu()
.name("menu_field","Menu Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#number
Field.number()
.name("number_field","Number Field")
Setting additional options with set
helper method
Field.number()
.name("number_field","Number Field")
.set("display","slider")
.set("step",1)
.set("min",0)
.set("max",100)
.set("prefix","$")
.set("suffix","K")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#page
Field.page()
.name("page_field","Page Field")
Setting additional options with set
helper method
Field.page()
.name("page_field","Page Field")
.set("placeholder","Page to pull from")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#rich-text
Field.richText()
.name("richtext_field","Rich Text Field")
Setting additional options with set
helper method
Field.richText()
.name("richtext_field","Rich Text Field")
.set("enabled_features",["bold","link","image"])
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#simple-menu
Field.simpleMenu()
.name("simplemenu_field","Simple menu Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#tag
Field.tag()
.name("tag_field","Tag Field")
Setting additional options with set
helper method
Field.tag()
.name("tag_field","Tag Field")
.set("tag_value","SLUG")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#text
Field.text()
.name("text_field","Text Field")
Setting additional options with set
helper method
Field.text()
.name("text_field","Text Field")
.set("placeholder","Enter text here")
.set("allow_new_line",false)
.set("show_emoji_picker",false)
.set("validation_regex","")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#url
Field.url()
.name("url_field","URL Field")
Setting additional options with set
helper method
Field.url()
.name("url_field","URL Field")
.set("supported_types",["EXTERNAL", "CONTENT", "FILE", "EMAIL_ADDRESS", "BLOG"])
.set("default",{
"content_id" : null,
"href" : "http://example.com",
"type" : "EXTERNAL"
})
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields#video
Field.video()
.name("video_field","Video Field")
Setting additional options with set
helper method
Field.video()
.name("video_field","Video Field")
.set("default",{
"player_id" : 32173842991,
"height" : 1224,
"width" : 1872,
"conversion_asset" : {
"type" : "CTA",
"id" : "c3e4fa03-2c69-461d-b9af-22b2fde86bc7",
"position" : "POST"
}
})
Field.sfCampaign()
.name("sfdc_campaign","Salesforce Campaign Field")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields-overview#field-groups
You can create a field group (and nested groups) like this:
const { Group, Field } = require("@igomoon/hubspot-fields-js");
new Group()
.name("group", "Group")
.children([
Field.text(),
// Other Fields/Groups
new Group()
.name("sub_content", "SubContent")
.children([
Field.text(),
// Other Fields/Groups
])
])
IMPORTANT: Make sure to pull in the Group
class from the package at the top of you file.
const { Group, Field } = require("@igomoon/hubspot-fields-js");
Looking for Repeating Groups? See the Helper Methods below. https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields-overview#repeating-groups
name(name, label)
Field.text()
.name("field_name","Field Label")
id(id)
Field.text()
.id("321732-3231-3213554-21")
default(value)
Field.text()
.default("value to set")
set(key,value)
Field.text()
.set("placeholder","Placeholder Text")
visibleIf(controllingField, regex, type = "EQUAL")
Sets controlling field options under visibility
Field.text()
.visibleIf("other_field_id","value to test")
Field.text()
.visibleIf("other_field_id","value to test","NOT_EQUAL")
https://developers.hubspot.com/docs/cms/building-blocks/module-theme-fields-overview#repeaters
repeat(overrides = {})
Field.text()
.repeat()
new Group()
.name("group","Group")
.children([])
.repeat()
Override the repeat options like so:
new Group()
.name("group","Group")
.children([])
.repeat({
"min": null,
"max": 5,
"sorting_label_field": 'group.name',
"default": 1
})
helpText(text)
Field.text()
.helpText("Help text")
inlineHelpText(text)
Field.text()
.inlineHelpText("Inline Help Text")
label(value)
Field.text()
.label("Label Value")
required(required = true)
Field.text()
.required()
Field.text()
.required(false)
Hidden Sub Fields
hiddenSubfields(subFields)
Sets hidden_subfields under visibility
Field.text()
.hiddenSubfields({
"font": true,
"size": true
})
locked(locked = true)
Field.text()
.locked()
Field.text()
.locked(false)
For choice Field only
choices(choices = [])
Field.choice()
.choices([])
For Groups Only
children(children = [])
new Group()
.children([])
What's the best feature of all? Hubspot Fields JS allows you to abstract your fields into partials. Giving you the ability to create common fields once and then pull them into any Fields-JS enabled module that you like. Removing the pain of constant duplication and allowing you to make global changes by just changing a sinle partial file.
The example below creates a text field partial with a validation regex for an id attribut, then in 2 different module fields.js file, that partial is pulled in and inserted.
src/fields/cssID.js
const { Field } = require('@igomoon/hubspot-fields-js');
module.exports = function () {
return Field
.text()
.name('css_id', 'CSS ID');
.set("validation_regex","-?[a-zA-Z]+[a-zA-Z0-9-]+")
}
src/modules/example.module/fields.js
const { Field } = require("@igomoon/hubspot-fields-js");
// Pull in the Partial (IMPROTANT: Relative to the modules final destination in the dist folder)
let cssID = require('../../../src/fields/cssID');
module.exports = [
Field.text()
.name("title","Title")
.default("Text"),
// This will insert the CSS ID field for this module
cssID()
];
src/modules/second-example.module/fields.js
const { Group, Field } = require("@igomoon/hubspot-fields-js");
// Pull in the Partial (IMPROTANT: Relative to the modules final destination in the dist folder)
let cssID = require('../../../src/fields/cssID');
module.exports = [
new Group()
.name("group","Group")
.children([
Field.text()
.name("title","Title")
.default("Text"),
Field.richText()
.name("text","Text")
.default("<p>This is just some placeholder text in a rich text field</p>")
])
// This will insert the CSS ID field for this module
cssID()
];
iGoMoon’s mission is to help companies grow through data-driven communication, smart technology and relevant content. We live and breathe HubSpot and being Certified in Advanced CMS Implementation we are constantly improving our development process to better serve our customers.
Get to know us more on our Vlog Månresan (The moonshot journey)
We are always looking for skilled developers at iGoMoon, if you have HubSpot experience then there may be a spot for you here. Think you have what it takes? Then try our HubSpot Developer Coding Task and connect with us on our career page here: https://careers.igomoon.com/connect
For more information on developing, see the Contributing Guide.
Apache 2.0