Skip to content

Commit

Permalink
Add more feature flagging, lang setting, and serverless handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ijjk committed Oct 3, 2020
1 parent 4b654e7 commit de94016
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 18 deletions.
3 changes: 3 additions & 0 deletions packages/next/build/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ export function createEntrypoints(
loadedEnvFiles: Buffer.from(JSON.stringify(loadedEnvFiles)).toString(
'base64'
),
i18n: config.experimental.i18n
? JSON.stringify(config.experimental.i18n)
: '',
}

Object.keys(pages).forEach((page) => {
Expand Down
3 changes: 3 additions & 0 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,9 @@ export default async function getBaseWebpackConfig(
),
'process.env.__NEXT_ROUTER_BASEPATH': JSON.stringify(config.basePath),
'process.env.__NEXT_HAS_REWRITES': JSON.stringify(hasRewrites),
'process.env.__NEXT_i18n_SUPPORT': JSON.stringify(
!!config.experimental.i18n
),
...(isServer
? {
// Fix bad-actors in the npm ecosystem (e.g. `node-formidable`)
Expand Down
64 changes: 64 additions & 0 deletions packages/next/build/webpack/loaders/next-serverless-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export type ServerlessLoaderQuery = {
runtimeConfig: string
previewProps: string
loadedEnvFiles: string
i18n: string
}

const vercelHeader = 'x-vercel-id'
Expand All @@ -49,6 +50,7 @@ const nextServerlessLoader: loader.Loader = function () {
runtimeConfig,
previewProps,
loadedEnvFiles,
i18n,
}: ServerlessLoaderQuery =
typeof this.query === 'string' ? parse(this.query.substr(1)) : this.query

Expand All @@ -66,6 +68,8 @@ const nextServerlessLoader: loader.Loader = function () {
JSON.parse(previewProps) as __ApiPreviewProps
)

const i18nEnabled = !!i18n

const defaultRouteRegex = pageIsDynamicRoute
? `
const defaultRouteRegex = getRouteRegex("${page}")
Expand Down Expand Up @@ -207,6 +211,58 @@ const nextServerlessLoader: loader.Loader = function () {
`
: ''

const handleLocale = i18nEnabled
? `
// get pathname from URL with basePath stripped for locale detection
const i18n = ${i18n}
const accept = require('@hapi/accept')
const { detectLocaleCookie } = require('next/dist/next-server/lib/i18n/detect-locale-cookie')
const { normalizeLocalePath } = require('next/dist/next-server/lib/i18n/normalize-locale-path')
let detectedLocale = detectLocaleCookie(req, i18n.locales)
if (!detectedLocale) {
detectedLocale = accept.language(
req.headers['accept-language'],
i18n.locales
)
}
if (
!nextStartMode &&
i18n.localeDetection !== false &&
denormalizePagePath(parsedUrl.pathname || '/') === '/'
) {
res.setHeader(
'Location',
formatUrl({
// make sure to include any query values when redirecting
...parsedUrl,
pathname: \`/\${detectedLocale}\`,
})
)
res.statusCode = 307
res.end()
}
// TODO: domain based locales (domain to locale mapping needs to be provided in next.config.js)
const localePathResult = normalizeLocalePath(parsedUrl.pathname, i18n.locales)
if (localePathResult.detectedLocale) {
detectedLocale = localePathResult.detectedLocale
req.url = formatUrl({
...parsedUrl,
pathname: localePathResult.pathname,
})
parsedUrl.pathname = localePathResult.pathname
}
detectedLocale = detectedLocale || i18n.defaultLocale
`
: `
const i18n = {}
const detectedLocale = undefined
`

if (page.match(API_ROUTE)) {
return `
import initServer from 'next-plugin-loader?middleware=on-init-server!'
Expand Down Expand Up @@ -300,6 +356,7 @@ const nextServerlessLoader: loader.Loader = function () {
const { renderToHTML } = require('next/dist/next-server/server/render');
const { tryGetPreviewData } = require('next/dist/next-server/server/api-utils');
const { denormalizePagePath } = require('next/dist/next-server/server/denormalize-page-path')
const { setLazyProp, getCookieParser } = require('next/dist/next-server/server/api-utils')
const {sendPayload} = require('next/dist/next-server/server/send-payload');
const buildManifest = require('${buildManifest}');
const reactLoadableManifest = require('${reactLoadableManifest}');
Expand Down Expand Up @@ -333,6 +390,9 @@ const nextServerlessLoader: loader.Loader = function () {
export const _app = App
export async function renderReqToHTML(req, res, renderMode, _renderOpts, _params) {
const fromExport = renderMode === 'export' || renderMode === true;
const nextStartMode = renderMode === 'passthrough'
setLazyProp({ req }, 'cookies', getCookieParser(req))
const options = {
App,
Expand Down Expand Up @@ -383,12 +443,16 @@ const nextServerlessLoader: loader.Loader = function () {
routeNoAssetPath = parsedUrl.pathname
}
${handleLocale}
const renderOpts = Object.assign(
{
Component,
pageConfig: config,
nextExport: fromExport,
isDataReq: _nextData,
locale: detectedLocale,
locales: i18n.locales,
},
options,
)
Expand Down
17 changes: 11 additions & 6 deletions packages/next/client/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import '@next/polyfill-module'
import React from 'react'
import ReactDOM from 'react-dom'
import { HeadManagerContext } from '../next-server/lib/head-manager-context'
import { normalizeLocalePath } from '../next-server/lib/i18n/normalize-locale-path'
import mitt from '../next-server/lib/mitt'
import { RouterContext } from '../next-server/lib/router-context'
import type Router from '../next-server/lib/router/router'
Expand Down Expand Up @@ -90,12 +89,18 @@ if (hasBasePath(asPath)) {

asPath = delLocale(asPath, locale)

if (isFallback && locales) {
const localePathResult = normalizeLocalePath(asPath, locales)
if (process.env.__NEXT_i18n_SUPPORT) {
const {
normalizeLocalePath,
} = require('../next-server/lib/i18n/normalize-locale-path')

if (localePathResult.detectedLocale) {
asPath = asPath.substr(localePathResult.detectedLocale.length + 1)
locale = localePathResult.detectedLocale
if (isFallback && locales) {
const localePathResult = normalizeLocalePath(asPath, locales)

if (localePathResult.detectedLocale) {
asPath = asPath.substr(localePathResult.detectedLocale.length + 1)
locale = localePathResult.detectedLocale
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/next/export/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ export default async function exportPage({
fontManifest: optimizeFonts
? requireFontManifest(distDir, serverless)
: null,
locale: renderOpts.locale!,
locales: renderOpts.locales!,
},
// @ts-ignore
params
Expand Down
25 changes: 17 additions & 8 deletions packages/next/next-server/lib/router/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,21 @@ function addPathPrefix(path: string, prefix?: string) {
}

export function addLocale(path: string, locale?: string) {
return locale && !path.startsWith('/' + locale)
? addPathPrefix(path, '/' + locale)
: path
if (process.env.__NEXT_i18n_SUPPORT) {
return locale && !path.startsWith('/' + locale)
? addPathPrefix(path, '/' + locale)
: path
}
return path
}

export function delLocale(path: string, locale?: string) {
return locale && path.startsWith('/' + locale)
? path.substr(locale.length + 1) || '/'
: path
if (process.env.__NEXT_i18n_SUPPORT) {
return locale && path.startsWith('/' + locale)
? path.substr(locale.length + 1) || '/'
: path
}
return path
}

export function hasBasePath(path: string): boolean {
Expand Down Expand Up @@ -430,8 +436,11 @@ export default class Router implements BaseRouter {
this.isSsr = true

this.isFallback = isFallback
this.locale = locale
this.locales = locales

if (process.env.__NEXT_i18n_SUPPORT) {
this.locale = locale
this.locales = locales
}

if (typeof window !== 'undefined') {
// make sure "as" doesn't start with double slashes or else it can
Expand Down
1 change: 1 addition & 0 deletions packages/next/next-server/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ export type DocumentProps = DocumentInitialProps & {
headTags: any[]
unstable_runtimeJS?: false
devOnlyCacheBusterQueryString: string
locale?: string
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/next/next-server/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,7 @@ export default class Server {
{
fontManifest: this.renderOpts.fontManifest,
locale: (req as any)._nextLocale,
locales: this.renderOpts.locales,
}
)

Expand Down
1 change: 1 addition & 0 deletions packages/next/next-server/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ function renderDocument(
headTags,
unstable_runtimeJS,
devOnlyCacheBusterQueryString,
locale,
...docProps,
})}
</AmpStateContext.Provider>
Expand Down
3 changes: 2 additions & 1 deletion packages/next/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export function Html(
HTMLHtmlElement
>
) {
const { inAmpMode, docComponentsRendered } = useContext(
const { inAmpMode, docComponentsRendered, locale } = useContext(
DocumentComponentContext
)

Expand All @@ -132,6 +132,7 @@ export function Html(
return (
<html
{...props}
lang={props.lang || locale || undefined}
amp={inAmpMode ? '' : undefined}
data-ampdevmode={
inAmpMode && process.env.NODE_ENV !== 'production' ? '' : undefined
Expand Down
1 change: 1 addition & 0 deletions test/integration/i18n-support/next.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
// target: 'experimental-serverless-trace',
experimental: {
i18n: {
locales: ['nl-NL', 'nl-BE', 'nl', 'en-US', 'en'],
Expand Down
Loading

0 comments on commit de94016

Please sign in to comment.