Skip to content

Instantly share code, notes, and snippets.

@leanazulyoro
Last active April 11, 2025 05:11
Show Gist options
  • Save leanazulyoro/23c6581fb4379ec311e3bc8538715687 to your computer and use it in GitHub Desktop.
Save leanazulyoro/23c6581fb4379ec311e3bc8538715687 to your computer and use it in GitHub Desktop.

Revisions

  1. leanazulyoro revised this gist Apr 20, 2020. 1 changed file with 1 addition and 9 deletions.
    10 changes: 1 addition & 9 deletions server.js
    Original file line number Diff line number Diff line change
    @@ -63,15 +63,7 @@ app.prepare().then(() => {
    server.use(compression());
    renderAndCache(app)(req, res, '/');
    });

    server.get('/blog/:id', (req, res) => {
    // since we don't use next's requestHandler, we lose compression, so we manually add it
    server.use(compression());
    const pagePath = '/blog'
    const queryParams = { id: req.params.id }
    renderAndCache(app)(req, res, pagePath, queryParams);
    });


    server.get('*', (req, res) => handle(req, res))

    server.listen(port, err => {
  2. leanazulyoro created this gist Apr 20, 2020.
    81 changes: 81 additions & 0 deletions server.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,81 @@
    const express = require('express')
    const next = require('next')
    const Cache = require('lru-cache');
    const compression = require('compression')


    const port = parseInt(process.env.PORT, 10) || 3000
    const dev = process.env.NODE_ENV !== 'production'
    const app = next({ dev })

    const handle = app.getRequestHandler()


    const ssrCache = new Cache({
    max: 20,
    maxAge: 1000 * 60 * 60, // 1hour
    });

    const renderAndCache = (app) => async function(req, res, pagePath, queryParams) {
    const { host } = req.headers;
    // Define the cache key as you wish here:
    const key = host + req.url;

    // if page is in cache, server from cache
    if (ssrCache.has(key)) {
    console.info('SSR Response from cache for ', key);
    res.setHeader('x-cache', 'HIT');
    res.end(ssrCache.get(key));
    return;
    }

    try {
    /**
    * Override res.end method before sending it to app.renderToHTML
    * to be able to get the payload (renderedHTML) and save it to cache.
    */
    const _resEnd = res.end.bind(res);
    res.end = function (payload) {
    // Add here custom logic for when you do not want to cache the page, for example when
    // the status is not 200
    if (res.statusCode !== 200) {
    console.warn('Oops, something is wrong, will skip the cache');
    } else {
    ssrCache.set(key, payload);
    }
    return _resEnd(payload);
    };
    // if not in cache, render the page into HTML
    res.setHeader('x-cache', 'MISS');
    console.info('SSR rendering without cache and try caching for ', key);
    await app.renderToHTML(req, res, pagePath, queryParams);
    } catch (err) {
    app.renderError(err, req, res, pagePath, queryParams);
    }
    };


    app.prepare().then(() => {
    const server = express()

    server.get('/', (req, res) => {
    // since we don't use next's requestHandler, we lose compression, so we manually add it
    server.use(compression());
    renderAndCache(app)(req, res, '/');
    });

    server.get('/blog/:id', (req, res) => {
    // since we don't use next's requestHandler, we lose compression, so we manually add it
    server.use(compression());
    const pagePath = '/blog'
    const queryParams = { id: req.params.id }
    renderAndCache(app)(req, res, pagePath, queryParams);
    });

    server.get('*', (req, res) => handle(req, res))

    server.listen(port, err => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
    })
    })