Skip to content

Commit

Permalink
Merge branch 'canary' into feat/app-build-stats
Browse files Browse the repository at this point in the history
  • Loading branch information
ijjk committed Aug 10, 2022
2 parents d4aeabd + b15a976 commit 756f86a
Show file tree
Hide file tree
Showing 92 changed files with 1,081 additions and 673 deletions.
11 changes: 11 additions & 0 deletions .eslintrc.json
Expand Up @@ -71,6 +71,7 @@
"functions": false,
"classes": false,
"variables": false,
"enums": false,
"typedefs": false
}
],
Expand Down Expand Up @@ -106,6 +107,16 @@
{
"files": ["examples/**/*"],
"rules": {
"@typescript-eslint/no-use-before-define": [
"error",
{
"functions": true,
"classes": true,
"variables": true,
"enums": true,
"typedefs": true
}
],
"import/no-anonymous-default-export": [
"error",
{
Expand Down
32 changes: 29 additions & 3 deletions docs/api-reference/next/future/image.md
Expand Up @@ -251,11 +251,37 @@ See also:

### sizes

A string that provides information about how wide the image will be at different breakpoints.
A string that provides information about how wide the image will be at different breakpoints. The value of `sizes` will greatly affect performance for images using [`fill`](#fill) or which are styled to have a responsive size.

It's important to assign `sizes` for responsive images that takes up less than the full viewport width. For example, when the parent element will constrain the image to always be less than half the viewport width, use `sizes="50vw"`. Without `sizes`, the image will be sent at twice the necessary resolution, decreasing performance.
The `sizes` property serves two important purposes related to image performance:

[Learn more](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes).
First, the value of `sizes` is used by the browser to determine which size of the image to download, from `next/future/image`'s automatically-generated source set. When the browser chooses, it does not yet know the size of the image on the page, so it selects an image that is the same size or larger than the viewport. The `sizes` property allows you to tell the browser that the image will actually be smaller than full screen. If you don't specify a `sizes` value in an image with the `fill` property, a default value of `100vw` (full screen width) is used.

Second, the `sizes` property configures how `next/future/image` automatically generates an image source set. If no `sizes` value is present, a small source set is generated, suitable for a fixed-size image. If `sizes` is defined, a large source set is generated, suitable for a responsive image. If the `sizes` property includes sizes such as `50vw`, which represent a percentage of the viewport width, then the source set is trimmed to not include any values which are too small to ever be necessary.

For example, if you know your styling will cause an image to be full-width on mobile devices, in a 2-column layout on tablets, and a 3-column layout on desktop displays, you should include a sizes property such as the following:

```js
import Image from 'next/image'
const Example = () => (
<div className="grid-element">
<Image
src="/example.png"
layout="fill"
sizes="(min-width: 75em) 33vw,
(min-width: 48em) 50vw,
100vw"
/>
</div>
)
```

This example `sizes` could have a dramatic effect on performance metrics. Without the `33vw` sizes, the image selected from the server would be 3 times as wide as it needs to be. Because file size is proportional to the square of the width, without `sizes` the user would download an image that's 9 times larger than necessary.

Learn more about `srcset` and `sizes`:

- [web.dev](https://web.dev/learn/design/responsive-images/#sizes)
- [mdn](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes)

### quality

Expand Down
32 changes: 27 additions & 5 deletions docs/api-reference/next/image.md
Expand Up @@ -131,15 +131,37 @@ const MyImage = (props) => {

### sizes

A string that provides information about how wide the image will be at different breakpoints. Defaults to `100vw` (the full width of the screen) when using `layout="responsive"` or `layout="fill"`.
A string that provides information about how wide the image will be at different breakpoints. The value of `sizes` will greatly affect performance for images using `layout="responsive"` or `layout="fill"`. It will be ignored for images using `layout="intrinsic"` or `layout="fixed"`.

If you are using `layout="fill"` or `layout="responsive"` it's important to assign `sizes` for any image that takes up less than the full viewport width.
The `sizes` property serves two important purposes related to image performance:

For example, when the parent element will constrain the image to always be less than half the viewport width, use `sizes="50vw"`. Without `sizes`, the image will be sent at twice the necessary resolution, decreasing performance.
First, the value of `sizes` is used by the browser to determine which size of the image to download, from `next/image`'s automatically-generated source set. When the browser chooses, it does not yet know the size of the image on the page, so it selects an image that is the same size or larger than the viewport. The `sizes` property allows you to tell the browser that the image will actually be smaller than full screen. If you don't specify a `sizes` value, a default value of `100vw` (full screen width) is used.

If you are using `layout="intrinsic"` or `layout="fixed"`, then `sizes` is not needed because the upper bound width is constrained already.
Second, the `sizes` value is parsed and used to trim the values in the automatically-created source set. If the `sizes` property includes sizes such as `50vw`, which represent a percentage of the viewport width, then the source set is trimmed to not include any values which are too small to ever be necessary.

[Learn more](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes).
For example, if you know your styling will cause an image to be full-width on mobile devices, in a 2-column layout on tablets, and a 3-column layout on desktop displays, you should include a sizes property such as the following:

```js
import Image from 'next/image'
const Example = () => (
<div className="grid-element">
<Image
src="/example.png"
layout="fill"
sizes="(min-width: 75em) 33vw,
(min-width: 48em) 50vw,
100vw"
/>
</div>
)
```

This example `sizes` could have a dramatic effect on performance metrics. Without the `33vw` sizes, the image selected from the server would be 3 times as wide as it needs to be. Because file size is proportional to the square of the width, without `sizes` the user would download an image that's 9 times larger than necessary.

Learn more about `srcset` and `sizes`:

- [web.dev](https://web.dev/learn/design/responsive-images/#sizes)
- [mdn](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes)

### quality

Expand Down
6 changes: 4 additions & 2 deletions docs/api-reference/next/router.md
Expand Up @@ -248,14 +248,16 @@ export default function Page() {

Prefetch pages for faster client-side transitions. This method is only useful for navigations without [`next/link`](/docs/api-reference/next/link.md), as `next/link` takes care of prefetching pages automatically.

> This is a production only feature. Next.js doesn't prefetch pages on development.
> This is a production only feature. Next.js doesn't prefetch pages in development.
```jsx
router.prefetch(url, as)
router.prefetch(url, as, options)
```

- `url` - The URL to prefetch, including explicit routes (e.g. `/dashboard`) and dynamic routes (e.g. `/product/[id]`)
- `as` - Optional decorator for `url`. Before Next.js 9.5.3 this was used to prefetch dynamic routes, check our [previous docs](https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes) to see how it worked
- `options` - Optional object with the following allowed fields:
- `locale` - allows providing a different locale from the active one. If `false`, `url` has to include the locale as the active locale won't be used.

#### Usage

Expand Down
File renamed without changes.
10 changes: 8 additions & 2 deletions errors/manifest.json
Expand Up @@ -673,8 +673,14 @@
"path": "/errors/import-next.md"
},
{
"title": "invalid-getserversideprops-return-value",
"path": "/errors/invalid-getserversideprops-return-value.md"
"path": "/errors/invalid-getserversideprops-return-value.md",
"redirect": {
"destination": "/docs/messages/invalid-getserversideprops-value"
}
},
{
"title": "invalid-getserversideprops-value",
"path": "/errors/invalid-getserversideprops-value.md"
},
{
"title": "no-assign-module-variable",
Expand Down
8 changes: 4 additions & 4 deletions examples/amp-first/components/amp/AmpCustomElement.tsx
Expand Up @@ -319,6 +319,10 @@ export function AmpIncludeAmpLinkRewriter() {
return <AmpIncludeCustomElement name="amp-link-rewriter" version="0.1" />
}

export function AmpIncludeAmpMustache() {
return <AmpIncludeCustomTemplate name="amp-mustache" version="0.2" />
}

export function AmpIncludeAmpList() {
return (
<>
Expand Down Expand Up @@ -350,10 +354,6 @@ export function AmpIncludeAmpMowplayer() {
return <AmpIncludeCustomElement name="amp-mowplayer" version="0.1" />
}

export function AmpIncludeAmpMustache() {
return <AmpIncludeCustomTemplate name="amp-mustache" version="0.2" />
}

export function AmpIncludeAmpNextPage() {
return <AmpIncludeCustomElement name="amp-next-page" version="0.1" />
}
Expand Down
14 changes: 7 additions & 7 deletions examples/amp-first/components/amp/AmpScript.tsx
Expand Up @@ -10,6 +10,13 @@ type AmpScriptProps = {
src?: string
}

const generateInlineScript = (script: Function | string) => {
if (typeof script === 'function') {
return `${script.toString()}()`
}
return String(script)
}

/**
* Embeds an AMP Script by either linking to a TS `src` file or embedding inline
* AMP Script via the `script` property. The inline script hash will automatically
Expand Down Expand Up @@ -42,10 +49,3 @@ const AmpScript: React.FC<AmpScriptProps> = ({
}

export default AmpScript

const generateInlineScript = (script: Function | string) => {
if (typeof script === 'function') {
return `${script.toString()}()`
}
return String(script)
}
8 changes: 4 additions & 4 deletions examples/cms-agilitycms/lib/components/rich-text-area.tsx
@@ -1,3 +1,7 @@
const setHTML = (textblob) => {
return { __html: textblob }
}

export default function RichTextArea({ fields }) {
const { textblob } = fields
return (
Expand All @@ -7,7 +11,3 @@ export default function RichTextArea({ fields }) {
/>
)
}

const setHTML = (textblob) => {
return { __html: textblob }
}
34 changes: 17 additions & 17 deletions examples/cms-agilitycms/lib/dependancies.ts
Expand Up @@ -3,6 +3,23 @@ const path = require('path')
const userComponentsPath = path.resolve('./components')
const libComponentsPath = path.resolve('./lib/components')

const requireComponent = (name) => {
let Component = null

try {
//check the user path first (must be relative paths)
Component = require(`../components/${name}.tsx`).default
} catch {}

if (!Component)
try {
//fallback to lib path (must be relative paths)
Component = require(`./components/${name}.tsx`).default
} catch {}

return Component
}

//Bug: when dynamic imports are used within the module, it doest not get outputted server-side
//let AgilityModule = dynamic(() => import ('../components/' + m.moduleName));

Expand Down Expand Up @@ -32,20 +49,3 @@ export const requireComponentDependancyByName = (name) => {

return Component
}

const requireComponent = (name) => {
let Component = null

try {
//check the user path first (must be relative paths)
Component = require(`../components/${name}.tsx`).default
} catch {}

if (!Component)
try {
//fallback to lib path (must be relative paths)
Component = require(`./components/${name}.tsx`).default
} catch {}

return Component
}
104 changes: 52 additions & 52 deletions examples/cms-agilitycms/lib/preview.ts
Expand Up @@ -2,45 +2,27 @@ import crypto from 'crypto'
import { getClient } from './api'
import { CMS_LANG, CMS_CHANNEL } from './constants'

//Validates whether the incoming preview request is valid
export async function validatePreview({ agilityPreviewKey, slug, contentID }) {
//Validate the preview key
if (!agilityPreviewKey) {
return {
error: true,
message: `Missing agilitypreviewkey.`,
}
}

//sanitize incoming key (replace spaces with '+')
if (agilityPreviewKey.indexOf(` `) > -1) {
agilityPreviewKey = agilityPreviewKey.split(` `).join(`+`)
}

//compare the preview key being used
const correctPreviewKey = generatePreviewKey()
//Generates a preview key to compare against
export function generatePreviewKey() {
//the string we want to encode
const str = `-1_${process.env.AGILITY_CMS_SECURITY_KEY}_Preview`

if (agilityPreviewKey !== correctPreviewKey) {
return {
error: true,
message: `Invalid agilitypreviewkey.`,
//message: `Invalid agilitypreviewkey. Incoming key is=${agilityPreviewKey} compared to=${correctPreviewKey}...`
}
//build our byte array
let data = []
for (var i = 0; i < str.length; ++i) {
data.push(str.charCodeAt(i))
data.push(0)
}

const validateSlugResponse = await validateSlugForPreview({ slug, contentID })

if (validateSlugResponse.error) {
//kickout
return validateSlugResponse
}
//convert byte array to buffer
const strBuffer = Buffer.from(data)
//encode it!
const previewKey = crypto
.createHash('sha512')
.update(strBuffer)
.digest('base64')

//return success
return {
error: false,
message: null,
slug: validateSlugResponse.slug,
}
return previewKey
}

//Checks that the requested page exists, if not return a 401
Expand Down Expand Up @@ -95,25 +77,43 @@ export async function validateSlugForPreview({ slug, contentID }) {
}
}

//Generates a preview key to compare against
export function generatePreviewKey() {
//the string we want to encode
const str = `-1_${process.env.AGILITY_CMS_SECURITY_KEY}_Preview`
//Validates whether the incoming preview request is valid
export async function validatePreview({ agilityPreviewKey, slug, contentID }) {
//Validate the preview key
if (!agilityPreviewKey) {
return {
error: true,
message: `Missing agilitypreviewkey.`,
}
}

//build our byte array
let data = []
for (var i = 0; i < str.length; ++i) {
data.push(str.charCodeAt(i))
data.push(0)
//sanitize incoming key (replace spaces with '+')
if (agilityPreviewKey.indexOf(` `) > -1) {
agilityPreviewKey = agilityPreviewKey.split(` `).join(`+`)
}

//convert byte array to buffer
const strBuffer = Buffer.from(data)
//encode it!
const previewKey = crypto
.createHash('sha512')
.update(strBuffer)
.digest('base64')
//compare the preview key being used
const correctPreviewKey = generatePreviewKey()

return previewKey
if (agilityPreviewKey !== correctPreviewKey) {
return {
error: true,
message: `Invalid agilitypreviewkey.`,
//message: `Invalid agilitypreviewkey. Incoming key is=${agilityPreviewKey} compared to=${correctPreviewKey}...`
}
}

const validateSlugResponse = await validateSlugForPreview({ slug, contentID })

if (validateSlugResponse.error) {
//kickout
return validateSlugResponse
}

//return success
return {
error: false,
message: null,
slug: validateSlugResponse.slug,
}
}

0 comments on commit 756f86a

Please sign in to comment.