-
Notifications
You must be signed in to change notification settings - Fork 27k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(next/image): render valid html according to W3C #33825
fix(next/image): render valid html according to W3C #33825
Conversation
await waitFor(1000) | ||
expect(await browser.hasElementByCssSelector('img')).toBeTruthy() | ||
const url = await browser.url() | ||
const result = await validateHTML({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add this to the existing image-component test suite here instead and ensure the different layouts all validate correctly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, done! 👍
To keep things simple, I still added a new page /valid-html-w3c
in the default
folder.
This allows to support Node.js v12 (ref: zrrrzzt/html-validator@c3a11fa)
package.json
Outdated
@@ -112,6 +113,7 @@ | |||
"get-port": "5.1.1", | |||
"glob": "7.1.6", | |||
"gzip-size": "5.1.1", | |||
"html-validator": "5", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason this isn't using the latest version, 6?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, v6 dropped support for Node.js v12 (ref: zrrrzzt/html-validator@c3a11fa), hence failing the test using Node.js v12.
But Next.js support Node.js >= 12.22.0.
But yes instead to use 5
, we could use 5.1.18
. 👍
Co-authored-by: Steven <[email protected]>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There are a few failing tests, even if this PR fixes the W3C issue, it breaks a lot of things! Instead, to do the fix by adding Could you rerun the GitHub Actions to see if indeed reverting #33218 fixes the issue? 😄 |
it('should be valid W3C HTML', async () => { | ||
let browser | ||
try { | ||
browser = await webdriver(appPort, '/valid-html-w3c') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets loop through every page here to ensure all usages of the image component are valid HTML
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try but that requires a lot of changes to these pages because a lot of them are not valid W3C because of all kinds of errors like duplicated IDs etc. And I feel like it's unrelated to this PR.
Testing only with the /valid-html-w3c
page keeps things simple and only test what is really needed.
Will keep you updated! 👍
You should be able to run the tests locally with |
This comment has been minimized.
This comment has been minimized.
Thanks for the tip! I was using this command: It seems like all the tests pass except on the Azure side (no idea why it's completely unrelated tests that fail). |
Lets make sure to run validation on all pages. You can update the test to do |
Yes, here is what I did: it('should be valid W3C HTML', async () => {
let browser
const pages = readdirSync(join(appDir, 'pages'))
.filter((page) => {
return page !== '_document.js' && page !== '_app.js'
})
.map((page) => {
return `/${page.replace(/\.js$/, '')}`
})
for (const page of pages) {
console.log(`Validating ${page}`)
try {
browser = await webdriver(appPort, page)
await waitFor(1000)
expect(await browser.hasElementByCssSelector('img')).toBeTruthy()
const url = await browser.url()
const result = await validateHTML({
url,
format: 'json',
isLocal: true,
})
expect(result.messages).toEqual([])
} finally {
if (browser) {
await browser.close()
}
}
}
}) It is working, but there are so many W3C errors (whereas
So it makes sense to only test that we render valid HTML when the user correctly use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, we can add it in a follow up PR. Thanks!
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I encoded space as %20
now it passes validation 👍
Stats from current PRDefault Build (Decrease detected ✓)General Overall decrease ✓
Page Load Tests Overall decrease
|
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.439 | 3.439 | ✓ |
/ avg req/sec | 727.06 | 726.95 | |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.561 | 1.59 | |
/error-in-render avg req/sec | 1601.05 | 1572.09 |
Client Bundles (main, webpack, commons)
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
450.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42.2 kB | 42.2 kB | ✓ |
main-HASH.js gzip | 27.2 kB | 27.2 kB | ✓ |
webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
Overall change | 71 kB | 71 kB | ✓ |
Legacy Client Bundles (polyfills)
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages Overall increase ⚠️
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.37 kB | 1.37 kB | ✓ |
_error-HASH.js gzip | 194 B | 194 B | ✓ |
amp-HASH.js gzip | 312 B | 312 B | ✓ |
css-HASH.js gzip | 326 B | 326 B | ✓ |
dynamic-HASH.js gzip | 2.37 kB | 2.37 kB | ✓ |
head-HASH.js gzip | 350 B | 350 B | ✓ |
hooks-HASH.js gzip | 919 B | 919 B | ✓ |
image-HASH.js gzip | 4.93 kB | 4.94 kB | |
index-HASH.js gzip | 263 B | 263 B | ✓ |
link-HASH.js gzip | 2.19 kB | 2.19 kB | ✓ |
routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
script-HASH.js gzip | 383 B | 383 B | ✓ |
withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 14.3 kB | 14.4 kB |
Client Build Manifests Overall decrease ✓
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
_buildManifest.js gzip | 460 B | 459 B | -1 B |
Overall change | 460 B | 459 B | -1 B |
Rendered Page Sizes
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
index.html gzip | 530 B | 530 B | ✓ |
link.html gzip | 545 B | 545 B | ✓ |
withRouter.html gzip | 526 B | 526 B | ✓ |
Overall change | 1.6 kB | 1.6 kB | ✓ |
Diffs
Diff for _buildManifest.js
@@ -12,7 +12,7 @@ self.__BUILD_MANIFEST = {
],
"/head": ["static\u002Fchunks\u002Fpages\u002Fhead-7100d3b2a548f0e4.js"],
"/hooks": ["static\u002Fchunks\u002Fpages\u002Fhooks-538d621a0e670391.js"],
- "/image": ["static\u002Fchunks\u002Fpages\u002Fimage-2477effd702d0bcc.js"],
+ "/image": ["static\u002Fchunks\u002Fpages\u002Fimage-53463827ccaef972.js"],
"/link": ["static\u002Fchunks\u002Fpages\u002Flink-f0a2c3bb0706d8b2.js"],
"/routerDirect": [
"static\u002Fchunks\u002Fpages\u002FrouterDirect-76232dd6bc335a24.js"
Diff for image-HASH.js
@@ -662,9 +662,8 @@
wrapperStyle.maxWidth = "100%";
hasSizer = true;
sizerStyle.maxWidth = "100%";
- // url encoded svg is a little bit shorten than base64 encoding
- sizerSvgUrl = "data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 version=%271.1%27 width=%27"
- .concat(widthInt, "%27 height=%27")
+ sizerSvgUrl = "data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27"
+ .concat(widthInt, "%27%20height=%27")
.concat(heightInt, "%27/%3e");
} else if (layout === "fixed") {
// <Image src="i.png" width="100" height="100" layout="fixed" />
Default Build with SWC (Decrease detected ✓)
General Overall decrease ✓
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
buildDuration | 18.1s | 18.2s | |
buildDurationCached | 3.7s | 3.7s | -34ms |
nodeModulesSize | 358 MB | 358 MB | -95 B |
Page Load Tests Overall decrease ⚠️
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.443 | 3.394 | -0.05 |
/ avg req/sec | 726.13 | 736.52 | +10.39 |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.565 | 1.577 | |
/error-in-render avg req/sec | 1597.64 | 1585.09 |
Client Bundles (main, webpack, commons)
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
450.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
main-HASH.js gzip | 27.3 kB | 27.3 kB | ✓ |
webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
Overall change | 71.3 kB | 71.3 kB | ✓ |
Legacy Client Bundles (polyfills)
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages Overall increase ⚠️
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
_error-HASH.js gzip | 180 B | 180 B | ✓ |
amp-HASH.js gzip | 305 B | 305 B | ✓ |
css-HASH.js gzip | 321 B | 321 B | ✓ |
dynamic-HASH.js gzip | 2.36 kB | 2.36 kB | ✓ |
head-HASH.js gzip | 342 B | 342 B | ✓ |
hooks-HASH.js gzip | 911 B | 911 B | ✓ |
image-HASH.js gzip | 4.97 kB | 4.98 kB | |
index-HASH.js gzip | 256 B | 256 B | ✓ |
link-HASH.js gzip | 2.21 kB | 2.21 kB | ✓ |
routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
script-HASH.js gzip | 375 B | 375 B | ✓ |
withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 14.3 kB | 14.3 kB |
Client Build Manifests
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
_buildManifest.js gzip | 458 B | 458 B | ✓ |
Overall change | 458 B | 458 B | ✓ |
Rendered Page Sizes
vercel/next.js canary | Divlo/next.js fix/next-image-render-valid-html-w3c | Change | |
---|---|---|---|
index.html gzip | 531 B | 531 B | ✓ |
link.html gzip | 544 B | 544 B | ✓ |
withRouter.html gzip | 526 B | 526 B | ✓ |
Overall change | 1.6 kB | 1.6 kB | ✓ |
Diffs
Diff for _buildManifest.js
@@ -12,7 +12,7 @@ self.__BUILD_MANIFEST = {
],
"/head": ["static\u002Fchunks\u002Fpages\u002Fhead-7100d3b2a548f0e4.js"],
"/hooks": ["static\u002Fchunks\u002Fpages\u002Fhooks-538d621a0e670391.js"],
- "/image": ["static\u002Fchunks\u002Fpages\u002Fimage-2477effd702d0bcc.js"],
+ "/image": ["static\u002Fchunks\u002Fpages\u002Fimage-53463827ccaef972.js"],
"/link": ["static\u002Fchunks\u002Fpages\u002Flink-f0a2c3bb0706d8b2.js"],
"/routerDirect": [
"static\u002Fchunks\u002Fpages\u002FrouterDirect-76232dd6bc335a24.js"
Diff for image-HASH.js
@@ -662,9 +662,8 @@
wrapperStyle.maxWidth = "100%";
hasSizer = true;
sizerStyle.maxWidth = "100%";
- // url encoded svg is a little bit shorten than base64 encoding
- sizerSvgUrl = "data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 version=%271.1%27 width=%27"
- .concat(widthInt, "%27 height=%27")
+ sizerSvgUrl = "data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27"
+ .concat(widthInt, "%27%20height=%27")
.concat(heightInt, "%27/%3e");
} else if (layout === "fixed") {
// <Image src="i.png" width="100" height="100" layout="fixed" />
Great, good solution! 👍 (better than reverting). Thanks for your help. @styfle |
## Bug - [x] Fixes vercel#33809 - [x] Related to vercel#33218 - [x] Integration tests added: Usage of [html-validator](https://www.npmjs.com/package/html-validator) to validate the HTML. - [x] Errors have helpful link attached, see `contributing.md` (N/A)
Bug
contributing.md
(N/A)