Skip to content

Commit

Permalink
Merge branch 'canary' into update-image-test
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Jan 13, 2021
2 parents 4ef5ecf + 334ce64 commit 9a4be1c
Show file tree
Hide file tree
Showing 13 changed files with 532 additions and 37 deletions.
2 changes: 1 addition & 1 deletion docs/advanced-features/module-path-aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Next.js automatically supports the `tsconfig.json` and `jsconfig.json` `"paths"`

> Note: `jsconfig.json` can be used when you don't use TypeScript
These option allow you to configure module aliases, for example a common pattern is aliasing certain directories to use absolute paths.
These options allow you to configure module aliases, for example a common pattern is aliasing certain directories to use absolute paths.

One useful feature of these options is that they integrate automatically into certain editors, for example vscode.

Expand Down
4 changes: 2 additions & 2 deletions docs/basic-features/data-fetching.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ In the [Pages documentation](/docs/basic-features/pages.md), we’ve explained t
We’ll talk about the three unique Next.js functions you can use to fetch data for pre-rendering:

- [`getStaticProps`](#getstaticprops-static-generation) (Static Generation): Fetch data at **build time**.
- [`getStaticPaths`](#getstaticpaths-static-generation) (Static Generation): Specify [dynamic routes](/docs/routing/dynamic-routes.md) to pre-render based on data.
- [`getStaticPaths`](#getstaticpaths-static-generation) (Static Generation): Specify [dynamic routes](/docs/routing/dynamic-routes.md) to pre-render pages based on data.
- [`getServerSideProps`](#getserversideprops-server-side-rendering) (Server-side Rendering): Fetch data on **each request**.

In addition, we’ll talk briefly about how to fetch data on the client side.
Expand Down Expand Up @@ -791,7 +791,7 @@ This approach works well for user dashboard pages, for example. Because a dashbo
### SWR
The team behind Next.js has created a React hook for data fetching called [**SWR**](https://swr.now.sh/). We highly recommend it if you’re fetching data on the client side. It handles caching, revalidation, focus tracking, refetching on interval, and more. And you can use it like so:
The team behind Next.js has created a React hook for data fetching called [**SWR**](https://swr.vercel.app/). We highly recommend it if you’re fetching data on the client side. It handles caching, revalidation, focus tracking, refetching on interval, and more. And you can use it like so:
```jsx
import useSWR from 'swr'
Expand Down
175 changes: 175 additions & 0 deletions docs/migrating/from-react-router.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
---
description: Learn how to migrate from React Router to file-system based routes with Next.js.
---

# Migrating from React Router

This guide will help you understand how to transition from [React Router](https://reactrouter.com) to [file-system based](/docs/routing/introduction.md) routes with Next.js. Using [`next/link`](/docs/api-reference/next/link.md) and [`next/router`](/docs/api-reference/next/router.md) will allow you to:

- Decrease bundle size by removing React Router as a dependency.
- Define your application routes through the file system.
- Utilize the latest improvements to the Next.js framework.

## Basics

First, uninstall React Router. You'll be migrating to the built-in routing with Next.js.

```jsx
npm uninstall react-router-dom
```

The `Link` component for performing client-side route transitions is slightly different from React Router.

```jsx
// Before (React Router)
import { Link } from 'react-router-dom'

export default function App() {
return <Link to="/about">About</Link>
}

// After (Next.js)
import Link from 'next/link'

export default function App() {
return (
<Link href="/about">
<a>About</a>
</Link>
)
}
```

Most React applications that use React Router have a top-level navigation file, containing a list of routes. For example:

```jsx
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'

export default function App() {
return (
<Router>
<Switch>
<Route path="/about">
<h1>About</h1>
</Route>
<Route path="/blog">
<h1>Blog</h1>
</Route>
<Route path="/">
<h1>Home</h1>
</Route>
</Switch>
</Router>
)
}
```

With Next.js, you can express the same application structure in the file system. When a file is added to the [`pages`](/docs/basic-features/pages.md) directory it's automatically available as a route.

- `pages/about.js``/about`
- `pages/blog.js``/blog`
- `pages/index.js``/`

## Nested Routes

In the example below, routes like `/blog/my-post` would render the `Post` component. If a slug was not provided, it would render the list of all blog posts.

```jsx
import {
BrowserRouter as Router,
Switch,
Route,
useRouteMatch,
useParams,
} from 'react-router-dom'

export default function Blog() {
// Nested route under /blog
const match = useRouteMatch()

return (
<Router>
<Switch>
<Route path={`${match.path}/:slug`}>
<Post />
</Route>
<Route path={match.path}>
<h1>All Blog Posts</h1>
</Route>
</Switch>
</Router>
)
}

function Post() {
const { slug } = useParams()
return <h1>Post Slug: {slug}</h1>
}
```

Rather than using the `:slug` syntax inside your `Route` component, Next.js uses the `[slug]` syntax in the file name for [Dynamic Routes](/docs/routing/dynamic-routes.md). We can transform this to Next.js by creating two new files, `pages/blog/index.js` (showing all pages) and `pages/blog/[slug].js` (showing an individual post).

```jsx
// pages/blog/index.js

export default function Blog() {
return <h1>All Blog Posts</h1>
}

// pages/blog/[slug].js

import { useRouter } from 'next/router'

export default function Post() {
const router = useRouter()
const { slug } = router.query

return <h1>Post Slug: {slug}</h1>
}
```

## Server Rendering

Next.js has built-in support for [Server-side Rendering](/docs/basic-features/pages#server-side-rendering.md). This means you can remove any instances of `StaticRouter` in your code.

## Code Splitting

Next.js has built-in support for [Code Splitting](https://reactrouter.com/web/guides/code-splitting). This means you can remove any instances of:

- `@loadable/server`, `@loadable/babel-plugin`, and `@loadable/webpack-plugin`
- Modifications to your `.babelrc` for `@loadable/babel-plugin`

Each file inside your `pages/` directory will be code split into its own JavaScript bundle during the build process. Next.js [also supports](/docs/basic-features/supported-browsers-features.md#javascript-language-features) ES2020 dynamic `import()` for JavaScript. With it you can import JavaScript modules dynamically and work with them. They also work with SSR.

For more information, read about [Dynamic Imports](https://nextjs.org/docs/advanced-features/dynamic-import).

## Scroll Restoration

Next.js has built-in support for [Scroll Restoration](https://reactrouter.com/web/guides/scroll-restoration). This means you can remove any custom `ScrollToTop` components you have defined.

The default behavior of `next/link` and `next/router` is to scroll to the top of the page. You can also [disable this](https://nextjs.org/docs/api-reference/next/link#disable-scrolling-to-the-top-of-the-page) if you prefer.

## Learn More

For more information on what to do next, we recommend the following sections:

<div class="card">
<a href="/docs/routing/introduction.md">
<b>Routing:</b>
<small>Learn more about routing in Next.js.</small>
</a>
</div>

<div class="card">
<a href="/docs/routing/dynamic-routes.md">
<b>Dynamic Routes:</b>
<small>Learn more about the built-in dynamic routes.</small>
</a>
</div>

<div class="card">
<a href="/docs/api-reference/next/link.md">
<b>Pages:</b>
<small>Enable client-side transitions with next/link.</small>
</a>
</div>
68 changes: 68 additions & 0 deletions errors/conflicting-ssg-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Conflicting SSG Paths

#### Why This Error Occurred

In your `getStaticPaths` function for one of your pages you returned conflicting paths. All page paths must be unique and duplicates are not allowed.

#### Possible Ways to Fix It

Remove any conflicting paths shown in the error message and only return them from one `getStaticPaths`.

Example conflicting paths:

```jsx
// pages/hello/world.js
export default function Hello() {
return 'hello world!'
}

// pages/[...catchAll].js
export const getStaticProps = () => ({ props: {} })

export const getStaticPaths = () => ({
paths: [
// this conflicts with the /hello/world.js page, remove to resolve error
'/hello/world',
'/another',
],
fallback: false,
})

export default function CatchAll() {
return 'Catch-all page'
}
```

Example conflicting paths:

```jsx
// pages/blog/[slug].js
export const getStaticPaths = () => ({
paths: ['/blog/conflicting', '/blog/another'],
fallback: false,
})

export default function Blog() {
return 'Blog!'
}

// pages/[...catchAll].js
export const getStaticProps = () => ({ props: {} })

export const getStaticPaths = () => ({
paths: [
// this conflicts with the /blog/conflicting path above, remove to resolve error
'/blog/conflicting',
'/another',
],
fallback: false,
})

export default function CatchAll() {
return 'Catch-all page'
}
```

### Useful Links

- [`getStaticPaths` Documentation](https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation)
8 changes: 5 additions & 3 deletions examples/with-polyfills/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Example app with polyfills
# With Polyfills

> ❗️ Warning: This example is not the suggested way to add polyfills and is known to cause issues with bundling. See [the browser support docs](https://nextjs.org/docs/basic-features/supported-browsers-features#custom-polyfills) for the correct way to load polyfills.
Next.js supports IE11 and all modern browsers (Edge, Firefox, Chrome, Safari, Opera, et al) with no required configuration. It also adds [some polyfills](https://nextjs.org/docs/basic-features/supported-browsers-features#polyfills) by default.

Next.js supports modern browsers and IE 11. It loads required polyfills automatically. If you need to add custom polyfills, you can follow this example.
If your own code or any external npm dependencies require features not supported by your target browsers, you need to add polyfills yourself.

In this case, you should add a top-level import for the specific polyfill you need in your Custom `<App>` or the individual component.

## Deploy your own

Expand Down
8 changes: 0 additions & 8 deletions examples/with-polyfills/client/polyfills.js

This file was deleted.

19 changes: 0 additions & 19 deletions examples/with-polyfills/next.config.js

This file was deleted.

4 changes: 2 additions & 2 deletions examples/with-polyfills/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
},
"dependencies": {
"next": "latest",
"react": "^16.7.0",
"react-dom": "^16.7.0"
"react": "latest",
"react-dom": "latest"
},
"license": "MIT"
}
9 changes: 9 additions & 0 deletions examples/with-polyfills/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Add your polyfills here or at the component level.
// For example...
// import 'resize-observer-polyfill'

function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}

export default MyApp
2 changes: 0 additions & 2 deletions examples/with-polyfills/pages/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
console.log('Inside the /index.js page')

export default function Home() {
return <div>Hello World</div>
}
10 changes: 10 additions & 0 deletions packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import createSpinner from './spinner'
import { traceAsyncFn, traceFn, tracer } from './tracer'
import {
collectPages,
detectConflictingPaths,
getJsPageSizeInKb,
getNamedExports,
hasCustomGetInitialProps,
Expand Down Expand Up @@ -870,6 +871,15 @@ export default async function build(
await traceAsyncFn(tracer.startSpan('static-generation'), async () => {
if (staticPages.size > 0 || ssgPages.size > 0 || useStatic404) {
const combinedPages = [...staticPages, ...ssgPages]

detectConflictingPaths(
[
...combinedPages,
...pageKeys.filter((page) => !combinedPages.includes(page)),
],
ssgPages,
additionalSsgPaths
)
const exportApp = require('../export').default
const exportOptions = {
silent: false,
Expand Down
Loading

0 comments on commit 9a4be1c

Please sign in to comment.