Send a constructed response to a web page

Learn how to send a dynamically constructed response at the edge using the browser’s Accept-Language header in the client request. A visitor from France would see a “Hello World” message in French, while a visitor from Spain would see the same message in Spanish.

This use case shows you how to create a simple, orchestrated response to a calling client based on their country of origin. It doesn't cover how to populate the database or deploy the code and the database. To learn how to to that, see Add data to your EdgeKV database .

  1. Import the two libraries you need to complete this task.

    The first createResponse library is native to Akamai. It's part of the responseProvider functionality of EdgeWorkers, which acts as a surrogate or mock origin server. It intercepts the request and sends back our response. For more about response Provider, see create-response.

    The second library is the EdgeKV helper library, which abstracts away all the complexity of making calls to the KV store. You can download this library from the Github repository.

import { createResponse } from 'create-response';
import { EdgeKV } from './edgekv.js';
  1. Set the hello world response function.

    From the async responseProvider event handler, set hello_world_response that resolves the promise returning the response that will be sent to the client.

    In this function, the request header serves as input parameter.

export async function responseProvider(request) {
    return hello_world_response(request)
}
  1. Set default values in the function.

    Set default values in case the data you need isn't in EdgeKV. For example, if you haven't defined a greeting value for a given language, you may want to respond with a default value. Here, default_greeting and language are set to English.

    You initialize empty variables for greeting and err_msg, which we will populate later.

async function hello_world_response(request) {

    let default_greeting = "Hello World";
    let default_language = "en";
    let content_lang = "en-US";
    let greeting = "";
    let err_msg = ""
  1. Fetch the Accept-Language header.

    Now you need to fetch the Accept-Language header from the client request and extract the language value. The Accept-Language header is set by the browser as a hint for which languages the client understands. It can contain multiple language directives which consist of a 2-3 letter base language optionally followed by subtags separated by a hyphen.

    For example: Accept-Language: en-US,en;q=0.5

    You can use the previously defined language variable to extract the value of the Accept-Language header. For simplicity in this recipe, the split method is used to only extract from the first language directive the value that comes before the comma and before the hyphen. It's then set it to lowercase to normalize it.

let languages = request.getHeader('Accept-Language');
    if (languages && languages[0]) {
        content_lang = languages[0].split(',')[0];
        language = content_lang.split('-')[0];
    }
    let key = language.toLowerCase();
  1. Instantiate the object that we will use to access the EdgeKV database.

    For more about EdgeKV's data model of namespaces, groups, and items, see EdgeKV data model.

📘

EdgeKV has a helper library that abstracts much of the complexity away from you. We simply need to specify the namespace and group that contains our data.

const edgeKv = new EdgeKV({ namespace: "default", group: "greetings" });
  1. Put your code in a try-catch block to handle any errors encountered and use the EdgeWorkers JavaScript logger to securely log error messages. To learn more, see Enable enhanced debug headers.
try {
        greeting = await edgeKv.getText({ item: key, default_value: default_greeting });
    } catch (error) {
        err_msg = error.toString();
        logger.log(encodeURI(err_msg).replace(/(%20|%0A|%7B|%22|%7D)/g, " "));
        greeting = default_greeting;
    }

📘

The error message is encoded as it will end up in the EdgeWorker response header. Also the default_greeting is used in case the item isn't found in the database.

  1. Construct an HTML response back to the browser that contains the greeting and language in the body of the page.

    Weave in the language variable to inform the markup of the target language. Also, create a page body and include the language-specific greeting that you previously stored in EdgeKV.

let html_body = '<!DOCTYPE html> \
                     <html lang="'+ language + '" xml:lang="' + language + '"> \
                     <head> \
                       <meta charset="UTF-8"> \
                     </head> \
                     <body><H1>' + greeting + '</H1></body>';
  1. Now you want to send back a 200 OK message with custom headers based on the language.

    You can use the typical Content-Type header of text/html, then add a Content-Language header that is populated with the content_lang variable.

let response = {
        status: 200,
        headers:
        {
            'Content-Type': ['text/html'],
            'Content-Language': [content_lang],
           
        },
        body: html_body
    };
  1. Finally, you need to create the response using the constructed html. With the createResponse method, you can return an object containing the status, headers, and body to the responseProvider event handler which sends that data in the response to the client.
return createResponse(response.status,
        response.headers,
        response.body);
}