Skip to content
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

i18n: seo #6860

Merged
merged 32 commits into from
Feb 14, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
31d658b
i18n v1 for SEO category.
exterkamp Dec 21, 2018
8c79982
Add link text test for multiple. Added link text displayValue label.
exterkamp Dec 21, 2018
c8b9f58
Removed imperative and reworded some description texts.
exterkamp Jan 2, 2019
42d8dda
Added multi-messages for font-size.
exterkamp Jan 2, 2019
60fc6b9
Reworded title descriptions based on feedback.
exterkamp Jan 3, 2019
b06fd1f
merge master
exterkamp Jan 29, 2019
8306ee7
Add SEO title i18n, fix tests.
exterkamp Jan 29, 2019
2c8eea0
Category description i18n.
exterkamp Jan 29, 2019
ffa4e7c
Add manual audit category desc.
exterkamp Jan 29, 2019
0570900
updated descriptions.
exterkamp Jan 31, 2019
f5b7751
merge in master
exterkamp Jan 31, 2019
7f47810
Adjusted text based on feedback.
exterkamp Feb 5, 2019
5b77efe
updated translations.
exterkamp Feb 5, 2019
3292058
Merge branch 'master' into i18n-seo
exterkamp Feb 5, 2019
b839a63
change for consistency to failureTitle.
exterkamp Feb 5, 2019
0f23dee
Forgot to update that last description in en-US.
exterkamp Feb 5, 2019
cf3ed80
merged in master...again
exterkamp Feb 11, 2019
feea7c3
Brendan feedback for robots.txt
exterkamp Feb 12, 2019
93a99bf
Brendan feedback on plugins.
exterkamp Feb 12, 2019
7b3fcb5
Brendan feedback for meta-desc, and manual seo audits.
exterkamp Feb 12, 2019
aa9bb0b
Brendan feedback for is crawlable and link text.
exterkamp Feb 12, 2019
62564d5
Brendan feedback for hreflang, canonical, http status code
exterkamp Feb 12, 2019
6dfbd5c
Added ticks to hreflang
exterkamp Feb 12, 2019
18a75ee
Brendan feedback font size and last part of robots.
exterkamp Feb 12, 2019
324db81
Update lighthouse-core/audits/seo/link-text.js
brendankenny Feb 12, 2019
5926722
Update lighthouse-core/audits/seo/manual/structured-data.js
brendankenny Feb 12, 2019
10cafea
Update lighthouse-core/audits/seo/manual/structured-data.js
brendankenny Feb 12, 2019
7294f93
Canonical fix maybe, and added suggestion changes to en-US.
exterkamp Feb 12, 2019
edea4fb
Feedback on canonical.
exterkamp Feb 12, 2019
b122256
removed toFixed(2). removed punctuation from canonical string. upda…
exterkamp Feb 12, 2019
2d36b31
changed displayValue naming
exterkamp Feb 12, 2019
4b692fa
Merge branch 'master' into i18n-seo
exterkamp Feb 14, 2019
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
45 changes: 35 additions & 10 deletions lighthouse-core/audits/seo/canonical.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ const LinkHeader = require('http-link-header');
const URL = require('../../lib/url-shim');
const MainResource = require('../../computed/main-resource.js');
const LINK_HEADER = 'link';
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** Imperative title of a Lighthouse audit that tells the user their site has a valid rel=canonical links. This is displayed in a list of audit titles that Lighthouse generates. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
title: 'Document has a valid `rel=canonical`',
/** Imperative title of a Lighthouse audit that tells the user their site has a valid rel=canonical links. This imperative title is shown to users when the rel=canonical link is invalid. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
failureTitle: 'Document does not have a valid `rel=canonical`',
/** Description of a Lighthouse audit that tells the user *why* they need to have a valid rel=canonical link. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'Canonical links suggest which URL to show in search results. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).',
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other. */
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by multiple URLs conflicting with each other. "urlList" will be replaced by a list of URLs (e.g. https://example.com, https://example2.com, etc ). */

explanationConflict: 'Multiple conflicting URLs ({urlList})',
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL being invalid. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL being invalid. */
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL being invalid. "url" will be replaced by the invalid URL (e.g. https://example.com). */

explanationInvalid: 'Invalid URL ({url})',
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL being relative. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
explanationRelative: 'Relative URL ({url})',
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context. */
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context. "href" will be replaced by the problematic URL (e.g. https://example.com). */

explanationPointsElsewhere: 'Points to another hreflang location ({href})',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is still a URL, so may be good to use the same url replacement term as the other explanations (will need to update the description if changing this one)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this should still always be a url. Good point!

/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain. */
/** [ICU Syntax] Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different domain. "url" will be replaced by the problematic URL (e.g. https://example.com). */

explanationDifferentDomain: 'Points to a different domain ({url})',
/** Explanatory message stating that there was a failure in an audit caused by a URL pointing to a root of the same origin. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
explanationRoot: 'Points to a root of the same origin',
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

/**
* @param {string} headerValue
Expand Down Expand Up @@ -62,10 +87,9 @@ class Canonical extends Audit {
static get meta() {
return {
id: 'canonical',
title: 'Document has a valid `rel=canonical`',
failureTitle: 'Document does not have a valid `rel=canonical`',
description: 'Canonical links suggest which URL to show in search results. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['Canonical', 'Hreflang', 'URL'],
};
}
Expand Down Expand Up @@ -118,7 +142,7 @@ class Canonical extends Audit {
if (canonicals.length > 1) {
return {
rawValue: false,
explanation: `Multiple conflicting URLs (${canonicals.join(', ')})`,
explanation: str_(UIStrings.explanationConflict, {urlList: canonicals.join(', ')}),
};
}

Expand All @@ -127,14 +151,14 @@ class Canonical extends Audit {
if (!isValidRelativeOrAbsoluteURL(canonical)) {
return {
rawValue: false,
explanation: `Invalid URL (${canonical})`,
explanation: str_(UIStrings.explanationInvalid, {url: canonical}),
};
}

if (!URL.isValid(canonical)) {
return {
rawValue: false,
explanation: `Relative URL (${canonical})`,
explanation: str_(UIStrings.explanationRelative, {url: canonical}),
};
}

Expand All @@ -145,7 +169,7 @@ class Canonical extends Audit {
baseURL.href !== canonicalURL.href) {
return {
rawValue: false,
explanation: `Points to another hreflang location (${baseURL.href})`,
explanation: str_(UIStrings.explanationPointsElsewhere, {href: baseURL.href}),
};
}

Expand All @@ -154,7 +178,7 @@ class Canonical extends Audit {
if (getPrimaryDomain(canonicalURL) !== getPrimaryDomain(baseURL)) {
return {
rawValue: false,
explanation: `Points to a different domain (${canonicalURL})`,
explanation: str_(UIStrings.explanationDifferentDomain, {url: canonicalURL}),
};
}

Expand All @@ -163,7 +187,7 @@ class Canonical extends Audit {
canonicalURL.pathname === '/' && baseURL.pathname !== '/') {
return {
rawValue: false,
explanation: 'Points to a root of the same origin',
explanation: str_(UIStrings.explanationRoot),
};
}

Expand All @@ -175,3 +199,4 @@ class Canonical extends Audit {
}

module.exports = Canonical;
module.exports.UIStrings = UIStrings;
12 changes: 8 additions & 4 deletions lighthouse-core/audits/seo/font-size.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const UIStrings = {
description: 'Font sizes less than 12px are too small to be legible and require mobile visitors to “pinch to zoom” in order to read. Strive to have >60% of page text ≥12px. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/font-sizes).',
/** [ICU Syntax] Label for the audit identifying font sizes that are too small. */
displayValue: '{decimalProportion, number, extendedPercent} legible text',
/** Explanatory message stating that there was a failure in an audit caused by a missing page viewport config. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
explanationViewport: 'Text is illegible because of a missing viewport config',
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
/** Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small. */
/** Explanatory message stating that there was a failure in an audit caused by a certain percentage of the text on the page being too small. "decimalProportion" will be replaced by a percentage between 0 and 100%. */

explanation: '{decimalProportion, number, extendedPercent} of text is too small{disclaimer}.',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
Expand Down Expand Up @@ -212,7 +216,7 @@ class FontSize extends Audit {
if (!hasViewportSet) {
return {
rawValue: false,
explanation: 'Text is illegible because of a missing viewport config',
explanation: str_(UIStrings.explanationViewport),
};
}

Expand Down Expand Up @@ -285,16 +289,16 @@ class FontSize extends Audit {

let explanation;
if (!passed) {
const percentageOfFailingText = parseFloat((100 - percentageOfPassingText).toFixed(2));
const percentageOfFailingText = parseFloat((100 - percentageOfPassingText).toFixed(2)) / 100;
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
let disclaimer = '';

// if we were unable to visit all text nodes we should disclose that information
if (visitedTextLength < totalTextLength) {
const percentageOfVisitedText = visitedTextLength / totalTextLength * 100;
disclaimer = ` (based on ${percentageOfVisitedText.toFixed()}% sample)`;
}

explanation = `${percentageOfFailingText}% of text is too small${disclaimer}.`;
explanation = str_(UIStrings.explanation,
{decimalProportion: percentageOfFailingText, disclaimer});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The {disclaimer} here is nested and will not be translated. Should we look into modifying i18n to have nested translations or combinations?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this (combining) would require a few additions elsewhere in the i18n handling right? (this is where I admit I don't know how i18n works here yet)

if (visitedTextLength < totalTextLength) {
	const percentageOfVisitedText = visitedTextLength / totalTextLength * 100;
	disclaimer = str_(UIStrings.explanation, {percentage: percentageOfVisitedText.toFixed()})
}
explanation = str_(UIStrings.explanation,
    {decimalProportion: percentageOfFailingText} + disclaimer)

That, or have two separate UIStrings for cases w/ the disclaimer and w/o.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll have to do str_(UIStrings.explanation, {decimalProportion) + ' ' + str_(UIStrings.disclaimer, {percentage})

it's not super kosher but it's better than having a random english string

the first argument to str_ must always be a statically known value

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The i18n replacement in the end can't replace 2 lookup strings can it, the output ends up like this afaik:
"lighthouse-core/audits/seo/font-size.js | explanation # 1 lighthouse-core/audits/seo/font-size.js | disclaimer # 0."
b/c it can't lookup 2 replacements in 1 string? Should we add that, or is there an option I'm not setting/seeing?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right we defer them to the end now, this is gonna be tricky 🤔 we might want to come up with a new format to handle this type of thing, like an I18NCombinedString object that gets replaced instead of just a normal string

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to some concat string handling (not nesting :).

As long as the constituent strings are findable statically, the human translators will understand and replacement should work fine after concatenating. We just need to get i18n.js to handle it without adding too much complexity.

Or what's the combinatorics on this audit? We could just defer on this and include multiple (partially redundant) explanation UIStrings.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or what's the combinatorics on this audit?

It's just two. I vote for deferring.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deferred by splitting into explanation with disclaimer and without

punted 🏈

}

return {
Expand Down
23 changes: 18 additions & 5 deletions lighthouse-core/audits/seo/hreflang.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ const MainResource = require('../../computed/main-resource.js');
const VALID_LANGS = importValidLangs();
const LINK_HEADER = 'link';
const NO_LANGUAGE = 'x-default';
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** Imperative title of a Lighthouse audit that tells the user the hreflang is valid for their site. This is displayed in a list of audit titles that Lighthouse generates. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
title: 'Document has a valid `hreflang`',
/** Imperative title of a Lighthouse audit that tells the user the hreflang is valid for their site. This imperative title is shown when the site does not have a valid hreflang element. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
failureTitle: 'Document doesn\'t have a valid `hreflang`',
/** Description of a Lighthouse audit that tells the user *why* they need to have an hreflang link on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Description of a Lighthouse audit that tells the user *why* they need to have an hreflang link on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
/** Description of a Lighthouse audit that tells the user *why* they need to have an hreflang link on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. "hreflang" is an HTML attribute and should not be translated. */

description: 'hreflang links tell search engines what version of a page they should ' +
'list in search results for a given language or region. [Learn more]' +
'(https://developers.google.com/web/tools/lighthouse/audits/hreflang).',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

/**
* Import list of valid languages from axe core without including whole axe-core package
Expand Down Expand Up @@ -65,11 +79,9 @@ class Hreflang extends Audit {
static get meta() {
return {
id: 'hreflang',
title: 'Document has a valid `hreflang`',
failureTitle: 'Document doesn\'t have a valid `hreflang`',
description: 'hreflang links tell search engines what version of a page they should ' +
'list in search results for a given language or region. [Learn more]' +
'(https://developers.google.com/web/tools/lighthouse/audits/hreflang).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['Hreflang', 'URL'],
};
}
Expand Down Expand Up @@ -119,3 +131,4 @@ class Hreflang extends Audit {
}

module.exports = Hreflang;
module.exports.UIStrings = UIStrings;
23 changes: 18 additions & 5 deletions lighthouse-core/audits/seo/http-status-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ const Audit = require('../audit');
const MainResource = require('../../computed/main-resource.js');
const HTTP_UNSUCCESSFUL_CODE_LOW = 400;
const HTTP_UNSUCCESSFUL_CODE_HIGH = 599;
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** Imperative title of a Lighthouse audit that tells the user their site has loaded with an appropriate HTTP status code. This is displayed in a list of audit titles that Lighthouse generates. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
title: 'Page has successful HTTP status code',
/** Imperative title of a Lighthouse audit that tells the user their site has loaded with an appropriate HTTP status code. This imperative title is shown when a site has sent an invalid HTTP status code. */
failureTitle: 'Page has unsuccessful HTTP status code',
/** Description of a Lighthouse audit that tells the user *why* they need to serve pages with a valid HTTP status code. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'Pages with unsuccessful HTTP status codes may not be indexed properly. ' +
'[Learn more]' +
'(https://developers.google.com/web/tools/lighthouse/audits/successful-http-code).',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class HTTPStatusCode extends Audit {
/**
Expand All @@ -17,11 +31,9 @@ class HTTPStatusCode extends Audit {
static get meta() {
return {
id: 'http-status-code',
title: 'Page has successful HTTP status code',
failureTitle: 'Page has unsuccessful HTTP status code',
description: 'Pages with unsuccessful HTTP status codes may not be indexed properly. ' +
'[Learn more]' +
'(https://developers.google.com/web/tools/lighthouse/audits/successful-http-code).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['devtoolsLogs', 'URL'],
};
}
Expand Down Expand Up @@ -55,3 +67,4 @@ class HTTPStatusCode extends Audit {
}

module.exports = HTTPStatusCode;
module.exports.UIStrings = UIStrings;
23 changes: 18 additions & 5 deletions lighthouse-core/audits/seo/is-crawlable.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ const BLOCKLIST = new Set([
]);
const ROBOTS_HEADER = 'x-robots-tag';
const UNAVAILABLE_AFTER = 'unavailable_after';
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** Imperative title of a Lighthouse audit that tells the user their page is not blocked from being indexed by search engine crawlers. This is displayed in a list of audit titles that Lighthouse generates. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
title: 'Page isn’t blocked from indexing',
/** Imperative title of a Lighthouse audit that tells the user their page is not blocked from being indexed by search engine crawlers. This imperative title is shown when the site has been blocked from indexing by search engine crawlers. */
failureTitle: 'Page is blocked from indexing',
/** Description of a Lighthouse audit that tells the user *why* they need to allow crawling on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Description of a Lighthouse audit that tells the user *why* they need to allow crawling on their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
/** Description of a Lighthouse audit that tells the user *why* allowing search-engine crawling of their page is beneficial. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */

description: 'Search engines are unable to include your pages in search results ' +
'if they don\'t have permission to crawl them. [Learn ' +
'more](https://developers.google.com/web/tools/lighthouse/audits/indexing).',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

/**
* Checks if given directive is a valid unavailable_after directive with a date in the past
Expand Down Expand Up @@ -64,11 +78,9 @@ class IsCrawlable extends Audit {
static get meta() {
return {
id: 'is-crawlable',
title: 'Page isn’t blocked from indexing',
failureTitle: 'Page is blocked from indexing',
description: 'Search engines are unable to include your pages in search results ' +
'if they don\'t have permission to crawl them. [Learn ' +
'more](https://developers.google.com/web/tools/lighthouse/audits/indexing).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['MetaRobots', 'RobotsTxt', 'URL'],
};
}
Expand Down Expand Up @@ -132,3 +144,4 @@ class IsCrawlable extends Audit {
}

module.exports = IsCrawlable;
module.exports.UIStrings = UIStrings;
29 changes: 23 additions & 6 deletions lighthouse-core/audits/seo/link-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ const BLOCKLIST = new Set([
'more',
'learn more',
]);
const i18n = require('../../lib/i18n/i18n.js');

const UIStrings = {
/** Imperative title of a Lighthouse audit that tells the user their links have descriptive enough text for a search engine crawler to parse them. This is displayed in a list of audit titles that Lighthouse generates. */
title: 'Links have descriptive text',
/** Imperative title of a Lighthouse audit that tells the user their links have descriptive enough text for a search engine crawler to parse them. This imperative title is shown when there are links on the page without proper text to describe them. */
failureTitle: 'Links do not have descriptive text',
/** Description of a Lighthouse audit that tells the user *why* they need to have descriptive text on the links in their page. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'Descriptive link text helps search engines understand your content. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text).',
/** [ICU Syntax] Label for the audit identifying the number of links found. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** [ICU Syntax] Label for the audit identifying the number of links found. */
/** [ICU Syntax] Label for the audit identifying the number of links found. "link" here refers to the links in a web page to other web pages. */

displayValue: `{itemCount, plural,
=1 {1 link found}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there any docs explaining how this format works

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other {# links found}
}`,
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

class LinkText extends Audit {
/**
Expand All @@ -26,10 +44,9 @@ class LinkText extends Audit {
static get meta() {
return {
id: 'link-text',
title: 'Links have descriptive text',
failureTitle: 'Links do not have descriptive text',
description: 'Descriptive link text helps search engines understand your content. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/descriptive-link-text).',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['URL', 'CrawlableLinks'],
};
}
Expand Down Expand Up @@ -68,8 +85,7 @@ class LinkText extends Audit {
let displayValue;

if (failingLinks.length) {
displayValue = failingLinks.length > 1 ?
`${failingLinks.length} links found` : '1 link found';
displayValue = str_(UIStrings.displayValue, {itemCount: failingLinks.length});
}

return {
Expand All @@ -81,3 +97,4 @@ class LinkText extends Audit {
}

module.exports = LinkText;
module.exports.UIStrings = UIStrings;
15 changes: 13 additions & 2 deletions lighthouse-core/audits/seo/manual/mobile-friendly.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
'use strict';

const ManualAudit = require('../../manual/manual-audit');
const i18n = require('../../../lib/i18n/i18n.js');

const UIStrings = {
/** Description of a Lighthouse audit that tells the user *why* and *how* they need to test their site to be mobile friendly. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'Take the [Mobile-Friendly Test](https://search.google.com/test/mobile-friendly) to check for audits not covered by Lighthouse, like sizing tap targets appropriately. [Learn more](https://developers.google.com/search/mobile-sites/).',
/** Imperative title of a Lighthouse audit that tells the user that their page is setup to be compatible with mobile devices such as cellphones. This is displayed in a list of audit titles that Lighthouse generates. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
title: 'Page is mobile friendly',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

/**
* @fileoverview Manual SEO audit to check if page is mobile friendly.
Expand All @@ -18,10 +28,11 @@ class MobileFriendly extends ManualAudit {
static get meta() {
return Object.assign({
id: 'mobile-friendly',
description: 'Take the [Mobile-Friendly Test](https://search.google.com/test/mobile-friendly) to check for audits not covered by Lighthouse, like sizing tap targets appropriately. [Learn more](https://developers.google.com/search/mobile-sites/).',
title: 'Page is mobile friendly',
description: str_(UIStrings.description),
title: str_(UIStrings.title),
}, super.partialMeta);
}
}

module.exports = MobileFriendly;
module.exports.UIStrings = UIStrings;
15 changes: 13 additions & 2 deletions lighthouse-core/audits/seo/manual/structured-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
'use strict';

const ManualAudit = require('../../manual/manual-audit');
const i18n = require('../../../lib/i18n/i18n.js');

const UIStrings = {
/** Description of a Lighthouse audit that tells the user *how* to test their page for using valid structured data. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'Run the [Structured Data Testing Tool](https://search.google.com/structured-data/testing-tool/) and the [Structured Data Linter](http://linter.structured-data.org/) to validate structured data. [Learn more](https://developers.google.com/search/docs/guides/mark-up-content).',
/** Imperative title of a Lighthouse audit that tells the user that their page has structured data. This is displayed in a list of audit titles that Lighthouse generates. */
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
title: 'Structured data is valid',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

/**
* @fileoverview Manual SEO audit to check if structured data on page is valid.
Expand All @@ -18,10 +28,11 @@ class StructuredData extends ManualAudit {
static get meta() {
return Object.assign({
id: 'structured-data',
description: 'Run the [Structured Data Testing Tool](https://search.google.com/structured-data/testing-tool/) and the [Structured Data Linter](http://linter.structured-data.org/) to validate structured data. [Learn more](https://developers.google.com/search/docs/guides/mark-up-content).',
title: 'Structured data is valid',
description: str_(UIStrings.description),
title: str_(UIStrings.title),
}, super.partialMeta);
}
}

module.exports = StructuredData;
module.exports.UIStrings = UIStrings;
Loading