Watch our biggest AI launch event

Announcing Visual Copilot - Figma to production in half the time

Builder.io logo
Contact Sales
Platform
Developers
Contact Sales

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

The Builder Visual Editor helps you add event handlers, bind to state, and even add custom JavaScript that runs on your page.

Tip: To add custom HTML to your Page or Section, use the Custom Code Block rather than custom JavaScript.

In Builder, you can bind state values to Builder blocks and implement custom actions when users interact with your content.

For detailed instructions on incorporating state bindings or action handlers, visit Building Interactivity Using State and Actions.

When adding custom JavaScript code within a state binding or action handler, remember that you don't need to use the return keyword to yield a value. Instead, choose from these four examples:

For straightforward, one-line expressions, you can write code directly in the code editor without the return statement:

state.showWelcomeMessage ? 'Say Hello' : 'Say Goodbye'

For more intricate logic, export a default value:

let greeting;
if (justLoggedIn) {
  value = 'Welcome';
} else {
  value = 'hi';
}
export default greeting;

You can access Builder state in both state bindings and action handlers. While state bindings are typically closely bound to Builder, you can also modify the state value within the binding. For example:

// use the plain value from state
state.someStringValue

// uppercase the state value
state.someStringValue.toUpperCase()

// return a different value depending on state property
state.someBooleanValue ? 'yes' : 'no

Action handlers introduce an additional object you can access: event.

This event object represents the HTML event triggered by the selected action. You can leverage event to access the event's target element or invoke methods such as preventDefault or stopPropagation:

// access the value attribute (ie from an input)
// and store it in builder state
state.someStateProp = event.currentTarget.value;

// if you have a link with an href, you might want to stop
// default browser navigation and handle this yourself
event.preventDefault();
var targetElementId = event.currentTarget.id;
var elementToScrollTo = document.getElementById(targetElementId);
elementToScrollTo.scrollIntoView({ behavior: 'smooth' });

To add custom styles or JavaScript to your content:

  1. In the content entry, go to the Data tab.
  2. Expand the Code section.
  3. Click the Edit Custom JS + CSS button.
  4. In the window that opens, you can put your CSS on the left and your JavaScript on the right.

This example shows adding some custom CSS to a Page and then applying it to elements on the Page.

The CSS in below—which the video features–applies a margin and blue color to links (the a tag), and a yellow background color to any element with .my-class:

/* Style all link elements */
a {
     margin: 10px;
     color: blue;
}

/* Style all elements with the class name "my-class" */
.my-class {
	background-color: yellow;
}

To use the CSS, add the code to the Custom Code editor and then apply the styles either by applying a class to an element or creating elements that would naturally inherit those styles.

The following video shows how to add custom CSS and apply it to elements. A written explanation follows the video.

Any element that has the .my-class applied inherits the .my-class styles as soon as .my-class is applied to that element. In this example, when the Box is given the class .my-class, its background immediately turns yellow.

Any elements that are styled directly in the CSS, such as links in this example, are styled automatically. This happens in the video as soon as the copy becomes a link.

You can run JS client side as well as server side using Builder.isBrowser and Builder.isServer. By default, any code not wrapped with Builder.isBrowser or Builder.isServer is run on Builder's servers.

To run code client-side, wrap it in if (Builder.isBrowser) {}.

For example, suppose you're rendering your Builder content lazily on the client and you want to support linking directly to certain sections of a page based on the ID attribute of the section. You could do this with some custom JavaScript:

if (Builder.isBrowser) {
    const el = location.hash &&
      document.getElementById(location.hash.slice(1))

    el.scrollIntoView({ behavior: 'smooth' });
}

You also have access to fetch() on the client and server. For server side data, you can export a default promise that resolves with the necessary data before responding:

async function main() {
  if (Builder.isServer) {
    // Place any code here you want to only run on 
    // the server. Any  data fetched on the server 
    // will be available to re-hydrate on the client
    // if added to the state object
    await fetch(someUrl)
      .then(res => res.json())
      .then(data => {
        // set the data on the state object so 
        // you can access it from your components
        state.someData = data;
     });
  }
  if (Builder.isBrowser) {
    // Place code that you only want to run 
    // in the browser (client-side only) here
    // For example, anything that uses 
    // document/window access or DOM manipulation
  }
}

export default main();

In the provided example, data fetched on the server is stored on the state object and can be accessed as data bindings in both the server and client UIs. For more details on fetching and using data, refer to Dynamic Preview URLs.

Remember to exercise caution and consider the impact on performance and security when adding custom code to your site. For instance, when incorporating custom event listeners, ensure the use of passive events for proper handling.

When adding your custom JavaScript code, the useful builder values include:

  • Builder.isServer: Use to determine if the code is running on the server-side (such as in a Node.js environment) or not. It returns true if the code is executing on the server, and false if it's running in a browser.
  • Builder.isBrowser: Use to check if the code is running in a browser environment. It returns true if the code is executing in a web browser, and false otherwise, including server-side.
  • Builder.isPreviewing: Use to check if the code is currently in preview mode within the Visual Editor. It returns true if the code is being previewed in the Visual Editor, and false if it's not in preview mode.
  • Builder.isEditing: Use to check if the code is currently being edited within the Builder.io editor. It returns true if the code is being edited, and false if it's not being edited.

For the source code, visit GitHub.

Tip: If your custom code isn't delivering expected results when working with page elements or third-party scripts, the event loop's asynchronous nature might be the reason. Consider using setTimeout() or conditional checks to time your code accurately and synchronize it with the page's rendering process.

For more information on the global objects available, visit:

Up next

3rd party libraries

Was this article helpful?

Product

Visual CMS

Theme Studio for Shopify

Sign up

Login

Featured Integrations

React

Angular

Next.js

Gatsby

Get In Touch

Chat With Us

Twitter

Linkedin

Careers

© 2020 Builder.io, Inc.

Security

Privacy Policy

Terms of Service

Newsletter

Get the latest from Builder.io

By submitting, you agree to our Privacy Policy

Product

Platform Overview

Integrations

What's New

Open Source

Builder

Builder

Mitosis

Mitosis

Qwik

Qwik

Partytown

Partytown

Popular Guides

From Design to Code Guide

Composable Commerce Guide

Headless CMS Guide

Headless Commerce Guide

Composable DXP Guide

Design to Code

Resources

Blog

Knowledge Base

Community Forum

Partners

Templates

Success Stories

Showcase

Resource Center

Frameworks

React

React

Next

Next.js

Qwik

Qwik

Gatsby

Gatsby

Angular

Angular

Vue

Vue

Svelte

Svelte

Remix logo

Remix

Nuxt

Nuxt

Hydrogen

Hydrogen

See All

© 2024 Builder.io, Inc.

Security

Privacy Policy

SaaS Terms

Security & Compliance

Cookie Preferences