Skip to content

Commit

Permalink
Merge branch 'canary' into font-defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
prateekbh authored Nov 17, 2020
2 parents 46fadf8 + ca590c4 commit 97932d4
Show file tree
Hide file tree
Showing 34 changed files with 433 additions and 42 deletions.
5 changes: 3 additions & 2 deletions .github/ISSUE_TEMPLATE/1.Bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ If applicable, add screenshots to help explain your problem.

- OS: [e.g. macOS, Windows]
- Browser (if applies) [e.g. chrome, safari]
- Version of Next.js: [e.g. 6.0.2]
- Version of Node.js: [e.g. 10.10.0]
- Version of Next.js: [e.g. 10.0.1]
- Version of Node.js: [e.g. 12.0.0]
- Deployment: [e.g. next start, next export, Vercel, other platform]

## Additional context

Expand Down
1 change: 1 addition & 0 deletions docs/basic-features/fast-refresh.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ local state being reset on every edit to a file:
- Sometimes, a file would export the result of calling higher-order component
like `HOC(WrappedComponent)`. If the returned component is a
class, state will be reset.
- Anonymous arrow functions like `export default () => <div />;` cause Fast Refresh to not preserve local component state. For large codebases you can use our [`name-default-component` codemod](/docs/advanced-features/codemods.md#name-default-component).

As more of your codebase moves to function components and Hooks, you can expect
state to be preserved in more cases.
Expand Down
4 changes: 4 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@
{
"title": "Migrating to Next.js",
"routes": [
{
"title": "Incrementally Adopting Next.js",
"path": "/docs/migrating/incremental-adoption.md"
},
{
"title": "Migrating from Gatsby",
"path": "/docs/migrating/from-gatsby.md"
Expand Down
77 changes: 77 additions & 0 deletions docs/migrating/incremental-adoption.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
description: Learn different strategies for incrementally adopting Next.js into your development workflow.
---

# Incrementally Adopting Next.js

<details>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/rewrites">Rewrites</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/redirects">Redirects</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-zones">Multi-Zones</a></li>
</ul>
</details>

Next.js has been designed from the start for gradual adoption. You can use as much (or as little) React as you need. By starting small and incrementally adding more pages, you can prevent derailing feature work by avoiding a complete rewrite.

## Strategies

### Subpath

If you need multiple applications on a single domain, you can take over an entire subpath. For example, you might deploy your Next.js e-commerce store at `acme.com/store`.

Using [`basePath`](/docs/api-reference/next.config.js/basepath.md), you can configure your Next.js application's assets and links to automatically work with your new subpath `/store`. Since each page in Next.js is its own [standalone route](/docs/routing/introduction.md), new files like `pages/products.js` will route to `acme.com/store/products` in your new application.

```jsx
// next.config.js

module.exports = {
basePath: '/store',
}
```

> This feature was introduced in [Next.js 9.5](https://nextjs.org/blog/next-9-5) and up. If you’re using older versions of Next.js, please upgrade before trying it out.
### Rewrites

If you plan on fully migrating your domain to Next.js, you can use [`rewrites`](/docs/api-reference/next.config.js/rewrites.md) inside `next.config.js`. This allows you to check your new routes before falling back to proxying your existing website.

For example, let's say you took over `/about` with Next.js. When a request for `acme.com/about` hits your Next.js application, it will serve the new page. A request for any other route (e.g. `acme.com/dashboard`) will fall back and proxy the URL you specify.

```jsx
// next.config.js

module.exports = {
async rewrites() {
return [
// we need to define a no-op rewrite to trigger checking
// all pages/static files before we attempt proxying
{
source: '/:path*',
destination: '/:path*',
},
{
source: '/:path*',
destination: `https://acme-proxy.com/:path*`,
},
]
},
}
```

> This feature was introduced in [Next.js 9.5](https://nextjs.org/blog/next-9-5) and up. If you’re using older versions of Next.js, please upgrade before trying it out.
### Micro-Frontends

Next.js and [Vercel](https://vercel.com) make it easy to adopt [micro-frontends](https://martinfowler.com/articles/micro-frontends.html) and deploy as a [Monorepo](https://vercel.com/blog/monorepos). This allows you to use [subdomains](https://en.wikipedia.org/wiki/Subdomain) to adopt new applications incrementally. Some benefits of micro-frontends:

- Smaller, more cohesive and maintainable codebases.
- More scalable organizations with decoupled, autonomous teams.
- The ability to upgrade, update, or even rewrite parts of the frontend in a more incremental fashion.

Once your monorepo is set up, push changes to your Git repository as usual and you'll see the commits deployed to the Vercel projects you've connected.

## Conclusion

To learn more, read about [subpaths](/docs/api-reference/next.config.js/basepath.md) and [rewrites](/docs/api-reference/next.config.js/rewrites.md) or [deploy an example with micro-frontends](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-zones).
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "10.0.2-canary.18"
"version": "10.0.2-canary.19"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"description": "ESLint plugin for NextJS.",
"main": "lib/index.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"license": "MIT",
"dependencies": {
"chalk": "4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-google-analytics/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-google-analytics",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-google-analytics"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-sentry/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-sentry",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-sentry"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)",
"main": "dist/polyfill-module.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
Expand Down
15 changes: 11 additions & 4 deletions packages/next/client/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ function prefetch(
throw err
}
})
const curLocale =
options && typeof options.locale !== 'undefined'
? options.locale
: router && router.locale

// Join on an invalid URI character
prefetched[href + '%' + as] = true
prefetched[href + '%' + as + (curLocale ? '%' + curLocale : '')] = true
}

function isModifiedEvent(event: React.MouseEvent) {
Expand Down Expand Up @@ -251,11 +256,13 @@ function Link(props: React.PropsWithChildren<LinkProps>) {
)
useEffect(() => {
const shouldPrefetch = isVisible && p && isLocalURL(href)
const isPrefetched = prefetched[href + '%' + as]
const curLocale =
typeof locale !== 'undefined' ? locale : router && router.locale
const isPrefetched =
prefetched[href + '%' + as + (curLocale ? '%' + curLocale : '')]
if (shouldPrefetch && !isPrefetched) {
prefetch(router, href, as, {
locale:
typeof locale !== 'undefined' ? locale : router && router.locale,
locale: curLocale,
})
}
}, [as, href, isVisible, locale, p, router])
Expand Down
30 changes: 20 additions & 10 deletions packages/next/next-server/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ export default class Server {
detectedLocale = detectedLocale || acceptPreferredLocale

let localeDomainRedirect: string | undefined
;(req as any).__nextHadTrailingSlash = pathname!.endsWith('/')

if (pathname === '/') {
;(req as any).__nextHadTrailingSlash = this.nextConfig.trailingSlash
}
const localePathResult = normalizeLocalePath(pathname!, i18n.locales)

if (localePathResult.detectedLocale) {
Expand All @@ -345,7 +350,12 @@ export default class Server {
pathname: localePathResult.pathname,
})
;(req as any).__nextStrippedLocale = true
parsedUrl.pathname = `${basePath || ''}${localePathResult.pathname}`
parsedUrl.pathname = `${basePath || ''}${localePathResult.pathname}${
(req as any).__nextHadTrailingSlash &&
localePathResult.pathname !== '/'
? '/'
: ''
}`
}

// If a detected locale is a domain specific locale and we aren't already
Expand Down Expand Up @@ -420,15 +430,15 @@ export default class Server {

res.setHeader(
'Location',
formatUrl({
// make sure to include any query values when redirecting
...parsed,
pathname: localeDomainRedirect
? localeDomainRedirect
: shouldStripDefaultLocale
? basePath || `/`
: `${basePath || ''}/${detectedLocale}`,
})
localeDomainRedirect
? localeDomainRedirect
: formatUrl({
// make sure to include any query values when redirecting
...parsed,
pathname: shouldStripDefaultLocale
? basePath || `/`
: `${basePath || ''}/${detectedLocale}`,
})
)
res.statusCode = 307
res.end()
Expand Down
7 changes: 7 additions & 0 deletions packages/next/next-server/server/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ export default class Router {
currentPathname === '/' ? '' : currentPathname
}`

if (
(req as any).__nextHadTrailingSlash &&
!currentPathname.endsWith('/')
) {
currentPathname += '/'
}

if (keepBasePath) {
currentPathname = `${this.basePath}${currentPathname}`
}
Expand Down
14 changes: 7 additions & 7 deletions packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down Expand Up @@ -63,10 +63,10 @@
"@ampproject/toolbox-optimizer": "2.7.0-alpha.1",
"@babel/runtime": "7.12.5",
"@hapi/accept": "5.0.1",
"@next/env": "10.0.2-canary.18",
"@next/polyfill-module": "10.0.2-canary.18",
"@next/react-dev-overlay": "10.0.2-canary.18",
"@next/react-refresh-utils": "10.0.2-canary.18",
"@next/env": "10.0.2-canary.19",
"@next/polyfill-module": "10.0.2-canary.19",
"@next/react-dev-overlay": "10.0.2-canary.19",
"@next/react-refresh-utils": "10.0.2-canary.19",
"ast-types": "0.13.2",
"babel-plugin-transform-define": "2.0.0",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
Expand Down Expand Up @@ -98,7 +98,7 @@
"schema-utils": "2.7.1",
"stream-browserify": "3.0.0",
"style-loader": "1.2.1",
"styled-jsx": "3.3.1",
"styled-jsx": "3.3.2",
"use-subscription": "1.5.1",
"vm-browserify": "1.1.2",
"watchpack": "2.0.0-beta.13",
Expand Down Expand Up @@ -128,7 +128,7 @@
"@babel/preset-react": "7.12.5",
"@babel/preset-typescript": "7.12.1",
"@babel/types": "7.12.6",
"@next/polyfill-nomodule": "10.0.2-canary.18",
"@next/polyfill-nomodule": "10.0.2-canary.19",
"@taskr/clear": "1.1.0",
"@taskr/esnext": "1.1.0",
"@taskr/watch": "1.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-dev-overlay/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/react-dev-overlay",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"description": "A development-only overlay for developing React applications.",
"repository": {
"url": "vercel/next.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-refresh-utils/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/react-refresh-utils",
"version": "10.0.2-canary.18",
"version": "10.0.2-canary.19",
"description": "An experimental package providing utilities for React Refresh.",
"repository": {
"url": "vercel/next.js",
Expand Down
6 changes: 6 additions & 0 deletions test/integration/client-navigation/lib/colored-blue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { css } from 'styled-jsx/css'
export const pBlue = css.resolve`
p {
color: blue;
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { pBlue } from '../lib/colored-blue'
export default () => (
<div>
<p id="blue-box" className={pBlue.className}>
This is blue
</p>
{pBlue.styles}
</div>
)
1 change: 1 addition & 0 deletions test/integration/client-navigation/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe('Client Navigation', () => {
'/fragment-syntax',
'/custom-extension',
'/styled-jsx',
'/styled-jsx-external',
'/with-cdm',
'/url-prop',
'/url-prop-override',
Expand Down
8 changes: 8 additions & 0 deletions test/integration/client-navigation/test/rendering.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,14 @@ export default function (render, fetch, ctx) {
expect(style.text().includes(`p.${styleId}{color:blue`)).toBeTruthy()
})

test('renders styled jsx external', async () => {
const $ = await get$('/styled-jsx-external')
const styleId = $('#blue-box').attr('class')
const style = $('style')

expect(style.text().includes(`p.${styleId}{color:blue`)).toBeTruthy()
})

test('renders properties populated asynchronously', async () => {
const html = await render('/async-props')
expect(html.includes('Diego Milito')).toBeTruthy()
Expand Down
Loading

0 comments on commit 97932d4

Please sign in to comment.