forked from hashicorp/terraform-website
-
Notifications
You must be signed in to change notification settings - Fork 0
/
middleware.ts
113 lines (113 loc) · 3.68 KB
/
middleware.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import setGeoCookie from '@hashicorp/platform-edge-utils/lib/set-geo-cookie';
// eslint-disable-next-line @next/next/no-server-import-in-page
import { NextRequest, NextResponse } from 'next/server';
import { docsRedirects } from 'data/docs-redirects';
import { getEdgeFlags } from 'flags/edge';
// To prevent an infinite redirect loop, we only look for a defined redirect
// for pages that aren't explicitly defined here.
const DEFINED_DOCS_PAGES = [
'/docs',
'/docs/glossary',
'/docs/partnerships',
'/docs/terraform-tools',
];
const BASE_PATHS = [
'cdktf',
'cli',
'cloud-docs',
'docs',
'enterprise',
'internals',
'intro',
'language',
'plugin',
'registry',
];
const devDotRoutes = [...BASE_PATHS, 'downloads'];
const devDotRedirectCheck = new RegExp(`^/(${devDotRoutes.join('|')})/?`);
function setHappyKitCookie(
cookie: Parameters<NextResponse['cookies']['set']>,
response: NextResponse,
): NextResponse {
response.cookies.set(...cookie);
return response;
}
export default async function middleware(request: NextRequest) {
let response: NextResponse;
const { geo } = request;
/**
* Apply redirects to nested docs pages from a static list in data/docs-redirects.
*/
if (
request.nextUrl.pathname &&
!DEFINED_DOCS_PAGES.includes(request.nextUrl.pathname)
) {
const path = request.nextUrl.pathname;
const pathIndexHtml = [path, 'index.html'].join('/');
const pathHtml = `${path}.html`;
for (const key of [path, pathIndexHtml, pathHtml]) {
if (key in docsRedirects) {
const destination = docsRedirects[key];
if (
destination.startsWith('https://') ||
destination.startsWith('http://')
) {
// If the URL is NOT relative, don't construct a new URL from the current one. This prevents
// learn redirects from going to https://terraform.io/https://learn.hashicorp.com/..., for example.
return NextResponse.redirect(destination, 308);
}
// cloning the URL so we can provide an absolute URL to the .redirect() call,
// per: https://nextjs.org/docs/messages/middleware-relative-urls
const newUrl = request.nextUrl.clone();
newUrl.pathname = destination;
return NextResponse.redirect(newUrl, 308);
}
}
}
/**
* We are running A/B tests on a subset of routes, so we are limiting the call to resolve flags from HappyKit to only those routes. This limits the impact of any additional latency to the routes which need the data.
*/
if (geo?.country === 'US' && ['/'].includes(request.nextUrl.pathname)) {
try {
const edgeFlags = await getEdgeFlags({ request });
const { flags, cookie } = edgeFlags;
if (flags?.ioHomeHeroAlt) {
const url = request.nextUrl.clone();
url.pathname = '/home/with-alt-hero';
response = setHappyKitCookie(
cookie.args,
NextResponse.rewrite(url),
);
} else {
response = setHappyKitCookie(cookie.args, NextResponse.next());
}
} catch {
// Fallback to default URLs
}
}
const url = request.nextUrl.clone();
/**
* Redirect opted-in users to Developer based on the existence of the terraform-io-beta-opt-in cookie.
*/
if (devDotRedirectCheck.test(url.pathname)) {
const redirectUrl = new URL('https://developer.hashicorp.com');
redirectUrl.pathname = `terraform${url.pathname}`;
redirectUrl.search = url.search;
const response = NextResponse.redirect(redirectUrl);
return response;
}
// Sets a cookie named hc_geo on the response
return setGeoCookie(request, response);
}
export const config = {
matcher: [
/**
* Match all request paths except for those starting with:
* - /api/ (API routes)
* - /_next/ (Static assets and images)
* - /favicon.svg (favicon)
* - /img/ (images in the public dir)
*/
'/((?!api\\/|_next\\/|favicon\\.ico|img\\/).*)',
],
};