D
D
Dmitry Sviridov2020-02-22 20:14:18
Node.js
Dmitry Sviridov, 2020-02-22 20:14:18

How to programmatically invalidate SSR cache in NextJS?

I don't understand how to invalidate the SSR cache in a project with NextJS . In all examples ( for example ), the cache is not stored in Memcache or, say, in Redis, but directly in the application and is invalidated by ttl. Accordingly, if I have a blog, and I edited the article so that the user sees the changes on the site, a certain time passes. If ttl is, say, 2 hours, then the maximum you can wait for a cache update is 2 hours, respectively. Is it possible to somehow programmatically invalidate the cache of a particular page? It was not possible to make NextJS friends with express-redis-cache .

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry Sviridov, 2020-02-22
@dimuska139

In general, he solved the issue. For cacheable-response , you can specify your Keyv instance in the cache parameter by passing the desired store to the class constructor. Accordingly, if you pass @keyv/redis there , then the cache will be stored in Redis. If desired, you can simply delete the desired key from Redis and that's it - that's invalidation.
Maybe a little misunderstood, so here is my server.js code:

const express = require('express');
const next = require('next');
const redirects = require("./redirects");
const cacheableResponse = require('cacheable-response');
const port = parseInt(process.env.PORT, 10) || 3001;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const KeyvRedis = require('@keyv/redis');
const Keyv = require('keyv');

const handle = app.getRequestHandler();

const keyvRedis = new KeyvRedis('redis://127.0.0.1:6399'); // TODO: Get from dotenv

const ssrCache = cacheableResponse({
    ttl: 1000 * 60 * 120, // 2 hours
    get: async ({ req, res, pagePath, queryParams }) => ({
        data: await app.renderToHTML(req, res, pagePath, queryParams)
    }),
    cache: new Keyv({ store: keyvRedis }),
    send: ({ data, res }) => res.send(data)
});


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

    redirects.forEach(({ from, to, type = 301, method = 'get' }) => {
        server[method](from, (req, res) => {
            res.redirect(type, to)
        })
    });

    server.use((req, res, next) => {
        res.append('Set-Cookie', "HttpOnly;Secure;SameSite=Strict");
        next();
    });

    server.get('/posts/:slug', (req, res) => {
        const queryParams = { slug: req.params.slug };
        const pagePath = '/post';
        return ssrCache({
            req,
            res,
            pagePath,
            queryParams
        });
    });

    server.get('/', (req, res) => {
        const pagePath = '/';
        return ssrCache({
            req,
            res,
            pagePath
        });
    });

    server.all('*', (req, res) => {
        //console.dir(req.url);
        return handle(req, res)
    });

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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question