How to create a website theme with NationBuilder

Creating a custom website theme in NationBuilder is easy to learn, and these docs cover all the essentials on how to get started. 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.

Building your theme on a Mac? Check out NationBuilder Theme Sync for Mac (beta).

Table of contents

Create a new theme

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 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. Then click New custom theme.

Give your theme a name and leave Clone your current theme and Switch site to your new site immediately selected. Then 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 3. Please refer to the official Bootstrap documentation as you style your new theme. We highly recommend you use Theme Sync For Mac 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.
  • tablet-and-desktop.scss are the styles for people viewing the site on tablet and desktops.
  • layout.html wraps every page and includes your header and footer.
  • _columns_1.html wraps the main content area of a page when the sidebar is turned off.
  • _columns_2.html wraps the main content area of a page 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. 

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 this template will override the theme level template and only affect this page. The Files page which exists under each page is where you should 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. Mixins:

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 rounder 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:

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


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 remove the dark background behind the header and nav area in Aware. 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 .header-container needs to be modified in theme.scss to get rid of the background.

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

Now click Save and publish. That's it -- the background is gone. 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 _columns_2.html. If you want to change what is in this area when someone is signed in, edit _supporter_nav.html. In general _columns_2.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.

NationBuilder Theme Sync for Mac

If you are building your theme on a Mac, you can download the beta of NationBuilder Theme Sync for Mac.

This is a useful little desktop application which allows you to edit theme and page level templates locally using your favorite text editor. Changes saved will automatically sync with your nation and be published live.

Uploading images, jQuery or other assets

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.


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:
  • Images in CSS tags:
  • Images in inline CSS attributes:
  • SCSS or CSS files linked in the header:
  • Javascript files linked in the header:

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: https://nationslug.nationbuilder.com/assets/pages/1/filename.jpg.

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

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!

For your slider to look 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 picresize.com 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.

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:

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:

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 tecnhique 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 persons 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 %}{% raw %} 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 {% raw %} {% 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 first name, last name, and email address.

Form won't submit?

Please note that {% hidden_field_tag "page_id", page.id %} should always come right after the beginning of the form. The form will not submit without it. Also make sure not to remove the liquid tag which displays error messages, as well as the div form-submit. If the form still won't submit, please read these troubleshooting tips.

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:

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.

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:

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.

To create a new style, 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, just like we do the public theme thumbnails. 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 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.

If you have a question you can't find in the documentation, try searching Frequently Asked Website Questions.

Do you like this page?

Showing 74 reactions

Wrap code snippets in <code></code> tags.

  • commented 2015-03-15 19:12:47 -0700 · Flag
    Is there a forum where one can ask design questions? I’m having trouble vertically centering a div.
    There seems to be a lot more containers than I can find the html for. I’m looking to vertically center the #content div on this page: http://aaap.nationbuilder.com/. Nothing seems to because I’m not sure what the parent div is and how to target it. Any tips?
  • commented 2015-02-24 15:58:45 -0800 · Flag
    How do I select two tags: {% tag “california” with “ca_posts” %}

    Posts with tag A and B or posts with tag A or tag B?
  • commented 2015-02-23 23:41:29 -0800 · Flag
    Hi Jeff, thanks for your response, i have been pulling my hair out over this one.

    I no longer get the same error, i have been experimenting a bit. I now just get nothing, that is, the stories with a certain tag i want to display on another page just do not appear. At best i have got a “tag does not exist”.
    I have created a new employer_stories.html file with the following code:
    {% for post in tag.most_recent_published_pages limit: 5 %}&lt;div style="font-weight: bold; font-size: 16px;"&gt;&lt;a href="%7B%7B%20post.url%20%7D%7D"&gt;{{ post.headline }}&lt;/a&gt;&lt;/div&gt;
    &lt;div class="byline"&gt;{{ post.published_at | date: '%b %d, %Y' }}&lt;/div&gt;
    &lt;div class="blog_teaser"&gt;{{ post.blog_post.content }}&lt;/div&gt;
    &lt;div class="continue_reading"&gt;
    &lt;a href="%7B%7B%20post.url%20%7D%7D"&gt;Read more&lt;/a&gt;&lt;/div&gt;
    &lt;hr&gt;{% endfor %}

    I think i have my “for post…” statement wrong? should it refer to my blog page slug i am pulling from?

    I next post the following into the page template where i want the stories to appear:
    {% tag "mcdonalds" with "employer_stories" %}

    As i understand it any blog post with the tag “mcdonalds” should be pulled through and displayed as a blog teaser.

    I also followed similar instructions i found over here and had a similar result: http://www.richiroutreach.com/nationbuilder-theme-guide/using-subpage-tag-pass-content-variables-template-file
    Their top line of code looks like this
    {% for post in page.blog.most_recent_blog_posts limit:3 offset:0 %}

    i clearly m not understanding something fundamental here. Your help greatly appreciated.

  • commented 2015-02-23 20:43:13 -0800 · Flag
    hey @kristingillies, can you link to the example in question? Are you getting the issue on the live-site or as a control-panel error message? If it’s the latter, there may be an issue with the snippet you’re trying to include with the subpage command. An exact link will help provide context, though!
  • commented 2015-02-16 21:17:09 -0800 · Flag
    I have followed the instructions to display content from pages with a certain tag on another page and get the following error: Liquid error: undefined method `gsub!’ for nil:NilClass

    Help please. Thanks in advance.
  • commented 2015-02-09 09:16:12 -0800 · Flag
    Thanks Pablo. Hmmm. When I click the upload button in the “Files” section of the page, all .html .scss and .css files are grayed out. I can only upload .js .jpg .png, etc.

    Maybe I will try a different browser.
  • commented 2015-02-09 08:46:20 -0800 · Flag
    Sorry but I don’t know what the code didn’t show up in my example…

    Is like this:
  • commented 2015-02-09 08:44:24 -0800 · Flag
    Hi Libero,

    That’s weird, you should be totally able to upload your custom CSS or even JS and then refer it with a relative URL.

    Here indeed you can see that I have my files uploaded there:


    And the reference in the code is simply like this (notice that is after the original theme .scss reference:

    Maybe this will sounds silly but, just to be sure: Are you browsing the files in the “Files” tab, not the “Templates” tab, right?
  • commented 2015-02-08 17:31:23 -0800 · Flag
    I understand how to edit custom themes and also to do page-level html edits, but how can you associate a “page template” with CSS other than the site them currently selected? How can you point to another CSS? With a tag in the section? And then do you use an absolute URL? The File uploader for the page doesn’t seem to allow uploading .css or .scss
  • commented 2015-01-16 10:59:16 -0800 · Flag
    Please am interested in nation builder and the value is what I want to know better thanks egbo Ifeanyi
  • commented 2015-01-15 12:52:09 -0800 · Flag
    i have a customized theme, how can i find out what public theme it was based on?
  • commented 2014-11-25 18:59:48 -0800 · Flag
    Thanks Hines! I suspected the documentation was off dated or something on that part. Good that have confirmation with your reply.

    Thanks a lot.
  • commented 2014-11-25 18:55:34 -0800 · Flag
    Hi Pablo — Aware (and the other NationBuilder public themes) are loosely based on Bootstrap, but they’re not consistent with its documentation any longer. You ought not assume that Bootstrap’s public documentation is true for Aware, and uploading Bootstrap’s files to your theme will likely cause many things to break.

    Instead, treat it as its own front-end framework and edit it accordingly.
  • commented 2014-11-25 18:14:25 -0800 · Flag
    Hi! My name is Pablo, I’m super noob with NationBuilder… I just want to ask if Aware really have Bootstrap or I got to do something to activate it. I cannot see a call to the Bootrstrap css files or the .js and using native Bootstrap classes seems to be ignored.

    I’m thinking in upload the framework files but maybe is the wrong way to do it… or maybe not… :P

    Thanks :)
  • commented 2014-11-01 04:11:34 -0700 · Flag
    You’re right, Ian. And I know somebody already posted that request… http://nationbuilder.com/ianpatrickhines/support_for_page_custom_values_key_i_e_custom_fields_for_pages

    My attempt was sort of a hack to the same effect, trying to maintain the important principle of keeping actual content out of the templates – not always easy…!
    In the short term, it might be easier for NationBuilder to support variables in Liquid tags like ‘subpage’ or ‘include’ – I believe other instances of Liquid facilitate that already?
  • commented 2014-10-31 10:01:29 -0700 · Flag
    If you’re going to add a feature request, the way to go would be to request custom fields for pages.
  • commented 2014-10-31 09:58:39 -0700 · Flag
    Kyle, have you found a solution to this, or should we make this a feature request? I’m in the same situation as you, basically accessing an additional editable content area for certain page types. So I’m trying to something like this:
    {% capture additional_slug %}{{ page.slug }}_additional{% endcapture %}
    {% subpage additional_slug with "additional_template %}

    Tried variations with quotation marks and variable brackets to no effect.
  • commented 2014-08-14 19:03:16 -0700 · Flag
    Regarding: Display content from pages with a certain tag on another page.
    My homepage is a (news) blog page and I’m trying to display an event from the calendar page on it.

    I’ve been able to get the post from the calendar page to show up on the homepage, but there is no styling and the excerpt is not showing up -just a title and a link.

    I’ve created an include _newspost_posts.html in the current theme, but the styles are still a now show on the (news) blog page. How can I get this page to respond to the style settings in the include?
  • commented 2014-07-25 11:25:10 -0700 · Flag
    Ian, I’m trying to match pages based on the slug and pull in the matching page’s content. It seems that would work for me if I could pass “page_slug” a variable.

    Is that not possible?
  • commented 2014-07-25 10:08:33 -0700 · Flag
    Kyle — I think what you’re trying to do is:

    {% subpage “page_slug” with “template_file_name” %}

    And in the template, call the variables you’re looking for.

    For example: http://www.ianpatrickhines.com/customizing-facebook-login-links-in-nationbuilder
  • commented 2014-07-25 09:40:05 -0700 · Flag
    Is there anyway to use a variable with subpage?

    Like so…
    {% subpage var with “template” %}
  • commented 2014-07-07 12:11:41 -0700 · Flag
    Currently working in publish theme and am trying to get my title and logo to both appear at the top of the website. Anytime I upload a logo it takes the title off and makes the logo in the center. Where do I go in the templates to change the title settings?
  • commented 2014-02-23 03:18:17 -0800 · Flag
    How could display content from other pages that match more than one tag?

    For example, how could you change the snippet above so that it displays the latest blog posts that match both “California” and “News”?

    I have tried
    {% tag "california news" with "ca_posts" %}

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

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

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

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

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

    but can’t get it to work.
  • commented 2014-01-16 13:26:42 -0800 · Flag
    Reggie – the “double font” issue is caused by a line in theme.scss for text-shadow that affects the body tag:

    text-shadow: #fff 0 1px;

    Deleting this line will render the font without a white “shadow” and keep it flat black.
  • commented 2014-01-15 05:14:08 -0800 · Flag
    I’m looking for help with fonts. I’ve been trying to change fonts in a custom theme based on Victory. Tried both typekit and google web fonts and get it done all except for the Donation page form. On that page, the names of text fields become weird—-double font in black and white.
  • commented 2014-01-02 13:04:10 -0800 · Flag
    Patrick, I’m glad you were able to find the answer to your question!
  • commented 2014-01-02 12:05:06 -0800 · Flag
    Sorry guys… it appears one more google search brought me to this link:


    And it appears NB supports custom .scss files, so now I will go debug those… thanks and sorry for the quick post… :)
  • commented 2014-01-02 12:02:20 -0800 · Flag
    Does anyone know if it is possible to upload your own custom .scss files into NationBuilder? What I am trying to do is to allow a user to configure which “color” of my theme they want to use…

    On another CMS, I have 10 color schemes and I use 2 .less files with each color… so if the user wants to use “red”, they do this:

    @import ‘/red.less’;
    @import ‘/galilee-base.less’;

    I know less isn’t supported, so my plan was to convert these to .scss files, but when I try to upload them as .scss files into the theme, I get an http error 500… not sure if this is a syntax error in my file, or that NB doesn’t support custom .scss files at all…

  • commented 2013-12-19 10:21:02 -0800 · Flag
    Gordon, I was editing blog post templates in the past couple days and wasn’t seeing this … I was editing page level templates though, not theme templates…
1  2  3  Next →