A website with manageable content using a Bootstrap theme, client-side JavaScript and prismic.io

Written by Rudy Rigot, Developer Evangelist in Engineering

For front-end developers out there who master the art of front-end technologies (including HTML5, JavaScript and CSS), manageable content used to impose some kind of a brick wall that stops the fun. It used to mean learning a back-end technology which is not trivial for some, and even not necessarily interesting for others.

Today, we're going to be building a website that displays manageable content, built with front-end technologies only (no, not even Node.js). We will see how prismic.io's brand new "single-page mini framework" can help us achieve just that. In a future blog post, we will see how to get a snappier, SEO friendly website using this framework.

prismic.io is a web software you can use to manage content in any kind of website or app. A prismic.io content repository comes with a REST API from which your website can query your content, and a writing-room where you can edit and manage your content. Get your beta invite today, they usually roll out within hours!

Step 1: picking a Bootstrap theme

I like to start off from a Bootstrap theme, because there are so many, and a lot of them are just stunning. Once I've downloaded my Bootstrap theme, all of the heavy lifting is already done as of front-end code, I can just use it as is, and I can start getting things done.

Today, I chose to build a small agency's website, based on the "Qubico" Bootstrap theme. It looks gorgeous, and has a lot of cool and funky animations here and there that are going the make the whole thing even more fun!

First things first: the theme offers a huge amount of different possible sections (there are actually 16!), which is great to offer a wide range of choice for its users; but in my case, I will not be needing them all. So I guess I should start with getting rid of the bits of HTML I don't need, to keep it simple...

Step 2: creating manageable content

To start with, I need to create my content repository. Your content repository is where your content lives. It literally takes a single click from the prismic.io dashboard, to get both my writing-room and my API (with its API browser) up and running.

For this particular project, I can quickly identify 8 document types I'm going to be needing, that I can create as document masks: "About", "Client", "Service", "Staff", "Way to contact", "Portfolio" with "Portfolio section", and "Copy" to write my copy in.

Document masks describe what a document should contain. For example, in the "staff" document mask, we require a full name, a title, a photo and so on (you can learn how to write your custom type here).

Then, I can log into my writing-room, and simply start writing and publishing content.

Step 3: including prismic.io's "single-page" framework

First, take the 3 JavaScript files in our "javascript-singlepage" open-source GitHub repository, and paste them into your "js" directory, right in your template.

Second, add this at the bottom of the <head> section of your webpage, and replace "your-repository-id" by your repository ID:

<meta name="prismic-api" content="https://your-repository-id.prismic.io/api">

Then, if you want to be able to preview future content releases directly on your project, create an application in your writing-room's settings, and add the application's client ID like this:

<meta name="prismic-oauth-client-id" content="UzJVxQEAANoLZ3N0">

Note that you can skip adding the "prismic-oauth-client-id" meta tag, but your repository's API access must then be set to "public".

Finally, copy-paste this at the bottom of the <head> section as well:

<script src="js/ejs-1.0.js"></script>
<script src="js/prismic.io-1.0.10.min.js"></script>
<script src="js/prismic.io-singlepage-1.0.0.js"></script>

Note that we are using ejs as a template engine here, but you can decide to use whatever template engine you want.

Your template is now fit to receive manageable content!

Step 4: preparing needed content for the website

Here we will use the Content Query API to retrieve content and store it into variables. Thanks to the prismic.io single-page framework, calling your content repository API is as simple as inserting <script type="text/prismic-query"> as needed in your code, like this:

<script type="text/prismic-query" data-binding="clients">
[
[:d = at(document.type, "client")]
]
</script>

In the snippet, we are querying the prismic.io repository's API with a single predicate that tells to retrieve all documents whose types are "client"; and we store the result in a variable called clients (as defined in the data-binding attribute). The object array stored in the clients variable can then be used to be templated anywhere in your HTML file.

It's very easy to query content with predicates; if you want to learn how predicates work, and how to write them for prismic.io, you should read the API documentation about it.

Step 5: templating the retrieved content into the theme

Since we are using ejs, we'll be templating our page with the ejs syntax; if you're not familiar with it, you'll see it's particularly simple.

For instance, if I retrieved and stored my document of type "copy" in a copy variable, here's how I display its "company_name" structured-text fragment:

[%= copy.getText('copy.company_name') %]

Often, you will be retrieving arrays of documents, and you will want to loop through them to show them all. Let's say you have queried the documents of type service, and they are in a "services" variable; here's what looping through the "service" documents and displaying their titles looks like:

<ul>
[% services.forEach(function(service) { %]
<li>[%= service.getText('service.title') %]</li>
[% } %]
</ul>

Here we are getting text from the "service.title" fragment of the document. Since there are many types of fragments in prismic.io, there are many ways to manipulate them, which you can learn about in our documentation about kits and helper. For instance, here's how you would display the "main" view of an image fragment called "logo" in a client document (an image in prismic.io has as several views as you need to get the view that's the most adapted to your design):

<img src="[%= client.getImageView('client.logo', 'main').url %]">

However, the above code can generate an annoying JavaScript error before EJS interprets it, as what you typed in the src attribute is not yet the URL of an image before EJS transforms it. Therefore, you can type it like this, with the EJS expression in a data-src attribute, and the prismic.io singlepage framework will make it happen the right way:

<img data-src="[%= client.getImageView('client.logo', 'main').url %]">

Some extra sugar: You can render any fragment to basic HTML. For an image, for instance, it will build the <img> tag, the src attribute, etc. This is how it looks like, make sure to open with [%- in order for your HTML tags not to be escaped.

[%- client.getImageView('client.logo', 'main').asHtml() %]

Step 6: any JS on page load?

If your template has JavaScript operations being executed on page load (like my funky animations on the Bootstrap theme I chose), then you need to make sure that those JavaScript operations don't get started before the templating is fully over.

When the prismic.io single-page framework is done with templating, it launches a single "prismic:rendered" event on "document". This is the cue for your scripts to happen.

Im my case, using JQuery, what I want to do is change this call in my JavaScript files:

$(document).ready(function() { ...

into this:

$(document).on('prismic:rendered', function() {

Step 7: deploying your front-end content website

Your website is now done, and all with fully manageable content! Since it's all a static website, you can push it to Dropbox, or GitHub Pages, and go edit, manage and plan your content in very advanced ways in your prismic.io writing-room, without ever having to worry about anything else.

I've hosted mine on GitHub Pages, and also on Dropbox!

What's next?

Actually the approach is pretty straightforward, prepare content documents, add content query script tags to the page, and template them.

You may be wondering how this approach solves the issues arising for front-end-only manageable-content websites? With a couple of extra operations, using the prismic.io single-page framework allows your SEO issues to go away; we'll cover this in an upcoming blog post.

EDIT: the upcoming blog post has landed, and introduces baked.js, our static website generator that works with prismic.io using the syntax introduced in this post.

EDIT2: Now that we know that Google interprets JS while crawling your webpage, SEO is not a downside on front-end apps any more (if you worry about other search engines such as Bing, their JS interpreter will most likely follow...). This doesn't discard baked.js though, you still may want to generate a static website for other reasons.