next.js at Chợ Tốt

Dzung Nguyen
Jun 16, 2017 · 7 min read
action asphalt back light

Overview

Every day, Chợ tốt (Chotot) receives over 1 million visits cross platforms, most of the traffic comes from mobile devices. It is really important for us to develop products that can run across devices. In 2016, we switched to a new stack to rebuild our products.

First boilerplate

Base on a starter boilerplate put together by erikras (link here) to experiment with our new web stack. However, we encountered problems in production.

problem

In production, if the traffic is high, the web server will stop responding to the client. At first, we optimized our codebase but the result was still the same. We resolved to use client-side rendering instead of server-side rendering. But the challenge is if we turn off server rendering, SEO will be affected.

solution 1

Search engines now support Javascript in their crawlers (check here for more detail). Our first solution was to delegate the rendering page to client-side. Here is our analysis:

  • Our ranking dropped

solution 2

The next solution was to split the project into 2 and deploy it to 2 different servers. One serves users with client-side rendering. Another one serves crawlers bot from Google, Facebook, … with server-side rendering.

solution 2

Why did we want to change?

  • When deploying code changes we had to deploy the new version to 2 different servers.
  • The boilerplate was out of date.
  • The time to rebuild code at development was too slow. It took more than 10 seconds to rebuild every single change.
  • We wanted to apply new tools to have good experience for Engineers and good performance for the product as well: webpack 2 with many improvements like “Tree shaking”, “dynamic import”…

next.js the rescuer

After looking around some repositories, we considered next.js as a potential replacement for several reasons:

  • There are many small examples on integrations between next.js and other libraries or technologies (check them out here).
  • The documentation is very clean and up-to-date.
  • next.js takes care of all basic configs. Allowing to extend configs of webpack or babel…

redux

We chose redux to manage application states. next.js provides a redux wrapper to help integrate with it easier and more consistent (You can visit here to see example)

ExamplePage.js

routing

next.js” provides a very clean directory structure. There is a special directory “pages”. When you put all your React components into that one, next.js automatically executes:

  • routing
  • hot code reloading and universal (server-side and client-side) rendering.
  • components: to store stateful & stateless component in react.

static resources

next.js also provides a static directory to serve static resources for the web application. All you have to do is place all resources like images, fonts, stylesheets, … into the ‘static’ directory. Then just use it as follows:

static directory
<img src='/static/img/logo.png' />
<link rel='stylesheet' href='/static/css/app.css' />

import modules

 import CSSTag from '../../../components/CSSTag'
module.exports = {
webpack: (config, { dev }) => {
config.alias: {
components_example: path.resolve(__dirname, '../components'),
}
return config
},
}
import CSSTag from 'components_example/CSSTag'
{   "scripts": {      "dev": "NODE_PATH=./ next"    }}
import CSSTag from 'components/CSSTag'
{  "presets": [    "next/babel"  ],  "plugins": [    ["babel-plugin-root-import", [      {        "rootPathPrefix": "@"      }    ]]  ]}
import CSSTag from '@/components/CSSTag'

CSS development

To develop CSS we use the pre-processor Sass with SCSS syntax. Sass provides many functionalities (check them out here). It allows us to

  • define variables
  • call a function (@include)
  • We can write CSS with module scope
index.scss
index.js
page source
CSSTag.js
import style from '@/styles/Example.scss'<CSSTag style={style} />
Example.js
  • auto-prefix
  • minified
// components
@import "./variables";
@import "./ultilities";
@import "./global.scss";
@import "./components/ToolBar";

// pages
@import "./index.scss";
gulpfile.js
production CSS building with gulp

Result

After completed a project with “next.js”, we used lighthouse to audit our web page. Here is a result.

Demo

Here is a full demo

What’s next?

Next.js gives us a lot of benefits so far:

  • Lightweight
  • Easy to use
  • Well document
  • Strong support from the community

Chợ Tốt

Learn more about how Chợ Tốt designs, builds, operates our…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store