Content Options in Jetpack 4.5

Now available through Jetpack, Content Options let users make small visual changes, like showing or hiding the author, date, featured images, and more.

Last August, we introduced a new Customizer panel called Content Options, which gives users an easy way to make small visual modifications across their sites – no custom CSS needed.

Content Options supports four main features: Blog Display, Author Bio, Post Details, and Featured Images.

Content Options are now available to self-hosted WordPress sites with the latest version of Jetpack (4.5). Theme developers can add support for Content Options by following the Jetpack guide.

Let’s look at the main features of Content Options in more detail.

Blog Display

Users can choose between displaying the full content of each post or an excerpt on the blog and category, tag, and date archive pages, as well as search results.

Full post blog display option in Shoreditch
Full post blog display option in Shoreditch
Post excerpt blog display option in Shoreditch
Post excerpt blog display option in Shoreditch

Default Blog Display

If a theme displays either an excerpt or the full post depending on the post’s post format, theme developers can add a “Default” blog display option to let the theme keep its default blog display settings. For example, by default a theme might always displays posts with the Quote post format as the full post, so a quote is never truncated, while other post formats like Standard might be always displayed as an excerpt.

Default blog display option in Button
Default blog display option in Button

Author Bio

On the single post view, users can opt to display the name and bio of the post’s author. This information comes directly from the author’s profile at Users  Your Profile, and their Gravatar image.

Author Bio displayed on single post in Shoreditch
Author bio displayed on single post in Shoreditch

Post Details

The post details section allows users to show or hide the post date, categories, tags, or the post author’s name.

Post Details displayed in Penscratch
Post details displayed in Penscratch
Post Details hidden in Penscratch
Post details hidden in Penscratch

Users can choose whether to display featured images on single posts and pages. They can also opt whether to display featured images on blog and archive pages, which include category, tag, and date archives as well as search-results pages.

Featured Images displayed in Sela
Featured images displayed in Sela users have loved the flexibility Content Options gives them. We’re very pleased that self-hosted sites can now benefit as well!

Restricting User Content: A Dialogue Among Themers

I had a Slack chat with my colleagues recently that we thought might be of interest to other themers.

Ernesto: I have a small theming question I’d like to clarify. Let’s say I have a page that is used as front page and there’s a section in the front page that displays some text. I can display the page’s content there, using the_content(), but I would only want there to be text — no fancy shortcodes or custom content, just basic formatting.

Would you create your own content filter for that section? Something like adding wpautop, convert_smileys, and wp_kses_post (possibly others too, if they make sense) into that filter? Or just use the_content() ?

I am leaning towards the filter approach, since it may give me what I want, without giving users full liberty to put all sorts of things into a div that is supposed to hold some minor text and content.

Tammie: This feels like a UX issue too. Why are you restricting?

Ernesto: Because it’s not a full content post, it’s a space where there should be one or two paragraphs at most. Just some introductory text.

theme screenshot

Tammie: Then why let full content appear anyway? Post restricting is expected behaviour, page restricting isn’t. Let’s not add a new behaviour.

I’d say the_content() and if user messes up, well…

If you limit that it’s adding a new behaviour.

Ernesto: Yeah, that makes sense.

Caroline: I’d agree with keeping it as simple as possible.

Tammie: Maybe they want to add a link. Adding a link there is a totally expected thing.

Caroline: So, the_content() works 🙂 And then with [the new content settings feature we’re working on] they could change it to the_excerpt() someday soon.


Tammie: Yep, win win.

Ernesto: Very good point… I see no problem with using the_content(), but since I know users want to add everything + the kitchen sink, I was just trying to avoid that.

Caroline: Hahaha.

Ernesto: So yeah, win win.

Tammie: Well that’s assuming they do. Many don’t.

Technically the ones that do make up for ones that don’t😉

David: Yeah, the_content() all the way.

Kathryn: Agreed 100%.

Ernesto: It’s interesting knowing your thoughts on this😀

David: If they put too much content in there, make the theme break elegantly.

Kathryn: If user wants to make their site busy, let them do it.

Kathryn: Users shouldn’t put a zillion widgets in one widget area, but we let them do that😉

Ernesto: Hehe, let them break and then tell them well… you shouldn’t do that.

David: It’s our job as developers to make themes that just work. Part of that is making edge cases not blow up a theme.

Tammie: Well, there’s hand holding and there is spoon feeding. Hands > spoons.

Kathryn: Very much agree re: “Part of that is making edge cases not blow up a theme.”

Also, making cluttered/ugly is different than “breaking”.

Ernesto: I think this is a very good & mature way of thinking… adding stuff for edge cases just makes the theme bloated.

Tammie: Also, edge cases aren’t always bad. We tend to have edge PTSD.

Kathryn: And there’s so much in between cluttered and minimal that is going to look just fine, I think.

Tammie: Yep.

Ernesto: Right, very good discussion and input, thank you so much, that’s why I love y’all:-)

Tammie: Also I kind of love the fact you didn’t even suggest a theme option for that.

Kathryn: Ha.

Ernesto: Hahaha.

Tammie: Times have changed and I like them.

Ernesto: I was going to admit it crossed my mind, but then noticed a page would be cleaner.

Tammie: And that’s why I have even more love about it. Self correcting rocks.

Ernesto: “If they put too much content in there, make the theme break elegantly.” – David Kennedy: Seriously?

David: Yep, I think that’s a sign of theme greatness.

Ernesto: That’s right, the I did what I could to hold the user’s content attitude, I like that too. Definitely adding some float-clearing there.

David: Before this, I worked at a place with a giant, talented editorial team. I thought, Perfect, we can work with them to get exactly the content we need! But they found ways to break things all the time. So whether you know the content, or don’t know it, make it highly fault tolerant.

Ernesto: Very very good advice, thank you!

Show the Latest Featured Image from Featured Content

For the latest ThemeShaper remake, we added Featured Content to Twenty Sixteen. That’s standard, but our design called for not showing the featured image of every post, but only the latest post. That image serves as a backdrop to our collection of featured posts, which can be from one to three posts at a time. It’s a neat design pattern, so I thought I’d share the code needed to grab that image.

First, I assume you have featured content set up like the example code from the Jetpack documentation suggests. Next, let’s write a function to grab that image:

function mytheme_get_first_featured_featured_image() {
	$featured_posts = mytheme_get_featured_posts();
	if ( is_array( $featured_posts ) && ! empty( $featured_posts ) ) {
		$post_id = (int) $featured_posts[0]->ID;
		if ( has_post_thumbnail( $post_id ) ) {
			 $big_post_image = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'mytheme-custom-image-size' );
			 printf( 'style="background-image: url(%s);"', esc_url( $big_post_image[0] ) );

Using it in your theme:

<div id="featured" class="featured-posts" <?php mytheme_get_first_featured_featured_image(); ?>>

<!-- Other stuff -->


A few notes about what’s happening in the code above:

  • First, we need to grab the featured posts, and check to make sure there are some posts.
  • If there is, we assign the post ID of the latest post to a variable, $post_id. We’ll need that later.
  • Next, if the latest post has a post thumbnail, we create another variable, $big_post_image, and use it to assign the actual output of the image URL.
  • Finally, we output the markup. It outputs as a style attribute, and you can then style the rest via CSS. In your theme, you just attach the function to the div or html element you want to apply the style on.

That’s it! Hopefully, this code snippet helps you in the next theme you create. Happy theming!

Jetpack Social Menu

With the release of Jetpack 3.9 last month, we introduced a new tool available for all theme developers: Social Menus. It allows site owners to create a new menu location which is used to display links to Social Media Profiles.

Adding Support

Theme developers can add support for a Social Menu by following these three simple steps.

Step 1: Declare support in a function hooked to after_setup_theme.

add_theme_support( 'jetpack-social-menu' );

Step 2: Create a new function to avoid fatal errors if Jetpack isn’t activated.

function themename_social_menu() {
	if ( ! function_exists( 'jetpack_social_menu' ) ) {
	} else {

Step 3: Use the function created in step 2 to output the menu where you would like it displayed in the theme.



Once you’ve created a menu, Jetpack will automatically enqueue a basic stylesheet to style each one of the menu items, thanks to Genericons. You don’t have to do anything else!

Introducing Components: A Toolbox for WordPress Theme Development

Meet Components, a starter-theme generator to speed up WordPress theme development.

We love a good starter theme. Since launching Toolbox and its popular successor, Underscores, we’ve always reached for a starter theme when building our next, awesome WordPress theme to get us off on the right foot. With Underscores, we always say it gives you a 1,000-hour start. We get excited when we see someone fork Underscores and make it their own, so it shouldn’t come as a surprise that we’re obsessed with evolving what we think of as a starter theme.

Continuing that journey, we’re pleased to announce Components. Think of it as a toolbox for taking your themes where you want them to go, faster. Forked from Underscores, Components gives you a solid base to work from – but it also takes the starter theme to the next level, offering a choice between five different theme types. Each one adds the code needed for starting a certain type of theme. You can select from:

The Classic Blog

  • A two-column layout
  • A sidebar with widgets
  • Navigation in the header
  • A fixed maximum width of 1120px in your style.css file

The Modern Blog

  • A single-column layout
  • A sliding panel for navigation, social menu, and also widgets
  • A large featured image with full-width script


  • A portfolio post type, courtesy of Jetpack, added to all the necessary files
  • A grid portfolio view
  • A single column blog template
  • A sliding panel for navigation, social menu, and also widgets
  • A large featured image with full-width script


  • A front page template with featured images in grid a layout, plus a two-column blog
  • Layout with excerpts
  • A two-column layout
  • A sidebar with widgets
  • Navigation in the header
  • A fixed maximum width of 1120px in your style.css file


  • A front-page template with a custom header, testimonials section, and  page content area
  • A custom testimonial post type turned on, courtesy of Jetpack
  • A two-column layout
  • A sidebar with widgets
  • Navigation in the header
  • A fixed maximum width of 1120px in your style.css file

Why Components?

So why the different approach with Components? Three main things inspired this direction: the community behind Underscores, the people who use our themes every day, and the web design and development community.

While maintaining and improving Underscores, we always see great pull requests from the community that we turn away because the contributions end up being too specific for a normal starter theme. Many of those additions would have been perfect in most themes. Now, some of them have a home in a project that zeroes in on a certain kind of user with each theme it builds. Speaking of users, we know from launching hundreds of themes on that themes are one of the most challenging areas of WordPress for people to understand. They need more themes that “just work,” and we hope Components will help achieve that. Lastly, the web community has embraced building systems, methodically created with the pieces that make up a site. Even some popular libraries have taken this approach. We see Components as the first step to allowing you to make a starter theme that’s just right for your project.

We’re very excited to see what the community brings to the project and are looking forward to evolving Components with your help. Right now, we’re in the early stages of our vision and execution for Components, so expect both repositories that power this project, theme-components and to evolve quickly and constantly.

Fork or download Components on GitHub or generate your own custom starter theme at and have fun making awesome new WordPress themes!

Give Your Jetpack Themes a Boost

If you’re making themes, Jetpack allows you to easily add additional functionality to your themes in a consistent way without a lot of overhead — and without accidentally wandering into “plugin territory.” Here at Automattic, more and more of our themes take advantage of Jetpack to implement site logos, featured content sliders, testimonials, portfolios, food menus, and other special functionality.

The trouble is that users don’t always realize they need to activate Jetpack in order to turn on this functionality. With so many installing themes directly from their WordPress dashboards, most users don’t even know where to find a readme file. As a result, we saw tons of confused users posting in the forums, asking how to make their sites look like our demos.

What we needed was a way to easily inform our users that their theme relied on certain Jetpack modules, and help them install or activate them as needed. This would save on support time as well as make our users happy. We also needed a solution that would be easy to add to lots of different themes, without requiring a lot of manual labor.

Enter the Jetpack Dependency Script

We’ve been working on a solution to this problem over the past few months, and we’ve come up with a simple script that helps our users figure out what’s going on. Since starting to use it in our themes, we’ve seen the number of support requests drop substantially.

Since we love open source, we’ve made the code freely available on Github — so you can use it, too!

Give It a Spin

Want to start using it in your themes? Download it from our Github repo, put it somewhere in your theme — I recommend the inc folder — and include it from your theme’s functions.php, like so:

 * Load plugin enhancement file to display admin notices.
require get_template_directory() . '/inc/plugin-enhancements.php';

You’ll want to replace all instances of textdomain in the script with your theme’s text domain, since it adds a few new strings. You’ll also want to regenerate your theme’s POT file once that’s done.

How It Works

Here’s how it works in Sela, which uses a Site Logo and the Testimonials custom post type.

If the user doesn’t have Jetpack installed, they’ll see this:
Install Jetpack

If the user has installed Jetpack, but hasn’t yet activated it:
Activate Jetpack

If the user has installed and activated Jetpack, but hasn’t activated the required modules:
Activate Custom Content Types module

The notifications appear on the user’s dashboard and on the Themes and Plugin pages. The notifications can be dismissed so they don’t annoy users who don’t want to use Jetpack.

What’s Under the Hood?

Since the script is looking for theme support using current_theme_supports(), themes need to explicitly register support for the Jetpack features they support. Some Jetpack features — like testimonials and portfolios — are available across all themes, and don’t require the theme to explicitly declare support for the feature. Be sure to add theme support for all Jetpack features you intend your theme to make use of. You can declare support like so:

add_theme_support( 'jetpack-portfolio' );

The script checks for theme support first, then checks to see if the required plugins (Jetpack) and modules are activated. It then builds out notifications tailored to the user’s individual situation, so that users are effectively guided through the process of installing and activating the plugin.

Blast Off!

Presto! In only 366 lines of code, we have happier support people and happier users. Feel free to use this script in your own themes, or remix it for your own purposes.

Challenges in JavaScript-Based Theming

Welcome to part three of our tutorial on building themes with JavaScript. In part one we considered the JavaScript web landscape and where it leaves us today. In part two we looked at the forthcoming WordPress REST API. In part three, we will consider the most pertinent question: how do we apply all this to WordPress theming? Some of you are likely already realizing that there are surely a lot of challenges in doing so. And you would be right.

Watch the video presentation or read the transcript below.

Demo Materials

You’ll find accompanying material for this screencast available in a public GitHub repo — each screencast has a corresponding folder with a very simple theme that can be activated.

Getting Real

As you may have noticed in the previous tutorial’s files, we need a theme skeleton to make a project like this work. Fortunately, WordPress only requires themes to have a style.css and index.php file to be recognized. Beyond these two files, we can build the whole thing in JavaScript. If this thought is setting off alarm bells for you right now, I understand. Put those alarm bells to one side for just a little while.

If we are going to build a theme with JavaScript, we probably don’t just want one massive JavaScript file. We also don’t want to have to enqueue lots of separate JavaScript files just for the sake of keeping things tidy. Fortunately, others have already done this work for us. CommonJS — a project which, like Node.js, kicked off in 2009 — has created a myriad of specifications and conventions for JavaScript developers to follow; they’re a bit like a JavaScript version of the W3C. The CommonJS project has created specifications for JavaScript modules, which we can use to split up our code. JavaScript modules allow us to create something similar to a WordPress theme, with different JavaScript files containing different template parts and theme files.

Although we can split out our code into different JavaScript files as we can with PHP, unlike with PHP, we’ll want to concatenate these files into one when we run the theme. In theory, we don’t have to do this — but if we don’t, each page would need to enqueue lots of different JavaScript files, which is bad for performance and user experience.

To concatenate the files we’ll will need to use a build tool, such as CodeKit, Grunt, or Gulp. We can even use Unix’s Make utility, which was first released in 1977(!), to run our build process. At this stage, it doesn’t really matter, as the main thing our build process will do is smoosh our JavaScript files into one file, so whichever utility you’re most comfortable with is fine. For this tutorial, I’ll use my current favourite, Webpack.

Let’s take a look at how these JavaScript modules work. In part two, I showed an example of a very basic JavaScript theme with some inline JavaScript. We were breaking quite a few WordPress conventions, with everything in one big index.php file.

I’ve now broken this up and turned it into a more conventional theme. In index.php we now just get a header and footer. We’re now enqueueing our JavaScript in our functions.php file correctly. And our JavaScript file now sits on its own.

But if you look closely, you might notice something has changed. Our changePost function has disappeared, and instead we are requiring the changePost function. If we go back to the containing directory, you can see that we also have a changepost.js file. This file now contains the changePost function. Note that at the bottom, we have a line that says module.exports = changePost. This is the CommonJS convention for defining what the module actually is. So when we require it, this ensures that what we require is the changePost function itself.

Let’s get concatenating. I’ve mentioned that we’re using Webpack, so let’s get that set up. First, you need to install Node.js. Fortunately, this is a lot easier than it used to be — simply go to and download the automatic installer for your system. Once node.js is installed, we can run a command to install Webpack:

npm install webpack -g

This gives us global command-line access to Webpack. With this done, we can now run the most basic Webpack command, which is to take a source file, and smoosh it into a compiled file. The command for this is:

webpack ./theme.js compiled.js

We can now view the compiled file and see that it contains the contents of both changepost.js and theme.js. An extra little bonus with Webpack is the -p flag, which simply means that you want to minify the file – remove whitespace and remove all comments etc. You can see that even this simple example our compiled file is almost a third of the size it was unminified.

We can also add the -w flag which means we want Webpack to watch the files and automatically recompile whenever we change anything.

With the file compiled, we can see everything in action working together.

The Route of All Evil

With everything we’ve looked at so far, you can probably imagine stringing together a theme that allows a user to browse through different chunks of content from their website. However, a major missing piece is routing, something that you may not have heard of. Routing broadly encompasses the way that we deal with URLs changing. Let’s say a user visits our site, clicks to a different post and wants to share the link. With the examples we’ve looked at so far, this isn’t possible. Routing also ties into our user’s history. If we have no routes, the user can’t press the back button. No routing also means we have little chance of anything meaningful being indexed by search engines. I’m sure you can now appreciate that routing is very important.

In PHP, WordPress deals with this for us. There is a rather large class called WP_Rewrite (you can find it in wp-includes/rewrite.php). This handles every different type of URL and works out what should be shown to the user. In JavaScript, we don’t have this luxury, so we have to deal with it ourselves.

Let’s look at something basic we can implement.

If you look closely at changepost.js, you’ll notice that I’ve added a new line since the last tutorial. As well as editing the document on success, I’ve added a line that redefines window.location.hash. This is the most basic way of changing our user’s route. You’ve probably seen this used on other websites and it amounts to the same thing as using an anchor link to take the user to certain heading on a page.

Let’s look at this in action. Our eventListener has been added to the first link in the menu. If we click it, note that the route now changes.

So with some very basic routing, we now want to change what happens if the user clicks back.

If we go back to theme.js, the eagle-eyed among you may have noticed another line beneath my link listener:

window.onhashchange = changeRoute

We’re hooking a new function, changeRoute, onto window.onhashchange. Every time the URL changes, the browser fires a hashchange event, so this method allows us to tag our own JavaScript on to what happens when the hash changes. You can see beneath this I have a changeRoute function. Here, we say if the hash equals nothing — as in, we’re on the homepage — show the original post that we fetched in the first place. The code here is almost identical to changePost, but it just gets the original post.

What About no-js?

A few minutes back I mentioned that you might have alarm bells ringing. We’ve now likely dealt with a couple of those alarm bells. But we’re not done. Some of you may be thinking, “But what if the user doesn’t have JavaScript enabled? Or what if something has caused JavaScript to break?” In our current scenario, our website simply wouldn’t work.

There are some who don’t think this is a problem. Today, only a tiny number of people browse the web with JavaScript turned off, and for the most part they’re probably power users who fully understand why they have it turned off and know that it will limit their experience. But I am personally not convinced that we should just forget about no-js situations.

Will Somebody Please Think About the Search Engines?!

Even if we sort out our routing, what about search engines? As it happens, Google is now able to render JavaScript. I’m not sure if it’s official yet, but I’ve experimented with this. For example, the ThemeConf website has no server-side rendering, but try Googling “ThemeConf”. It also works on DuckDuckGo. Despite this, it’s not a great idea to rely on others to render your JavaScript — there are also places where this doesn’t work. Ironically, even though Facebook developed React, it doesn’t render JavaScript-rendered content when you’re embedding a link, for example. To see this in action, and if you use Facebook, try pasting a link to there. You don’t have to actually share it of course, but you should notice that the preview of the content Facebook will embed is blank.

I believe the most compelling reason to not rely on JavaScript rendering is performance. A developer at Google called Jake Archibald has given some great talks on this. In a worst-case scenario, our current theme makes our users wait for three page loads when they first arrive. First, the page loads, then the JavaScript loads, then the JavaScript loads the content from the REST API. Yuck! This may not be a problem if you’re connected with fiber-optic broadband, but if you’re on a mobile device or a spotty Wifi connection, you’ll really feel the pain.

This ties back into the search engine point, since we know that Google does take page-load times into account when ranking sites in search results. We really don’t want our load times to be three to four times longer than they need to be.

One way to tackle this problem with our simple theme example would be to add PHP to render the theme as well. In our simple example, this wouldn’t take too long and will work fine. The content would load exactly as the menu and footer loads, then the JavaScript will load and take over. However, this would very quickly get out of hand if we tried to build a whole theme. We would be forever having to repeat ourselves, and generally getting into a massive tangle.

Already, our simple JavaScript theme is starting to get pretty messy!

In the next part of this tutorial, we’ll look at how to move from our basic theme to something more advanced, building from an altogether more stable foundation.

The Series

  1. JavaScript, jQuery and the web landscape today
  2. Introducing REST APIs
  3. Challenges in JavaScript-Based Theming
  4. Bringing React into our theme
  5. Et voila, a JavaScript WordPress theme that uses the WordPress REST API

Introducing REST APIs

Welcome back to our tutorial on building themes with JavaScript. In part one, we considered the JavaScript web landscape and looked at where we are today. I suggested that while JavaScript lets us render content in new and interesting ways, there are challenges when it comes to fetching the content in the first place.

Watch the video presentation or read the written transcript below.


Demo Materials

You’ll find accompanying material for this screencast available in a public GitHub repo — each screencast has a corresponding folder with very simple theme that can be activated.

Time for a REST

With traditional WordPress themes, we’ve been able to use all manner of loops and custom queries to get data. In shifting our approach to be less PHP-centric, where will our data come from?

The missing piece of our puzzle is a REST API, essentially an HTTP interface for getting data from a source. The REST part stands for REpresentational State Transfer. Think of it as a way of accessing WordPress queries directly through a URL. We can type a URL into our browser and include parameters just like we would with a custom loop, and in the browser we can see pure data from our website.

A REST API also allows you to post data, so the WordPress REST API allows you to add and update content directly without using the admin interface. Certain types of requests do need authentication, the REST API only publicly exposes content which is already revealed by WordPress through other avenues, like RSS feeds.

This all means that you don’t have to worry about connecting to a database, you just use a series of URLs to access different types of content on your site — these are known as endpoints.

The WordPress REST API is due to be fully incorporated in WordPress 4.5, due in the spring of next year. In fact, the infrastructure of the WordPress REST API will be included with WordPress 4.4 and has already been merged into trunk.

Exploring the WordPress REST API

Next, let’s look at some of the basic things we can do with the WordPress REST API.

I have a WordPress environment set up locally where I have installed WP API. Ahead of its inclusion in core, WP API is available as a plugin on the WordPress plugin repository. With the plugin activated, I can navigate to the URL /wp-json/. At this URL I can see an overview of everything that the REST API makes available to me.

Screen Shot 2015-11-25 at 17.39.08

As the URL suggests, WP API uses JSON formatted data. This is not compulsory for REST APIs, but most REST APIs will use either JSON or XML formatted data. More recently JSON is the preferred format as it’s less verbose and generally easier to work with. I’m also using a Chrome extension called JSON View, which adds sane line breaks and some colours to make it easier to read the JSON. Without JSON View, the JSON data is quite hard for a human to read!

The REST API adds namespaces to its endpoints. This is to ensure that extensions and future versions of the API don’t break functionality for sites and software that use it. The primary namespace at the moment is wp/v2. This means that we can build our website against version 2 of the REST API. If, in the future, it’s decided that the REST API should be structured differently, this restructure would happen under the namespace of wp/v3. Therefore the REST API could completely change, but what we built for v2 would be safe with the inherent backwards compatibility of the v2 namespace.

So, if we navigate to /wp-json/wp/v2/ we can see all of the information about this namespace. As newcomers, we don’t have to worry about this at the moment, but it’s worth understanding the path we take to what we’re really trying to get from the REST API.

If we add posts/ to the end of the above URL, we finally start seeing the data from our website. By default, posts/ will show us the same content that a generic loop on our homepage would. On a clean install of WordPress, this is usually the 10 most recent posts.

Screen Shot 2015-11-25 at 17.39.35

We can further narrow down our request to the REST API by adding a post’s ID to the URL. So in this instance, /wp-json/wp/v2/posts/1241/ will show us just the one post with ID 1241.

The REST API provides typical things that we might want in relation to a post. We can see the date, modified date, permalink, title, content, excerpt, format, whether or not it’s sticky, and more.

Now let’s consider an example where we use the REST API to render content on a page using JavaScript.

I’ve set up a basic HTML document set up in my text editor, including a div with the id "page", an anchor link with text “Hello world,” and an empty h1 and div element. The div has an id of "content".

Beneath that, we have some inline JavaScript inside a script tag. To begin, we use JavaScript’s native XMLHttpRequest API to fetch our data. This is what’s behind jQuery’s Ajax functions, you may remember this from part 1 when I spoke about the website

What this does is fetch the URL from the REST API that we were just looking at. If it’s successful, it will parse the JSON response so that we can access the different elements as a JavaScript object. We then use the querySelector and innerHTML methods to change the data in the HTML on this page. At the moment we aren’t dealing with errors, we would want to deal with these if we were doing this in production.

Let’s see how this works. If I activate the session 2 theme on my test site, we can see what this does. There we go, the data from the REST API is being rendered in my theme demo.

One last thing before we end this tutorial. We still have that link that I added at the top — let’s look at how this is connected.

Well, if we go back to the index of our little theme and scroll down, you can see we also have a function, changePost. This does exactly the same thing as the other bit of JavaScript, but it gets a different post (with ID 1). Beneath this, you can see that we add an event listener to the link. The link listens for a click, if it gets clicked it fires the function. Let’s see what happens.

There we have it.

You can now see how a very basic WordPress REST API-based theme can work. In the next screencast we will consider more advanced approaches to theming and the challenges we face when taking this approach.

The Series

  1. JavaScript, jQuery and the web landscape today
  2. Introducing REST APIs
  3. Challenges in JavaScript-Based Theming
  4. Bringing React into our theme
  5. Et voila, a JavaScript WordPress theme that uses the WordPress REST API

The ThemeShaper JavaScript Theme Tutorial

Dive into the brave new world of JavaScript WordPress theming, looking at best practices and pitfalls along the way.


WordPress theming hasn’t changed very much over the past few years. It’s certainly become more refined, and projects such as Underscores (_s) have helped promote best practices and robust standards. That said, we can still go as far back as Kubrick and find plenty of common ground with the most recent WordPress themes.

This isn’t a bad thing, and it’s probably one of the reasons WordPress is so popular and so many people have been able to get involved in theming. But the web has changed substantially since WordPress welcomed its first default theme in 2006. More than half the web’s users now access it from mobile devices. We have HTML5, and with it a whole host of browser APIs that didn’t exist in 2006. These advances have helped a whole new ecosystem of JavaScript-based web apps blossom.

Some aspects of this ecosystem have found their way into WordPress themes. Most of us have probably seen our fair share of jQuery-enabled carousels. We have JavaScript-enhanced tiled galleries and lightboxes available through plugins like Jetpack. Yet very few of us would consider building a theme entirely in JavaScript. The thought may even send shivers down many of our spines.

Building a WordPress theme with JavaScript might be considered lunacy by some, who may wonder why you’d want to attempt such a thing. Others may have questions about SEO, performance, accessibility, plugin compatibility, among a myriad of issues. There are definitely challenges to building a theme with JavaScript, and before reading any further you should know that this is still an experimental area of WordPress theme development.

But, and this is a big “but,” a JavaScript-based approach to theme-building opens up a wonderful world of new possibilities to the curious developer, including:

  • Storing and pre-fetching content using the browser’s Web Storage API to allow server-less, seamless transitions — using the browser’s History API — between posts and pages.
  • Animations within themes, for more natural and intuitive interactions.
  • The ability to create entirely offline experiences using all new Service Workers.

Along with these exciting improvements, the WordPress REST API is being integrated into Core. The REST API makes it much easier for us to build themes with JavaScript. There is no better time to start getting familiar with how the WordPress ecosystem is changing.

The Series

In this five-part tutorial, we’ll expose you to the brave new world that WordPress theme development might inhabit in the coming years. While the best practices for building a theme in this way are still to be established, we’ll do our very best to guide you into the secret garden of the future.

Stay tuned for:

  1. JavaScript, jQuery and the web landscape today
  2. Introducing REST APIs
  3. Challenges in JavaScript-Based Theming
  4. Bringing React into our theme
  5. Et voila, a JavaScript WordPress theme that uses the WordPress REST API

JavaScript, jQuery and the Web Landscape Today

This is the first in our five-part series on building WordPress themes with JavaScript. Let’s kick things off with an overview of today’s web landscape and how JavaScript fits in. The vast majority of WordPress themes today use jQuery for at least something, so I’ll look at how we’re building themes today, and how we can think about using JavaScript techniques that may be less familiar.

Check out the video presentation or the written transcript below.


A Brief History of JavaScript

What is JavaScript? In Douglas Crockford’s JavaScript: The Good Parts he describes JavaScript as the language of the browser. It enables developers to manipulate the web browser, and therefore affect users’ interactions with the browser. This is at the core of why we should even be thinking about JavaScript in the context of theming.

I’m not just talking about the DOM (Document Object Model). Of course, without JavaScript we can control what the user sees in the browser. But with JavaScript, we can interact with things beyond the DOM. We can edit the browser’s history, we can store data in the browser’s memory, and now we can even create push notifications. This takes us even further than the browser and into the user’s device.

For a long time, JavaScript also allowed us to do things asynchronously, loading things in the background while the user is doing something else. Google, via Gmail, have been doing this since 2004. At that point, working with JavaScript was prohibitively difficult, and unless you had a lot of developers and money, you didn’t generally use it in the way Google did. That said, developers did start making basic use of the Ajax techniques that Google largely pioneered with Gmail. Ajax stands for Asynchronous JavaScript and XML.

Getting Our Hands Dirty

Let’s look at some simple things we can do with JavaScript in Chrome’s developer console, using the BBC website as an example. (All modern browsers have an equivalent way of doing this.) I’m not going to use jQuery, just so we can get more comfortable with the idea of pure JavaScript.

First, we want to select something in the DOM. The two most common methods for doing this are getElementById and querySelector. They’re similar, except with querySelector we can select elements by their class. As its name suggests getElementById only allows us to select elements by their ID.

With something selected, we could now change pretty much anything about it. This is basically what jQuery does behind the scenes.

jQuery etc.

I’ve mentioned jQuery a few times. Years ago, many felt JavaScript was arcane and hard to understand. There were a lot of browser inconsistencies and compatibility issues. The jQuery project, which kicked off in 2006, tried to abstract the difficult problems with JavaScript, and allow people to more easily make use of it. At its essence, jQuery is a library of abbreviations. A great introduction to jQuery is the website

When this site first went live it was the butt of a lot of jokes, but it’s actually quite a useful resource. On the one hand we can see how jQuery really does shorten how much code we need to write, but sometimes the jQuery version is no shorter than pure JavaScript. Occasionally, the jQuery way is even slightly longer, such as with outerHTML.

I’ve used jQuery a lot in my time as a developer and while it can be useful, I do believe that jQuery can restrict those using it to what it is able to do. I also think that because of jQuery, a lot of developers remain mostly unfamiliar with JavaScript itself.

It’s also worth noting that there are/were some other players in the same field as jQuery, for example MooTools and YUI.

A Whole New Node

In 2009, JavaScript saw the start of a bit of a renaissance, as Node.js landed, which allowed you to run a server with JavaScript. The JavaScript renaissance really hit its stride in 2011 with the arrival of npm, the Node Package Manager. This was huge because it made it trivial to create and distribute JavaScript modules. In a way, npm is like a JavaScript version of the WordPress plugin repository. Since Node’s arrival, lots of new JavaScript libraries and frameworks have come onto the scene including Backbone, Ember, Angular, and React.

These new libraries and frameworks have made it easier for developers to create quite impressive app-like websites with JavaScript. At the same time, many of the browser inconsistencies and compatibility issues with JavaScript have been ironed out. We are now in a position with JavaScript where we can take pretty much complete control of the user’s experience on our websites. The one missing piece of the puzzle in the context of WordPress is data. Yes, we can manipulate the DOM and move things around, but how do we get the data from WordPress? That’s where the REST API comes in, and that’s what I’ll be focusing on in the second part of this tutorial.

The Series

  1. JavaScript, jQuery and the web landscape today
  2. Introducing REST APIs
  3. Challenges in JavaScript-Based Theming
  4. Bringing React into our theme
  5. Et voila, a JavaScript WordPress theme that uses the WordPress REST API