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 .
-
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 aboutresponse 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';
-
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)
}
-
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
andlanguage
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 = ""
-
Fetch the Accept-Language header.
Now you need to fetch the
Accept-Language
header from the client request and extract the language value. TheAccept-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();
-
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" });
- 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.
-
Construct an HTML response back to the browser that contains the
greeting
andlanguage
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>';
-
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 oftext/html
, then add aContent-Language
header that is populated with thecontent_lang
variable.
let response = {
status: 200,
headers:
{
'Content-Type': ['text/html'],
'Content-Language': [content_lang],
},
body: html_body
};
- Finally, you need to create the response using the constructed html. With the
createResponse
method, you can return an object containing thestatus
,headers
, andbody
to theresponseProvider
event handler which sends that data in the response to the client.
return createResponse(response.status,
response.headers,
response.body);
}
Updated over 2 years ago