Develop a hint
Contributor guide
- Getting started
- Guides
- How to
Develop a hint
A hint is a group of related checks webhint will validate. The API should
be flexible enough to allow you to implement anything you want easily, e.g.:
- Validate that all links are
HTTPS. - Integrate with a third party service.
- Inject JavaScript to execute in the context of the page.
- etc.
If there is something you want to do and you can’t, or it is not clear how to do it, please open an issue.
Using the CLI to create a hint
The easiest way to create a new hint is via the create-hint package:
npm init hint |
This command will start a wizard that will ask you a series of questions related to this new hint. A complete list of the questions is shown below:
- What’s the name of this new hint?
- Please select the category of this new hint:
- accessibility
- development
- compatibility
- performance
- pwa
- pitfalls
- security
- What’s the description of this new hint?
- Please select the category of use case:
- DOM
- What DOM element does the hint need access to?
- Resource Request
- Third Party Service
- JS injection
- DOM
Answer these questions and you will end up with a template hint file. Events determined to be relevant to this use case will be subscribed to automatically in the script.
How hints work
The following is a basic template for a hint (imports might change
depending on the hint type):
import { Category } from '@hint/utils-types';
import { FetchEnd, IHint, HintMetadata } from 'hint/dist/src/lib/types';
import { HintContext } from 'hint/dist/src/lib/hint-context';
export default class MyNewHint implements IHint {
public static readonly meta: HintMetadata = {}
public constructor(context: HintContext) {
// Your code here.
const validateFetchEnd = (fetchEnd: FetchEnd) => {
// Code to validate the hint on the event fetch::end.
};
const validateElement = (element: ElementFound) => {
// Code to validate the hint on the event element::element-type.
};
context.on('element', validateElement);
context.on('fetch::end::*', validateFetchEnd);
// As many events as you need
}
} |
Hints are executed via events. There are several
events exposed by the connectors. The way to indicate which ones the hint cares
about is via the method create. This method returns an objects whose keys
are the names of the events and the values the event handlers:
{
"eventName1": "eventHandler1",
"eventName2": "eventHandler2"
} |
There is no limit to the number of events a hint can listen to, but you want to keep it as simple as possible.
Hint constructors receive a context object that makes it easier to interact
with the website and report errors.
To report an error, the hint has to do the following:
context.report(resource, message, { element: elementToReport }); |
resourceis the URL of what is being analyzed (HTML, JS, CSS, manifest, etc.)messageis the text to show to the user about the problem.optionsis an (optional) object that can contain the following:elementis an optionalHTMLElementwhere the issue was found (used to get aProblemLocationif one was not provided). For example, if an image is missing analtattribute, this can be theimgelement.codeSnippetis a string of source code to display (defaults to theouterHTMLofelement).contentis a string of text withinelementwhere the issue was found (used to refine aProblemLocation).;locationis an explicitProblemLocation({col: number, line: number}) where the issue was found. If used withelement, it represents an offset from the start of that element’s content (e.g. for inline CSS in HTML).severityoverrides the defaultSeverityfor the hint to determine how the issue will be reported (e.g.Severity.error).
On top or reporting errors, the context object exposes more information
to enable more complex scenarios. Some of the following sections describe them.
The meta property
Hints have an object meta that defines several properties:
{
"docs": {
"category": "Category",
"description": "string"
},
"id": "hint-id",
"recommended": "boolean", // If the hint is part of the recommended options
"schema": ["json schema"], // An array of valid JSON schemas
"worksWithLocalFiles": "boolean" // If the hint works with `file://`
} |
One of the most useful properties is schema. This property specifies
if the hint allows the user to configure it (other than the severity).
By default it should be an empty array if it doesn’t, or an array of
valid JSON schemas. These schemas will be used when
validating a .hintrc file. As long as there is one of the schemas
that passes, the configuration will be valid. This allows writting
simpler templates.
The hint can access the custom configuration via context.hintOptions.