Combine 2 blocks of javascript using 1 cloudflare worker

Viewed 70

I have this "route" setup to trigger a Cloudflare worker, where it'll change http header tags to index for certain pages.

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);

  // Clone the response so that it's no longer immutable
  const newResponse = new Response(response.body, response);


  // Adjust the value for an existing header
  newResponse.headers.set('x-robots-tag', 'index');

  return newResponse;
}

Works well but cloudflare will skip my other worker as it gets triggered by a "less specific route" ( the prerender.io Cloudflare middleware code )

/**
 * Basic settings
 */

// The API key visible on your Prerender dashboard.
const API_KEY = 'XXXX';

// The domains that you want to be prerendered.
const PRERENDERED_DOMAINS = [
  'sub.example.com'

];

/**
 * Advanced settings
 */

 // These are the user agents that the worker will look for to
 // initiate prerendering of the site.
const BOT_AGENTS = [
  'googlebot',
  'yahoo! slurp',
  'bingbot',
  'yandex',
  'baiduspider',
  'facebookexternalhit',
  'twitterbot',
  'rogerbot',
  'linkedinbot',
  'embedly',
  'quora link preview',
  'showyoubot',
  'outbrain',
  'pinterest/0.',
  'developers.google.com/+/web/snippet',
  'slackbot',
  'vkshare',
  'w3c_validator',
  'redditbot',
  'applebot',
  'whatsapp',
  'flipboard',
  'tumblr',
  'bitlybot',
  'skypeuripreview',
  'nuzzel',
  'discordbot',
  'google page speed',
  'qwantify',
  'pinterestbot',
  'bitrix link preview',
  'xing-contenttabreceiver',
  'chrome-lighthouse',
  'telegrambot'
];

// These are the extensions that the worker will skip prerendering
// even if any other conditions pass.
const IGNORE_EXTENSIONS = [
  '.js',
  '.css',
  '.xml',
  '.less',
  '.png',
  '.jpg',
  '.jpeg',
  '.gif',
  '.pdf',
  '.doc',
  '.txt',
  '.ico',
  '.rss',
  '.zip',
  '.mp3',
  '.rar',
  '.exe',
  '.wmv',
  '.doc',
  '.avi',
  '.ppt',
  '.mpg',
  '.mpeg',
  '.tif',
  '.wav',
  '.mov',
  '.psd',
  '.ai',
  '.xls',
  '.mp4',
  '.m4a',
  '.swf',
  '.dat',
  '.dmg',
  '.iso',
  '.flv',
  '.m4v',
  '.torrent',
  '.woff',
  '.ttf',
  '.svg',
  '.webmanifest'
];

/**
 * This attaches the event listener that gets invoked when CloudFlare receives
 * a request.
 */
addEventListener('fetch', event => {
  const { request } = event;
  const url = new URL(request.url);
  const { hostname } = url;
  const requestUserAgent = (request.headers.get('User-Agent') || '').toLowerCase();
  const xPrerender = request.headers.get('X-Prerender');
  const pathName = url.pathname.toLowerCase();
  const ext = pathName.substring(pathName.lastIndexOf('.') || pathName.length);

  if (
    !xPrerender
    && containsOneOfThem(BOT_AGENTS, requestUserAgent)
    && !isOneOfThem(IGNORE_EXTENSIONS, ext)
    && isOneOfThem(PRERENDERED_DOMAINS, hostname)
  ) {
    event.respondWith(prerenderRequest(request))
  }
})

/**
 * Helper function to check if an array contains an exact match for an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function isOneOfThem(array, element) {
  return array.some(e => e === element);
}

/**
 * Helper function to check if an array contains an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function containsOneOfThem(array, element) {
  return array.some(e => element.indexOf(e) !== -1);
}

/**
 * Function to request the prerendered version of a request.
 *
 * @param {Request} request - The request received by CloudFlare
 * @returns {Promise<Response>}
 */
function prerenderRequest(request) {
  const { url, headers } = request;
  const prerenderUrl = `https://service.prerender.io/${url}`;
  const headersToSend = new Headers(headers);

  headersToSend.set('X-Prerender-Token', API_KEY);

  const prerenderRequest = new Request(prerenderUrl, {
    headers: headersToSend,
    redirect: 'manual',
  });

  return fetch(prerenderRequest);
}

So I need to combine them both but I'm missing something, everything I try throws an error when I "Save and deploy" the Cloudflare worker.

Here was my one of my attempts

 /**
 * Basic settings
 */

// The API key visible on your Prerender dashboard.
const API_KEY = 'XXXX';

// The domains that you want to be prerendered.
const PRERENDERED_DOMAINS = [
  'sub.example.com'

];

/**
 * Advanced settings
 */

 // These are the user agents that the worker will look for to
 // initiate prerendering of the site.
const BOT_AGENTS = [
  'googlebot',
  'yahoo! slurp',
  'bingbot',
  'yandex',
  'baiduspider',
  'facebookexternalhit',
  'twitterbot',
  'rogerbot',
  'linkedinbot',
  'embedly',
  'quora link preview',
  'showyoubot',
  'outbrain',
  'pinterest/0.',
  'developers.google.com/+/web/snippet',
  'slackbot',
  'vkshare',
  'w3c_validator',
  'redditbot',
  'applebot',
  'whatsapp',
  'flipboard',
  'tumblr',
  'bitlybot',
  'skypeuripreview',
  'nuzzel',
  'discordbot',
  'google page speed',
  'qwantify',
  'pinterestbot',
  'bitrix link preview',
  'xing-contenttabreceiver',
  'chrome-lighthouse',
  'telegrambot'
];

// These are the extensions that the worker will skip prerendering
// even if any other conditions pass.
const IGNORE_EXTENSIONS = [
  '.js',
  '.css',
  '.xml',
  '.less',
  '.png',
  '.jpg',
  '.jpeg',
  '.gif',
  '.pdf',
  '.doc',
  '.txt',
  '.ico',
  '.rss',
  '.zip',
  '.mp3',
  '.rar',
  '.exe',
  '.wmv',
  '.doc',
  '.avi',
  '.ppt',
  '.mpg',
  '.mpeg',
  '.tif',
  '.wav',
  '.mov',
  '.psd',
  '.ai',
  '.xls',
  '.mp4',
  '.m4a',
  '.swf',
  '.dat',
  '.dmg',
  '.iso',
  '.flv',
  '.m4v',
  '.torrent',
  '.woff',
  '.ttf',
  '.svg',
  '.webmanifest'
];

/**
 * This attaches the event listener that gets invoked when CloudFlare receives
 * a request.
 */
addEventListener('fetch', event => {
  const { request } = event;
  const url = new URL(request.url);
  const { hostname } = url;
  const requestUserAgent = (request.headers.get('User-Agent') || '').toLowerCase();
  const xPrerender = request.headers.get('X-Prerender');
  const pathName = url.pathname.toLowerCase();
  const ext = pathName.substring(pathName.lastIndexOf('.') || pathName.length);

  if (
    !xPrerender
    && containsOneOfThem(BOT_AGENTS, requestUserAgent)
    && !isOneOfThem(IGNORE_EXTENSIONS, ext)
    && isOneOfThem(PRERENDERED_DOMAINS, hostname)
  ) {
    event.respondWith(prerenderRequest(request))
  }
})
 addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);

  // Clone the response so that it's no longer immutable
  const newResponse = new Response(response.body, response);


  // Adjust the value for an existing header
  newResponse.headers.set('x-robots-tag', 'index');

  return newResponse;

/**
 * Helper function to check if an array contains an exact match for an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function isOneOfThem(array, element) {
  return array.some(e => e === element);
}

/**
 * Helper function to check if an array contains an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function containsOneOfThem(array, element) {
  return array.some(e => element.indexOf(e) !== -1);
}

/**
 * Function to request the prerendered version of a request.
 *
 * @param {Request} request - The request received by CloudFlare
 * @returns {Promise<Response>}
 */
function prerenderRequest(request) {
  const { url, headers } = request;
  const prerenderUrl = `https://service.prerender.io/${url}`;
  const headersToSend = new Headers(headers);

  headersToSend.set('X-Prerender-Token', API_KEY);

  const prerenderRequest = new Request(prerenderUrl, {
    headers: headersToSend,
    redirect: 'manual',
  });

  return fetch(prerenderRequest);
}
1 Answers

I ended up figuring it, seems just adding the http headers part to the bottom worked.

    /**
 * Basic settings
 */

// The API key visible on your Prerender dashboard.
const API_KEY = 'XXX';

// The domains that you want to be prerendered.
const PRERENDERED_DOMAINS = [
  'sub.example.com'

];

/**
 * Advanced settings
 */

 // These are the user agents that the worker will look for to
 // initiate prerendering of the site.
const BOT_AGENTS = [
  'googlebot',
  'yahoo! slurp',
  'bingbot',
  'yandex',
  'baiduspider',
  'facebookexternalhit',
  'twitterbot',
  'rogerbot',
  'linkedinbot',
  'embedly',
  'quora link preview',
  'showyoubot',
  'outbrain',
  'pinterest/0.',
  'developers.google.com/+/web/snippet',
  'slackbot',
  'vkshare',
  'w3c_validator',
  'redditbot',
  'applebot',
  'whatsapp',
  'flipboard',
  'tumblr',
  'bitlybot',
  'skypeuripreview',
  'nuzzel',
  'discordbot',
  'google page speed',
  'qwantify',
  'pinterestbot',
  'bitrix link preview',
  'xing-contenttabreceiver',
  'chrome-lighthouse',
  'telegrambot'
];

// These are the extensions that the worker will skip prerendering
// even if any other conditions pass.
const IGNORE_EXTENSIONS = [
  '.js',
  '.css',
  '.xml',
  '.less',
  '.png',
  '.jpg',
  '.jpeg',
  '.gif',
  '.pdf',
  '.doc',
  '.txt',
  '.ico',
  '.rss',
  '.zip',
  '.mp3',
  '.rar',
  '.exe',
  '.wmv',
  '.doc',
  '.avi',
  '.ppt',
  '.mpg',
  '.mpeg',
  '.tif',
  '.wav',
  '.mov',
  '.psd',
  '.ai',
  '.xls',
  '.mp4',
  '.m4a',
  '.swf',
  '.dat',
  '.dmg',
  '.iso',
  '.flv',
  '.m4v',
  '.torrent',
  '.woff',
  '.ttf',
  '.svg',
  '.webmanifest'
];

/**
 * This attaches the event listener that gets invoked when CloudFlare receives
 * a request.
 */
addEventListener('fetch', event => {
  const { request } = event;
  const url = new URL(request.url);
  const { hostname } = url;
  const requestUserAgent = (request.headers.get('User-Agent') || '').toLowerCase();
  const xPrerender = request.headers.get('X-Prerender');
  const pathName = url.pathname.toLowerCase();
  const ext = pathName.substring(pathName.lastIndexOf('.') || pathName.length);

  if (
    !xPrerender
    && containsOneOfThem(BOT_AGENTS, requestUserAgent)
    && !isOneOfThem(IGNORE_EXTENSIONS, ext)
    && isOneOfThem(PRERENDERED_DOMAINS, hostname)
  ) {
    event.respondWith(prerenderRequest(request))
  }
})


/**
 * Helper function to check if an array contains an exact match for an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function isOneOfThem(array, element) {
  return array.some(e => e === element);
}

/**
 * Helper function to check if an array contains an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function containsOneOfThem(array, element) {
  return array.some(e => element.indexOf(e) !== -1);
}

/**
 * Function to request the prerendered version of a request.
 *
 * @param {Request} request - The request received by CloudFlare
 * @returns {Promise<Response>}
 */
function prerenderRequest(request) {
  const { url, headers } = request;
  const prerenderUrl = `https://service.prerender.io/${url}`;
  const headersToSend = new Headers(headers);

  headersToSend.set('X-Prerender-Token', API_KEY);

  const prerenderRequest = new Request(prerenderUrl, {
    headers: headersToSend,
    redirect: 'manual',
  });

  return fetch(prerenderRequest);
}

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);

  // Clone the response so that it's no longer immutable
  const newResponse = new Response(response.body, response);


  // Adjust the value for an existing header
  newResponse.headers.set('x-robots-tag', 'index');

  return newResponse;
}
Related