Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions core/audits/seo/canonical.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,31 @@ class Canonical extends Audit {
if (!link.hrefRaw) continue;

// Links that had an hrefRaw but didn't have a valid href were invalid, flag them
if (!link.href) invalidCanonicalLink = link;
// Links that had a valid href but didn't have a valid hrefRaw must have been relatively resolved, flag them
else if (!UrlUtils.isValid(link.hrefRaw)) relativeCanonicallink = link;
// Otherwise, it was a valid canonical URL
else uniqueCanonicalURLs.add(link.href);
// if (!link.href) invalidCanonicalLink = link;
// // Links that had a valid href but didn't have a valid hrefRaw must have been relatively resolved, flag them
// else if (!UrlUtils.isValid(link.hrefRaw)) relativeCanonicallink = link;
// // Otherwise, it was a valid canonical URL
// else uniqueCanonicalURLs.add(link.href);

if (!link.href) {
invalidCanonicalLink = link;
} else {
let parsed;
try {
parsed = new URL(link.hrefRaw);
} catch {
invalidCanonicalLink = link;
continue;
}

if (!parsed.origin || parsed.origin === 'null') {
relativeCanonicallink = link;
} else {
uniqueCanonicalURLs.add(link.href);
}
}


} else if (link.rel === 'alternate') {
if (link.href && link.hreflang) hreflangURLs.add(link.href);
}
Expand Down
27 changes: 27 additions & 0 deletions core/test/audits/seo/canonical-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,33 @@ describe('SEO: Document has valid canonical link', () => {
});
});

it('fails when canonical url is invalid', async () => {
const mainDocumentUrl = 'https://example.com/';
const mainResource = {url: mainDocumentUrl};
const devtoolsLog = networkRecordsToDevtoolsLog([mainResource]);

const artifacts = {
DevtoolsLog: devtoolsLog,
URL: {mainDocumentUrl},
LinkElements: [
link({
rel: 'canonical',
source: 'headers',
href: null,
hrefRaw: 'example.com',
}),
],
};

const context = createContext();
const result = await Canonical.audit(artifacts, context);

expect(result.score).toBe(0);
expect(result.explanation)
.toContain('Invalid URL');
});


it('fails when canonical points to a different hreflang', () => {
const mainDocumentUrl = 'https://example.com/';
const mainResource = {url: mainDocumentUrl};
Expand Down