DYI content management system with Firebase & React
There are two ways of handling website content:
Option number 2 is quicker at first, and is fine for an early stage startup operating in one country. However, two big problems will surface and grow as companies scale.
In fact, I have personally experienced multiple times the first of these two problems at work.
Every time there needs to be a content change, the product team would need to ping an engineer, and the engineer would in turn need to:
This whole process takes at best half an hour to forty-five minutes. However, the opportunity cost is much more because the engineer could have spent that time on more important tasks.
Wouldn’t it be amazing if changing copy is instantaneous instead?
Website can only be displayed in English if the English copy is hard-coded in. This will definitely be a problem if the company ever goes international in non-English speaking countries.
The solution to these two problems is a good content management system.
Pillow, where I’m currently working, had a Hackathon last week. The theme was productivity. I thought that building a CMS to solve problem number 1 would make both the product and the engineering team more productive.
Additionally, I wanted my CMS to not only solve problem number 1, but to also offer a way of handling problem number 2 in the future.
A day? Yup, that’s all it takes to set up a simple and effective CMS.
Firebase is a real-time NoSQL cloud-hosted database. Anyone can signup for an account with their gmail, create a project, and add data to the database.
Because of the NoSQL structure, I thought it would be a great way to store website copy. This is what I did to structure Pillow’s landing page copy during the Hackathon:
Screenshot of json data structure
Pillow’s website is already built with React, and that made my job a lot easier.
All I needed to do on that front is install re-base, set up some configuration, and replace the hard copies. re-base
is an npm package that offers handy methods to easily sync data with Firebase. The repo has good set up documentation, so I won’t go into too much detail here.
I used the listenTo
function to sync with Firebase. Then, I used dispatch to load the data into the state. Thus,re-base
works well with Redux.
componentWillMount() {const { dispatch } = this.props
base.listenTo('en', {
context: this,
then(copies) {
dispatch( loadCopies( language, copies ) )
},
onFailure(error) {
console.log('error', error)
}
})
}
My loadCopies
action calls a reducer to return a new state with the copy loaded.
In the render method of my component, I used the copy stored in the state rather than anything hard coded in.
I also built a separate Rails app with an UI for editing Firebase data. This CMS is thus completely separate from the main app, preventing the main app from becoming an even bigger monolith.
Screenshot of my Rails app for editing content
Once again, I used React and re-base for handling Firebase sync.
componentWillMount() {const that = thisfirebase.auth().signInWithPopup(provider).then(function(result) {
const user = result.user
if (user.email.indexOf('[@pillow](http://twitter.com/pillow "Twitter profile for @pillow").com') > -1) {
base.syncState(EN, {
context: that,
state: EN,
onFailure(error) {
console.log('error', error)
}
})
base.syncState(FR, {
context: that,
state: FR,
onFailure(error) {
console.log('error', error)
}
})
}
}).catch(function(error) {
// Handle Errors here.
console.log("ERROR", error)
})
(Please forgive some of the “hackiness” here, I did do this in one work day.)
syncState
function is a “two-way street.” It listens to changes in Firebase, which then update the state of the component. If the component state gets updated (by this.setState
for instance), the change gets synced to Firebase automatically.
In my Firebase editor app, each value stored inside Firebase is displayed within a textarea
. Thus, this whole DOM structure is dynamically generated based on Firebase data. When the value within a textarea
changes, it triggers a change in the component’s state, which in turn updates the database.
In summary, this is what the CMS logic looks like:
Check out my mad powerpoint skill
Watch the screen recording of my CMS at work:
https://www.youtube.com/watch?v=SNDvfpr3r1s
Now, you may ask, why did I build my own CMS?
There’s no magic reason really, I did it because:
If you like this story, give me some claps! :)