Skip to content

Commit

Permalink
Merge branch 'canary' into feedthejim/next-1656-static-preload-prefet…
Browse files Browse the repository at this point in the history
…ch-doesnt-contain-loadingjs
  • Loading branch information
huozhi authored Sep 25, 2023
2 parents 531e876 + 69439d8 commit 8eade60
Show file tree
Hide file tree
Showing 119 changed files with 12,460 additions and 12,459 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,28 @@ export async function GET(request, { params }) {
| `app/items/[slug]/route.js` | `/items/b` | `{ slug: 'b' }` |
| `app/items/[slug]/route.js` | `/items/c` | `{ slug: 'c' }` |

### URL Query Parameters

The request object passed to the Route Handler is a `NextRequest` instance, which has [some additional convenience methods](/docs/app/api-reference/functions/next-request#nexturl), including for more easily handling query parameters.

```ts filename="app/api/search/route.ts" switcher
import { type NextRequest } from 'next/server'

export function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams
const query = searchParams.get('query')
// query is "hello" for /api/search?query=hello
}
```

```js filename="app/api/search/route.js" switcher
export function GET(request) {
const searchParams = request.nextUrl.searchParams
const query = searchParams.get('query')
// query is "hello" for /api/search?query=hello
}
```

### Streaming

Streaming is commonly used in combination with Large Language Models (LLMs), such as OpenAI, for AI-generated content. Learn more about the [AI SDK](https://sdk.vercel.ai/docs).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module.exports = {
> - Forms calling Server Actions from Server Components can function without JavaScript.
> - Forms calling Server Actions from Client Components will queue submissions if JavaScript isn't loaded yet, prioritizing client hydration.
> - Server Actions inherit the [runtime](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) from the page or layout they are used on.
> - Server Actions work with fully static routes (including revalidating data with ISR).
## Revalidating Cached Data

Expand Down
36 changes: 18 additions & 18 deletions docs/02-app/02-api-reference/01-components/image.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,24 @@ export default function Page() {
Here's a summary of the props available for the Image Component:

<div style={{ overflowX: 'auto', width: '100%' }}>
| Prop | Example | Type | Required | |
----------------------------------------- |
------------------------------------ | --------------- | -------- | |
[`src`](#src) | `src="/profile.png"` | String | Yes | | [`width`](#width) |
`width={500}` | Integer (px) | Yes | | [`height`](#height) | `height={500}` |
Integer (px) | Yes | | [`alt`](#alt) | `alt="Picture of the author"` | String
| Yes | | [`loader`](#loader) | `loader={imageLoader}` | Function | - | |
[`fill`](#fill) | `fill={true}` | Boolean | - | | [`sizes`](#sizes) |
`sizes="(max-width: 768px) 100vw"` | String | - | | [`quality`](#quality) |
`quality={80}` | Integer (1-100) | - | | [`priority`](#priority) | `priority=
{true}` | Boolean | - | | [`placeholder`](#placeholder) | `placeholder="blur"`
| String | - | | [`style`](#style) | `style={{ objectFit: 'contain' }}` | Object
| - | | [`onLoadingComplete`](#onloadingcomplete) | `onLoadingComplete=
{(img) => done()}` | Function | - | | [`onLoad`](#onload) | `onLoad=
{(event) => done()}` | Function | - | | [`onError`](#onerror) | `onError(event
=> fail()}` | Function | - | | [`loading`](#loading) | `loading="lazy"` | String
| - | | [`blurDataURL`](#blurdataurl) | `blurDataURL="data:image/jpeg..."` | String
| - |
| Prop | Example | Type | Required |
| ----------------------------------------- | ------------------------------------ | --------------- | -------- |
| [`src`](#src) | `src="/profile.png"` | String | Yes |
| [`width`](#width) | `width={500}` | Integer (px) | Yes |
| [`height`](#height) | `height={500}` | Integer (px) | Yes |
| [`alt`](#alt) | `alt="Picture of the author"` | String | Yes |
| [`loader`](#loader) | `loader={imageLoader}` | Function | - |
| [`fill`](#fill) | `fill={true}` | Boolean | - |
| [`sizes`](#sizes) | `sizes="(max-width: 768px) 100vw"` | String | - |
| [`quality`](#quality) | `quality={80}` | Integer (1-100) | - |
| [`priority`](#priority) | `priority={true}` | Boolean | - |
| [`placeholder`](#placeholder) | `placeholder="blur"` | String | - |
| [`style`](#style) | `style={{objectFit: "contain"}}` | Object | - |
| [`onLoadingComplete`](#onloadingcomplete) | `onLoadingComplete={img => done())}` | Function | - |
| [`onLoad`](#onload) | `onLoad={event => done())}` | Function | - |
| [`onError`](#onerror) | `onError(event => fail()}` | Function | - |
| [`loading`](#loading) | `loading="lazy"` | String | - |
| [`blurDataURL`](#blurdataurl) | `blurDataURL="data:image/jpeg..."` | String | - |
</div>

## Required Props
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export const size = {
export const contentType = 'image/png'

// Image generation
export default function Image() {
export default async function Image() {
// Font
const interSemiBold = fetch(
new URL('./Inter-SemiBold.ttf', import.meta.url)
Expand Down
38 changes: 38 additions & 0 deletions packages/next-swc/crates/next-core/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,44 @@ pub async fn env_for_js(
map.insert("__NEXT_STRICT_MODE_APP".to_string(), "true".to_string());
}

map.insert(
"__NEXT_STRICT_NEXT_HEAD".to_string(),
if next_config.experimental.strict_next_head.unwrap_or(false) {
"true".to_string()
} else {
"false".to_string()
},
);

map.insert(
"__NEXT_TRAILING_SLASH".to_string(),
if next_config.trailing_slash.unwrap_or(false) {
"true".to_string()
} else {
"false".to_string()
},
);

map.insert(
"__NEXT_ROUTER_BASEPATH".to_string(),
// Don't stringify undefined
if let Some(base_path) = next_config.base_path.as_ref() {
serde_json::to_string(base_path)?
} else {
"undefined".to_string()
},
);

map.insert(
"__NEXT_ASSET_PREFIX".to_string(),
// Don't stringify undefined
if let Some(asset_prefix) = next_config.asset_prefix.as_ref() {
serde_json::to_string(asset_prefix)?
} else {
"undefined".to_string()
},
);

if !test_mode.is_empty() {
map.insert("__NEXT_TEST_MODE".to_string(), "true".to_string());
}
Expand Down
7 changes: 4 additions & 3 deletions packages/next-swc/crates/next-core/src/next_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ pub struct NextConfig {
pub modularize_imports: Option<IndexMap<String, ModularizeImportPackageConfig>>,
pub dist_dir: Option<String>,
sass_options: Option<serde_json::Value>,
trailing_slash: bool,
pub trailing_slash: Option<bool>,
pub asset_prefix: Option<String>,
pub base_path: Option<String>,

// Partially supported
pub compiler: Option<CompilerConfig>,
Expand All @@ -96,8 +98,6 @@ pub struct NextConfig {
cross_origin: Option<String>,
amp: AmpConfig,
analytics_id: String,
asset_prefix: String,
base_path: String,
clean_dist_dir: bool,
compress: bool,
dev_indicators: DevIndicatorsConfig,
Expand Down Expand Up @@ -403,6 +403,7 @@ pub enum LoaderItem {
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)]
#[serde(rename_all = "camelCase")]
pub struct ExperimentalConfig {
pub strict_next_head: Option<bool>,
pub server_components_external_packages: Option<Vec<String>>,
pub turbo: Option<ExperimentalTurboConfig>,
pub allowed_revalidate_header_keys: Option<Vec<String>>,
Expand Down
61 changes: 20 additions & 41 deletions packages/next/src/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
isWebpackServerLayer,
} from './utils'
import { CustomRoutes } from '../lib/load-custom-routes.js'
import { isEdgeRuntime } from '../lib/is-edge-runtime'
import {
CLIENT_STATIC_FILES_RUNTIME_AMP,
CLIENT_STATIC_FILES_RUNTIME_MAIN,
Expand Down Expand Up @@ -285,35 +284,26 @@ function getOptimizedAliases(): { [pkg: string]: string } {
const stubObjectAssign = path.join(__dirname, 'polyfills', 'object-assign.js')

const shimAssign = path.join(__dirname, 'polyfills', 'object.assign')
return Object.assign(
{},
{
unfetch$: stubWindowFetch,
'isomorphic-unfetch$': stubWindowFetch,
'whatwg-fetch$': path.join(
__dirname,
'polyfills',
'fetch',
'whatwg-fetch.js'
),
},
{
'object-assign$': stubObjectAssign,

// Stub Package: object.assign
'object.assign/auto': path.join(shimAssign, 'auto.js'),
'object.assign/implementation': path.join(
shimAssign,
'implementation.js'
),
'object.assign$': path.join(shimAssign, 'index.js'),
'object.assign/polyfill': path.join(shimAssign, 'polyfill.js'),
'object.assign/shim': path.join(shimAssign, 'shim.js'),

// Replace: full URL polyfill with platform-based polyfill
url: require.resolve('next/dist/compiled/native-url'),
}
)
return {
unfetch$: stubWindowFetch,
'isomorphic-unfetch$': stubWindowFetch,
'whatwg-fetch$': path.join(
__dirname,
'polyfills',
'fetch',
'whatwg-fetch.js'
),
'object-assign$': stubObjectAssign,
// Stub Package: object.assign
'object.assign/auto': path.join(shimAssign, 'auto.js'),
'object.assign/implementation': path.join(shimAssign, 'implementation.js'),
'object.assign$': path.join(shimAssign, 'index.js'),
'object.assign/polyfill': path.join(shimAssign, 'polyfill.js'),
'object.assign/shim': path.join(shimAssign, 'shim.js'),

// Replace: full URL polyfill with platform-based polyfill
url: require.resolve('next/dist/compiled/native-url'),
}
}

// Alias these modules to be resolved with "module" if possible.
Expand Down Expand Up @@ -641,17 +631,6 @@ export default async function getBaseWebpackConfig(
? '-experimental'
: ''

if (isClient) {
if (
// @ts-expect-error: experimental.runtime is deprecated
isEdgeRuntime(config.experimental.runtime)
) {
Log.warn(
'You are using `experimental.runtime` which was removed. Check https://nextjs.org/docs/api-routes/edge-api-routes on how to use edge runtime.'
)
}
}

const babelConfigFile = await getBabelConfigFile(dir)
const distDir = path.join(dir, config.distDir)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,17 @@ if ('${method}' in entry) {
'${method}'
>
>()
${
''
// Adding void to support never return type without explicit return:
// e.g. notFound() will interrupt the execution but the handler return type is inferred as void.
// x-ref: https://github.com/microsoft/TypeScript/issues/16608#issuecomment-309327984
}
checkFields<
Diff<
{
__tag__: '${method}',
__return_type__: Response | Promise<Response>
__return_type__: Response | void | never | Promise<Response | void | never>
},
{
__tag__: '${method}',
Expand Down Expand Up @@ -428,7 +434,7 @@ declare module 'next/link' {
import type { LinkProps as OriginalLinkProps } from 'next/dist/client/link.js'
import type { AnchorHTMLAttributes, DetailedHTMLProps } from 'react'
import type { UrlObject } from 'url'
type LinkRestProps = Omit<
Omit<
DetailedHTMLProps<
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/lib/turbopack-warning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const supportedTurbopackNextConfigOptions = [
'assetPrefix',
'distDir',
'experimental.serverComponentsExternalPackages',
'experimental.strictNextHead',
'experimental.turbo',
'experimental.mdxRs',
'experimental.forceSwcTransforms',
Expand Down
9 changes: 8 additions & 1 deletion packages/next/src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,13 +325,20 @@ function assignDefaults(
}
}

// TODO: remove this in next major or minor version after 13.5
// TODO: Remove this warning in Next.js 14
warnOptionHasBeenDeprecated(
result,
'experimental.appDir',
'App router is available by default now, `experimental.appDir` option can be safely removed.',
silent
)
// TODO: Remove this warning in Next.js 14
warnOptionHasBeenDeprecated(
result,
'experimental.runtime',
'You are using `experimental.runtime` which was removed. Check https://nextjs.org/docs/api-routes/edge-api-routes on how to use edge runtime.',
silent
)
warnOptionHasBeenMovedOutOfExperimental(
result,
'relay',
Expand Down
1 change: 0 additions & 1 deletion packages/next/src/trace/trace-uploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import findUp from 'next/dist/compiled/find-up'
import fsPromise from 'fs/promises'
import child_process from 'child_process'
import assert from 'assert'
// @ts-ignore
import fetch from 'next/dist/compiled/node-fetch'
import os from 'os'
import { createInterface } from 'readline'
Expand Down
6 changes: 6 additions & 0 deletions packages/next/types/misc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ declare module 'next/dist/compiled/@next/react-refresh-utils/dist/ReactRefreshWe
export = m
}

declare module 'next/dist/compiled/node-fetch' {
import fetch from 'node-fetch'
export * from 'node-fetch'
export default fetch
}

declare module 'next/dist/compiled/node-html-parser' {
export * from 'node-html-parser'
}
Expand Down
34 changes: 28 additions & 6 deletions test/build-turbopack-tests-manifest.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
const fetch = require('node-fetch')
const fs = require('fs')
const prettier = require('prettier')

async function format(text) {
const options = await prettier.resolveConfig(__filename)
return prettier.format(text, { ...options, parser: 'json' })
}

const override = process.argv.includes('--override')

Expand Down Expand Up @@ -66,11 +72,11 @@ async function updatePassingTests() {
}

for (const info of Object.values(passing)) {
info.failed = [...new Set(info.failed)]
info.pending = [...new Set(info.pending)]
info.failed = [...new Set(info.failed)].sort()
info.pending = [...new Set(info.pending)].sort()
info.passed = [
...new Set(info.passed.filter((name) => !info.failed.includes(name))),
]
].sort()
}

if (!override) {
Expand All @@ -97,13 +103,29 @@ async function updatePassingTests() {
)
}
// Merge the old passing tests with the new ones
newData.passed = [...new Set([...oldData.passed, ...newData.passed])]
newData.passed = [
...new Set([...oldData.passed, ...newData.passed]),
].sort()
// but remove them also from the failed list
newData.failed = newData.failed.filter((name) => !shouldPass.has(name))
newData.failed = newData.failed
.filter((name) => !shouldPass.has(name))
.sort()
}
}

fs.writeFileSync(PASSING_JSON_PATH, JSON.stringify(passing, null, 2))
// JS keys are ordered, this ensures the tests are written in a consistent order
// https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key
const ordered = Object.keys(passing)
.sort()
.reduce((obj, key) => {
obj[key] = passing[key]
return obj
}, {})

fs.writeFileSync(
PASSING_JSON_PATH,
await format(JSON.stringify(ordered, null, 2))
)
}

function stripWorkingPath(path) {
Expand Down
3 changes: 0 additions & 3 deletions test/development/api-route-errors/app/pages/api/error.js

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 8eade60

Please sign in to comment.