* Redirect homepage to user's language * Redirect URLs with no language code * Add leading forward slash * Revert "Redirect URLs with no language code" This reverts commit f817ac1136ea0c7e11c4d61327a4445b56a2f5d6. * Simplify per @zeke * Add homepage language redirect tests * Update middleware/redirects/handle-redirects.js Co-authored-by: Kevin Heis <heiskr@users.noreply.github.com> * braces are good Co-authored-by: Kevin Heis <heiskr@users.noreply.github.com>
69 lines
2.3 KiB
JavaScript
69 lines
2.3 KiB
JavaScript
import patterns from '../../lib/patterns.js'
|
|
import { URL } from 'url'
|
|
import languages from '../../lib/languages.js'
|
|
|
|
export default function handleRedirects(req, res, next) {
|
|
// never redirect assets
|
|
if (patterns.assetPaths.test(req.path)) return next()
|
|
|
|
// blanket redirects for languageless homepage
|
|
if (req.path === '/') {
|
|
let language = 'en'
|
|
|
|
// if set, redirect to user's preferred language translation or else English
|
|
if (
|
|
req.context.userLanguage &&
|
|
languages[req.context.userLanguage] &&
|
|
!languages[req.context.userLanguage].wip
|
|
) {
|
|
language = req.context.userLanguage
|
|
}
|
|
|
|
return res.redirect(301, `/${language}`)
|
|
}
|
|
|
|
// begin redirect handling
|
|
let redirect = req.path
|
|
let queryParams = req._parsedUrl.query
|
|
|
|
// update old-style query params (#9467)
|
|
// have to do this now because searchPath replacement changes the path as well as the query params
|
|
if (queryParams) {
|
|
queryParams = '?' + queryParams.replace('q=', 'query=')
|
|
redirect = (redirect + queryParams).replace(patterns.searchPath, '$1')
|
|
}
|
|
|
|
// remove query params temporarily so we can find the path in the redirects object
|
|
let redirectWithoutQueryParams = removeQueryParams(redirect)
|
|
|
|
// look for a redirect in the global object
|
|
// for example, given an incoming path /v3/activity/event_types
|
|
// find /en/developers/webhooks-and-events/github-event-types
|
|
redirectWithoutQueryParams =
|
|
req.context.redirects[redirectWithoutQueryParams] || redirectWithoutQueryParams
|
|
|
|
// add query params back in
|
|
redirect = queryParams ? redirectWithoutQueryParams + queryParams : redirectWithoutQueryParams
|
|
|
|
// do not redirect a path to itself
|
|
// req._parsedUrl.path includes query params whereas req.path does not
|
|
if (redirect === req._parsedUrl.path) return next()
|
|
|
|
// do not redirect if the redirected page can't be found
|
|
if (!req.context.pages[removeQueryParams(redirect)]) {
|
|
// display error on the page in development, but not in production
|
|
// include final full redirect path in the message
|
|
if (process.env.NODE_ENV !== 'production' && req.context) {
|
|
req.context.redirectNotFound = redirect
|
|
}
|
|
return next()
|
|
}
|
|
|
|
// do the redirect!
|
|
return res.redirect(301, redirect)
|
|
}
|
|
|
|
function removeQueryParams(redirect) {
|
|
return new URL(redirect, 'https://docs.github.com').pathname
|
|
}
|