Skip to content

Heroku Integration

Heroku runs your app on dynos and supports any Node.js server. Integrating SeoRend is straightforward using the Express middleware approach.

Your Heroku app adds SeoRend middleware that intercepts bot requests before they reach your frontend. Since Heroku has full Node.js support, no additional configuration is needed beyond setting an environment variable.

  • Heroku account with a deployed app
  • Node.js app (Express, Fastify, or similar)
  • SeoRend API key from app.seorend.com
  1. Using Heroku CLI:

    Terminal window
    heroku config:set SEOREND_API_KEY=sk_live_your_key_here --app your-app-name

    Or go to Heroku Dashboard → Settings → Config Vars → Reveal Config Vars and add SEOREND_API_KEY.

  2. If your app uses Express, add the middleware before your static file serving:

    server.js
    const express = require('express');
    const app = express();
    // Bot detection patterns
    const BOT_PATTERNS = [
    'googlebot', 'bingbot', 'yandexbot', 'duckduckbot', 'applebot',
    'facebookexternalhit', 'twitterbot', 'linkedinbot', 'slackbot',
    'gptbot', 'claudebot', 'perplexitybot', 'google-extended', 'ccbot',
    'semrushbot', 'ahrefsbot', 'rogerbot',
    ];
    const STATIC_EXT = /\.(js|css|png|jpg|gif|ico|svg|webp|woff2?|pdf|mp4)$/i;
    function isBot(ua) {
    const lower = (ua || '').toLowerCase();
    return BOT_PATTERNS.some(p => lower.includes(p));
    }
    // SeoRend middleware — must be registered before static serving
    app.use(async (req, res, next) => {
    const ua = req.headers['user-agent'] || '';
    if (req.method !== 'GET') return next();
    if (STATIC_EXT.test(req.path)) return next();
    if (!isBot(ua)) return next();
    const apiKey = process.env.SEOREND_API_KEY;
    if (!apiKey) return next();
    const url = `${req.protocol}://${req.get('host')}${req.originalUrl}`;
    try {
    const response = await fetch('https://render.seorend.com/v1/render', {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${apiKey}`,
    },
    body: JSON.stringify({ url, userAgent: ua }),
    });
    if (!response.ok) return next();
    const data = await response.json();
    res.set('Content-Type', 'text/html; charset=utf-8');
    res.set('X-Seorend-Cache', data.cache?.hit ? 'HIT' : 'MISS');
    return res.status(data.status || 200).send(data.html);
    } catch {
    return next();
    }
    });
    // Serve your React/Vue/Angular app
    app.use(express.static('build'));
    app.get('*', (req, res) => {
    res.sendFile('index.html', { root: 'build' });
    });
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
  3. Terminal window
    git add .
    git commit -m "Add SeoRend prerendering middleware"
    git push heroku main
  4. Terminal window
    heroku logs --tail --app your-app-name

    Then test:

    Terminal window
    curl -s -I -A "Googlebot/2.1" https://your-app.herokuapp.com/
    # Should see: X-Seorend-Cache: MISS (first request) or HIT

If you use Heroku Review Apps, set SEOREND_API_KEY in your app.json to automatically include it in review app environments:

app.json
{
"env": {
"SEOREND_API_KEY": {
"description": "SeoRend API key for bot prerendering",
"required": true
}
}
}

fetch not available: Node.js 18+ includes fetch globally. If you’re on Node.js 16, add node-fetch:

Terminal window
npm install node-fetch

And import it: const fetch = require('node-fetch');

Config var not set: Run heroku config --app your-app-name to verify SEOREND_API_KEY is present.