Create a website theme with NationBuilder

Creating a custom website theme in NationBuilder is easy to learn, and this HOWTO covers all the essentials on how to get started.

Updated over a week ago

Table of Contents

Create a new theme

You can customize any element of your website and have access to all the objects and variables that make NationBuilder so powerful. NationBuilder extends HTML with the Liquid template language, and extends CSS with SASS. All that means is you can use regular HTML and CSS, but you also get some cool plugins, variables, and logic in both.
To create a custom website theme, sign in to your nation's control panel and click Websites > Theme. This will display thumbnails of all public themes. You can also browse all free public themes in the theme gallery.

Clicking a thumbnail instantly changes the way your website looks. It also reveals several theme style variations for you to choose from which offer different colors combinations, fonts and so on.

To customize your website beyond these choices, you need to create a custom theme. If you want to start with something already a bit polished, select your favorite public theme. What you select will serve as the starting point for your new custom theme. Click New custom theme.

Give your theme a name and leave Clone your current theme and Switch site to your new site immediately selected. Click Create theme.

If you are a designer or developer familiar with the Bootstrap framework, select "Start with Bootstrap framework" to begin with a stripped down theme which uses Bootstrap 4.3. Please refer to the official Bootstrap documentation as you style your new theme. We highly recommend you use our Dropbox integration to edit your theme files.

The theme templates page

When the theme is done cloning, you will land on the templates page of your new custom theme:

Some important files to note are:

  • theme.scss is the mobile first stylesheet which controls the overall look of your website.

  • layout.html wraps every page and includes your header and footer.

  • _content.html wraps the main content area of a page and provides correct classes to html elements for when the sidebar is turned on.

  • splash.html wraps your splash page, if you have one enabled.

Listed below these files are templates for every type of page you can create in NationBuilder. Key points to understand about these templates are:

  • Changes made to a template here will modify every page of that type across your website. For example, modifying pages_show_blog_post.html will modify all blog posts pages. If you wish to modify a template for a specific page only, click Website, select the page you wish to edit, then click Template.

  • Templates ending in _wide.html will be shown when the sidebar is turned off on a page. 

Sync your themes with Dropbox

Connecting Dropbox to your nation allows you to edit and sync website theme files and custom page templates directly on your computer, using your favorite text editor.

Need more help? Learn more by watching the video below or reading our in-depth documentation.

Theme vs. page level editing

Theme level editing: There are two levels of editing your theme - theme level editing and page level editing. Theme level describes editing entire page types across your entire website. Any template edited on the themes template page accessed from Website > Theme is theme level editing.

Example: If you want all Petition pages on your website to look a certain way, edit the file pages_show_petition.html.

Page level editing: Page level editing is when you only want to style one specific page. Select the page you want to edit from Website and then Template. Modifying the template will override the theme level template and only affect this page. The Files page which exists under each page is where you can upload images or assets used for that page only.

Example: You currently have a Petition page with the title "Jobs Bill" you wish to style differently than other petition pages. Click Edit next to the "Jobs Bill" page and then click Template to modify the HTML and Liquid.

The stylesheet

Why is the stylesheet file extension .scss?

The reason the stylesheet file extension ends in .scss (instead of .css) is because NationBuilder uses the SCSS syntax of Sass. Sass is a CSS3 extension which uses mixins, variables and simple logic which allows you to do some amazing things you normally can't do with normal CSS. While you can write CSS like you always have without any problems, learning the basics of Sass can go a long way. Browse tutorials and documentation here to learn more.

Two of the most powerful features of Sass are variables and mixins. Let's take a quick look at how both work:


Sass variables begin with a dollar sign and are followed by a value. Variables allow you to easily produce the same properties throughout your stylesheet.

  $blue: #3bbfce; /* $blue will equal #3bbfce */
  $margin: 16px; /* $margin will equal 16px */

  .content-navigation {
    border-color: $blue; /* will render as border-color: #3bbfce; */
  .border {
    padding: $margin; /* will render as margin: #16px; */


Mixins are one of the most powerful Sass features. They allow re-use of styles – properties or even selectors – without having to copy and paste them or move them into a non-semantic class.

For example, let's say you want round corners on a background element. Instead of typing out the border-radius property for all the different browsers, you can just use the border-radius mixin like so:

  .rounded {
    @include border-radius(5px); /* sets the rounded corners to 5px */

Now let's take a look at theme.scss. You open the file by clicking the filename theme.scss:

  //== Colors
  //## Gray and brand colors for use across Bootstrap.

  $gray-base: #02004D;
  $gray-darker: #353371;
  $gray-dark: lighten($gray-base, 20%) !default;
  $gray: #B6C5D7;
  $gray-light: #DAE1E6;
  $gray-lighter: #F3F6F7;

  $brand-primary: #0FE0B1;
  $brand-primary-lighter: lighten(desaturate(adjust-hue($brand-primary, 1.4928), 16.0191), 47.6471);

In theme.scss above, we see the color palette, headline and body fonts are defined by variables. This means you only need to figure out these values once, and then you can easily reuse the same colors and fonts over and over again in your stylesheet.

Note that theme.scss is a mobile first stylesheet. This means all the styles are mobile devices are loaded first, and styles for tablet or desktop users are loaded afterwards in table-and-desktop.scss.

The easiest way to manipulate the way elements look on your website is to override these default styles or creating new styles when necessary. Using Inspect Element in Chrome and Safari or Firebug in Firefox is the easiest way to reveal which styles are controlling various areas on a given page.

For example, let's say you want to change the color of the header and nav area in Action. First, right click on that area of the page and click Inspect Element. This will reveal the class or id name and attributes.

You can see Inspect Element revealed the div class, and on the right you can see that .navbar-header needs to be modified in theme.scss.

Next, open theme.scss and simply search for the class .navbar-header and edit the background property.

Now click Save and publish. That's it -- the background is a new color. Apply this same approach to anything you want to change on your site.

How the website templates work together

Let's take a quick look at how the website templates work by clicking on layout.html.

Layout.html is what wraps every page and includes your header and footer. Inside you'll find:

  • {{ content_for_header }} loads a critical chunk of code required for your NationBuilder website to function properly. For example, it automatically loads jQuery and relevant meta data. Never remove this.

  • {% include "nav" %} includes the _nav.html file, which contains all the code for your top nav. You will find your _nav.html file on your theme template page if you wish to edit it.

  • {% if request.is_sidebar? %} checks to see if the sidebar is enabled on the page being loaded or not. The sidebar can be turned on or off under settings when editing any page. You will notice if the side bar is turned on, then _columns_2.html is shown, and if it's turned off, _columns_1.html is shown.

  • {{ content_for_footer }} loads a second batch of critical code required for your NationBuilder website to function properly, such as various jQuery scripts. Never remove this.

_columns_2.html wraps the main content area of a page when the sidebar is turned on. Inside you'll find:

  • {{ content_for_notifications }} displays various notification messages, such as when a form is successfully submitted.

  • {% yield %} loads the template for the type of page being loaded. For example, if a calendar page is being loaded, the _pages_show_calendar.html template will be loaded here.

  • {% if request.logged_in? %} checks to see if the user loading the page is logged in. If they are, it loads _supporter_nav.html in the sidebar. If they aren't, it loads the rest of code in this template in the sidebar. If you want to change what is in the right column when someone is logged in, edit _supporter_nav.html.

What is shown in the sidebar changes when a user is signed in vs. signed out

If you want to change what is in the sidebar when someone is signed out, edit _sidebar.html. If you want to change what is in this area when someone is signed in, edit _supporter_nav.html. In general _sidebar.html usually includes an email sign up form, social media widgets and ways for your users to sign in, whereas _supporter_nav.html includes the sidenav which is configurable from the control panel.

Uploading images, jQuery or other assets

If your nation is connected to Dropbox, images and assets used for your overall theme can be uploaded by simply dragging and dropping them into your Dropbox theme folder. Images or assets used on only one page should be uploaded directly to the Files area for the page in the control panel. Learn more about the NationBuilder Dropbox integration.

If you're not using Dropbox, all images or assets used for your overall theme should be uploaded to Website > Theme > Files.

When referencing images or assets in your theme templates, simply refer to them by the file name. No path is necessary. So if you upload header.jpg, refer to it like this: <img src="header.jpg" />.

It's easy to install any jQuery script you want. From the theme templates page, click Files > Upload Files to upload all the script files. Next, click Templates > layout.html. Scroll to the bottom of the file and reference the script files somewhere above the </body> tag.

      <script src="bootstrap.js"></script>

Depending on the installation instructions for the jQuery script you're using, you may need to add additional stylesheets or javascript. If so, the same method applies.

Reference images, stylesheets, and javascript files using just the file name, not the full URL.

This applies everywhere:

  • Images in SCSS or CSS files

  • Images in img tags:      

<img src="myfile.jpg" />    
  • Images in CSS tags:     

 <style> .aclass { background-image: url('myfile.jpg'); } </style>    
  • Images in inline CSS attributes:    

  <div style="background-image: url('myfile.jpg');"></div>    
  • SCSS or CSS files linked in the header:    

  <link rel="stylesheet" href="myfile.scss" type="text/css" />    
  • Javascript files linked in the header:      

<script src="myfile.js"></script>    

If you need to link to an absolute URL, upload the file, then right click on it and choose "Copy Link Address". That link will look something like this:

If you are referencing an image or file within a <script> tag, upload the file to Website > Theme > Files and use the following code:

  {{ theme['myfile.jpg'] }}

Image sliders

NationBuilder has a great image slider already built in. We call it a Featured content slider and you can add one to any page. Select a page you want to add it to from Website and click Featured content sliders.

Simply create a label, headline and select a page to link to and then choose the image and click Save featured content slider. Repeat this process until all images you wish to use have been uploaded. You can rearrange the order of the images by drag and dropping the list on the right.

Make sure all your images are the same size!

So your slider looks great, it's important all your featured content slider images are the exact same size. You also want them to take up the full width of the column. In most cases, a good width is 660px, but if your sidebar is disabled or if your theme uses a full width slider, you'll want a width of about 960px. If you don't have access to Photoshop, you can use apps like Gimp or even websites like to modify the size of your images.



Because NationBuilder uses TypeKit, you can easily use the following high quality fonts on your website by using the font-family values below.

Please note that because Typekit restricts access to a specific domain, you will need to create your own kit if you set up a custom domain. Learn more about registering with Typekit here.

Chunk by Ms. Meredith Mandel.

font-family: "chunk-1","chunk-2"

Lobster by Pablo Impallari.

font-family: "lobster-1","lobster-2"

Museo Sans by exljbris Font Foundry.

font-family: "museo-sans-1","museo-sans-2"

Myriad Pro by Adobe.

font-family: "myriad-pro-1","myriad-pro-2"

Museo by exljbris Font Foundry.

font-family: "museo-1","museo-2"

Google Web Fonts

You can also easily add free Google Web fonts to your nation. Learn more about how they work and how to install them here.

Adobe Edge Web Fonts

Adobe's new free web font library can also be added to your nation easily. The edge web font library includes contributions from Adobe, Google, and other designers.

Display content from one page on another page

You may want your homepage to include snippets of content from another page, such as your latest 3 blog posts. To do this, click Website > Theme > New File and name the file _blog_latest.html, and click Create and edit file. Next, copy and paste the following contents into the file and click Save and Publish.

  {% for post in limit:3 offset:0 %}
    <div style="font-weight: bold; font-size: 16px;">
      <a href="{{ post.url }}">{{ post.headline }}</a>
    <div class="byline">
      {{ post.published_at | date: '%b %d, %Y' }}
    <div class="blog_teaser">
      {{ post.blog_post.content | strip_html | truncatewords:50 }}
    <div class="continue_reading">
      <a class="link-arrow" href="{{ post.url }}">Read more</a>
    <hr />
  {% endfor %}

The code above was pulled from the blog template, and will display the latest 3 posts, and truncate each post to 50 characters each. Adjust or restyle this as you desire.

📌 Note: To display content from other page types, copy and paste the for statement from the template of that page type into the new file instead of the code above.

Next, click Website and then select the page where you wish to display the latest 3 blog posts. Then click Template and paste the following where you want the posts to display:

  {% subpage "blog" with "blog_latest" %}

The {% subpage %} tag

The {% subpage %} tag connects the data and settings of page with a partial template. In this example, it's connecting the page with the slug name blog to the partial template with the file name _blog_latest.html.

You can also display an image attached to a page via this technique by using the following code:

  <img src="{{ page['filename.jpg'] }}" />

Display a form from one page on another page

You may want to display a segment of an action form from one page on another page. If you're just trying to display a form excerpt on your homepage and you're using the Aware theme, you can do this by simply tagging any page homepage. Learn more here.

However, you may wish to use a form differently, or customize it much further. Follow these directions to learn how.

This technique will work with any page type, but this example focuses on signup pages. By default, you have a dedicated signup page with the slug join. Most likely this page won't be your homepage, but you may want to display a piece of that form collecting a person's first name, last name and email address on another page. You will need to "connect" a partial form you create with your signup page so NationBuilder knows what to do with the information, and to apply the settings of your signup page to the form (e.g. landing page, tags to apply to signups, etc.). We'll do that using the {% subpage %} tag and a partial template.

First, navigate to your signup page template under the Website > Themes and click pages_show_signup.html. Copy everything between {% form_for signup %} to {% endform_for %}. Now click New File and give it a name which begins with an underscore, such as _homepage_signup.html, and paste the contents of your clipboard. Edit the form down to the fields you want to display. Note that some pages always require certain fields. In the example below, I've stripped it down to just the first name, last name, and email address.

  {% form_for signup %}
    <div class="form-errors">{% error_messages_for signup %}</div>
    <div class="form-row">
      <div class="form-group col-12 col-md-4">
        <label for="signup_first_name">First Name</label>
        {% text_field "first_name", class:"form-control" %}
      <div class="form-group col-12 col-md-4">
        <label for="signup_last_name">Last Name</label>
        {% text_field "last_name", class:"form-control" %}
      <div class="form-group col-12 col-md-4">
        <label for="signup_email">Email</label>
        {% email_field "email", class:"form-control", placeholder:"Email address", required: "required" %}
      <div class="form-group">
        {% submit_tag "Join", class:"btn btn-primary submit-button" %}
    <div class=”form-submit”></div>
  {% endform_for %}

Finally, we want to display this on a page. To do this, we need to connect this form partial with your signup page by adding a {% subpage %} tag to the page template. It should look like this:

  {% subpage "join" with "homepage_signup" %}

That's it! This tag will connect your signup page with the slug join with the partial template we just created.

Display content from pages with a certain tag on another page

While clicking on page tag will display all pages with that tag, you may want to include pages with the same tag on another page. Doing this is very similar to the method listed above.

For example, let's say you wanted to include all blog posts with the tag "California" on a basic page. To do this, click Websites > Theme > New File and name the file something like _ca_posts.html, and click Create and edit file. Next, copy the following contents into the file and click Save and Publish.

  {% for post in tag.most_recent_published_pages limit: 5 %}
    <div style="font-weight: bold; font-size: 16px;">
      <a href="{{ post.url }}">{{ post.headline }}</a>
    <div class="byline">
      {{ post.published_at | date: '%b %d, %Y' }}
    <div class="blog_teaser">
      {{ post.blog_post.content }}
    <div class="continue_reading">
      <a href="{{ post.url }}" class="link-arrow">Read more</a>
    <hr />
  {% endfor %}

This will display the latest 5 blog posts. Adjust as you desire.

Next, click Website and then select the page where you wish to display the posts tagged California. Then click Template, and paste the following where you want the posts to display:

  {% tag "california" with "ca_posts" %}

This will use the ca_posts.html file we first created and populate it with all the blog posts tagged California.

📌 Note: Always use lower case letters for the tag in the code above. If your tag is more than one word, use an underscore instead of a space.

Keeping donation pages secure

Donation pages in NationBuilder automatically have SSL encryption. Users can see this by a lock icon displayed in their browser. If you want to use an image on your donation page, make sure you upload them to the Files area of the donation page as those images will be served securely. Never link to an image hosted on another server as your donation page will no longer be considered secure.

How to create theme styles

You can create numerous styles of your custom theme, just as we do with public themes. You can alter any element which you define with a SASS variable, such as your font families, font size, colors, button styles, background images, and so on.

If you’re using the Bootstrap 4 starter theme, you can use any of the variables that are found in the theme.scss file. All you have to do is click New File and use the prefix _style_ for the filename. If your theme style is called "Orange," then the filename should be _style_orange.scss. Now add the variables you want to modify. For example, you may want the primary color to be orange and the secondary color to be purple. You could do that by adding the following to your _style_orange.scss file. 

$primary: #FF851B;

$secondary: #3A506B;

Save the file when done. For more in depth information on how you can utilize Bootstrap’s robust theming system, check out the Bootstrap theming documentation.

For other themes create a new style and copy the SASS variables from the top of your theme.scss file to your clipboard. Next, click New File and use the prefix style for the filename. If your style is called "Blue," then the filename should be _style_blue.scss. Now paste the SASS variables into the file and edit the values as desired. Save the file when done.

Finally, create a thumbnail which shows what the theme looks like. The dimensions should be 600px by 484px, and you do not need to include the browser chrome as it will be automatically added. Save the file as a PNG image, and give it the same filename as your style stylesheet, (in this case, that would be _style_blue.png). Now upload your file to Themes > Files.

The next time you select your theme from Themes > Switch to a custom theme, you will be able to click on a thumbnail to select which style of the theme you want the site to use. Note that you must select your new custom theme style before you will see changes made to the _style_blue.scss file.

📌 Note: You probably want to add a "default" theme style option for users to select which includes all the SASS variables from your theme.scss file, unmodified. Follow the instructions above to do this, and give it an obvious name like _style_default.scss and _style_default.png.

Congrats! Those are the essentials, but there's much more to learn...

The documentation above explains all the essential information needed to start building our your custom website theme, but there's so much more cool stuff you can do. Dive into the how to guides below to learn about all the amazing things you can do with liquid.

Related HOWTOs

Did this answer your question?