diff --git a/docs/usage/search-results/tokens.md b/docs/usage/search-results/tokens.md
index 0174f93f..6eb062b6 100644
--- a/docs/usage/search-results/tokens.md
+++ b/docs/usage/search-results/tokens.md
@@ -50,6 +50,7 @@ Tokens related to connected Web Parts in the Search Results.
|**{PageContext.<PropertyName>}** | Resolves current SPFx page context related tokens. You can use deep paths here to access properties. Ex: `{PageContext.site.absoluteUrl}`. Use the debug template in the web part to see all tokens available under the `context` node.
| **{LegacyPageContext.<PropertyName>}** | Resolves current SPFx legacy page context related tokens. You can use deep paths here to access properties. Ex: `{LegacyPageContext.aadTenantId}`.
|**{QueryString.<ParameterName>}**
| A value from a query string in the URL of the current page. For example, if the URL of the current page contains a query string such as ItemNumber=567, you could obtain the value 567 by specifying `{QueryString.ItemNumber}`.
Use `{?QueryString.Parameter}` if you want the part to be omitted in case the query string parameter is not present.|
+|**{Cookie.<CookieName>}**
| The value from a cookie. For example, if a cookie called Current-Language contains a value such as en-us, you could obtain the value en-us by specifying `{Cookie.Current-Language}`.
Use `{?Cookie.CookieName}` if you want the part to be omitted in case the cookie is empty or is not present.|
|**{CurrentDisplayLanguage}**
|The current display language based on MUI in _ll-cc format_.
|
|**{CurrentDisplayLCID}**
|Numeric value of the current display language based on MUI in _ll-cc format_.
|
|**{TenantUrl}**
|URL of the tenant (root site)
|
diff --git a/search-parts/src/services/tokenService/TokenService.ts b/search-parts/src/services/tokenService/TokenService.ts
index 7edf5406..b577a0d7 100644
--- a/search-parts/src/services/tokenService/TokenService.ts
+++ b/search-parts/src/services/tokenService/TokenService.ts
@@ -139,6 +139,7 @@ export class TokenService implements ITokenService {
inputString = this.replaceGroupTokens(inputString);
inputString = this.replaceLegacyPageContextTokens(inputString);
inputString = await this.replaceHubTokens(inputString);
+ inputString = this.replaceCookieTokens(inputString);
inputString = inputString.replace(/\{TenantUrl\}/gi, `https://` + window.location.host);
@@ -631,6 +632,47 @@ export class TokenService implements ITokenService {
return inputString;
}
+ /**
+ * Resolve current cookie related tokens
+ * @param inputString the input string containing tokens
+ */
+ private replaceCookieTokens(inputString: string): string {
+
+ const cookieRegExp = /\{(?:\?){0,1}(?:Cookie)\.(.*?)\}/gi;
+ let modifiedString = inputString;
+ let matches = cookieRegExp.exec(inputString);
+
+ while (matches !== null) {
+ const cookieName = matches[1];
+ const cookieValue = this.getCookieValue(cookieName);
+ if (cookieValue) {
+ modifiedString = modifiedString.replace(matches[0], cookieValue);
+ }
+ else if (matches[0].includes("?")) {
+ // If Cookie Token is specified like this, {?Cookie.CookieName}, it is removed if the Cookie doesn't exist
+ modifiedString = modifiedString.replace(matches[0], "");
+ }
+ matches = cookieRegExp.exec(inputString);
+ }
+
+ return modifiedString;
+ }
+
+ /**
+ * Return the cookie value
+ * @param cookieName name of the cookie
+ */
+ private getCookieValue(cookieName: string): string {
+ const name = cookieName + "=";
+ const decodedCookie = decodeURIComponent(document.cookie);
+ const ca = decodedCookie.split(';');
+ let val = ca.filter(cookie => cookie.includes(name))[0]?.split("=")[1];
+ if (!val) {
+ val = '';
+ }
+ return val;
+ }
+
private replaceAndOrOperator(inputString: string) {
// Example match: {|owstaxidmetadataalltagsinfo:{Page..TermID}}