# DEPRECATED: This value is no longer updated. min_validator_revision_required: 475 # DEPRECATED: This value is no longer updated. spec_file_revision: 1188 styles_spec_url: "https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/style_pages/" script_spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/validation-workflow/validation_errors/#custom-javascript-is-not-allowed" # Validator extensions. # ===================== # In addition to the rules in this file, the Validator honors the rules # in the extensions/*/validator-*.protoascii files. This makes it # easy to organize the rules for extensions next to their Javascript # implementation. # Please read how the rules in this file works: # https://github.com/ampproject/amphtml/blob/fc447110e86db57e4391bf5c50de8dd2bf75e18f/docs/component-validator-rules.md # Rules for AMP HTML # https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml doc: { html_format: AMP4EMAIL max_bytes: 200000 max_bytes_spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/?format=email" } tags: { html_format: AMP html_format: AMP4EMAIL tag_name: "!DOCTYPE" spec_name: "html doctype" descriptive_name: "html !doctype" mandatory_parent: "$ROOT" mandatory: true unique: true explicit_attrs_only: true attrs: { name: "html" mandatory: true value: "" } # `lang` is not supported per spec but is allowed because it has been observed # on existing AMP documents. attrs: { name: "lang" deprecation: "html" deprecation_url: "https://github.com/ampproject/amphtml/issues/25926" } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } # AMP4ADS may need time to transition to using explicit attrs only. # Tracking in b/123227526 to merge into tagspec with spec name "html doctype". tags: { html_format: AMP4ADS tag_name: "!DOCTYPE" spec_name: "html doctype (AMP4ADS)" descriptive_name: "html !doctype" mandatory_parent: "$ROOT" mandatory: true unique: true attrs: { name: "html" mandatory: true value: "" } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } # Below, we list the allowed elements in the order in which they are appear # in the spec in section 4 "The Elements of HTML" # (http://www.w3.org/TR/html5/single-page#html-elements). # 4.1 The root element # 4.1.1 The html element tags: { # HTML tag for non-transformed AMP. html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL disabled_by: "transformed" tag_name: "HTML" mandatory: true mandatory_parent: "!DOCTYPE" unique: true spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } tags: { # HTML tag for transformed AMP. html_format: AMP enabled_by: "transformed" tag_name: "HTML" spec_name: "html (transformed)" mandatory: true mandatory_parent: "!DOCTYPE" unique: true attrs: { name: "i-amphtml-layout" value: "" } attrs: { name: "i-amphtml-no-boilerplate" value: "" } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } # 4.2 Document metadata # 4.2.1 The head element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "HEAD" mandatory: true mandatory_parent: "HTML" unique: true spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } # 4.2.2 The title element tags: { html_format: AMP html_format: AMP4ADS tag_name: "TITLE" spec_name: "title" attrs: { name: "[text]" } } tags: { html_format: AMP4EMAIL tag_name: "TITLE" spec_name: "title [AMP4EMAIL]" attrs: { name: "[text]" } deprecation: "Title tags in email have no meaning. This tag may become invalid in the future." deprecation_url: "https://github.com/ampproject/amphtml/issues/22318" } # 4.2.3 the base element tags: { html_format: AMP html_format: AMP4ADS tag_name: "BASE" unique: true mandatory_parent: "HEAD" # We only allow "/" right now because other value can cause havoc with PWA # implementations. In the future, it may be possible to widen this to any # absolute URL. attrs: { name: "href" value: "/" } attrs: { name: "target" value_casei: "_blank" value_casei: "_self" value_casei: "_top" } } # Disallowed. # 4.2.4 the link element attr_lists: { name: "common-link-attrs" attrs: { name: "charset" value_casei: "utf-8" } attrs: { name: "color" } attrs: { name: "crossorigin" } attrs: { name: "fetchpriority" value_casei: "high" value_casei: "low" value_casei: "auto" } attrs: { name: "hreflang" } attrs: { name: "media" } attrs: { name: "sizes" } attrs: { name: "target" } attrs: { name: "type" } } tags: { html_format: AMP html_format: AMP4ADS tag_name: "LINK" spec_name: "link rel=" disallowed_ancestor: "TEMPLATE" attrs: { name: "href" } attrs: { name: "rel" mandatory: true # There are a wide variety of link rel attribute values used in the wild as # this attribute is used as meta-data for any html client such as search # engines. Unfortunately, there are also a number of attribute values which # have behavioral impacts in modern browsers. A few places where these are # loosely documented include: # - http://microformats.org/wiki/existing-rel-values # - http://www.iana.org/assignments/link-relations/link-relations.xhtml # - https://html.spec.whatwg.org/#linkTypes # We denylist a few specific values which have browser behavior that could # negatively impact performance. # TODO(gregable): This could be improved such that the error message would # report which value in a list is the one causing problems. disallowed_value_regex: "(^|\\s)(" # Values are space separated. "canonical|" # Handled separately below, has specific requirements. "components|" "import|" "manifest|" # Handled separately below, has specific requirements. "modulepreload|" # Handled separately below, has specific requirements. "preload|" # Handled separately below, has specific requirements. "serviceworker|" "stylesheet|" # Handled separately below, has specific requirements. "subresource" ")(\\s|$)" # It is worth noting that user-authored tags for dns-prefectch, preconnect, # prefetch, and prerender will be disabled by the transformations applied # in the AMP Cache. Therefore, these hints will only be used on publisher # origins, not on the AMP Cache. } attr_lists: "common-link-attrs" spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } tags: { html_format: AMP tag_name: "LINK" spec_name: "link rel=canonical" descriptive_name: "link rel=canonical" mandatory_parent: "HEAD" mandatory: true unique: true attrs: { name: "href" mandatory: true value_url: { protocol: "http" protocol: "https" } disallowed_value_regex: "__amp_source_origin" } attrs: { name: "rel" value_casei: "canonical" mandatory: true dispatch_key: NAME_VALUE_DISPATCH } attr_lists: "common-link-attrs" spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } # Allow but not tags: { html_format: AMP html_format: AMP4ADS tag_name: "LINK" spec_name: "link rel=manifest" descriptive_name: "link rel=manifest" mandatory_parent: "HEAD" satisfies_condition: "amp-app-banner data source" attrs: { name: "href" mandatory: true value_url: { protocol: "https" } disallowed_value_regex: "__amp_source_origin" } attrs: { name: "rel" value_casei: "manifest" mandatory: true dispatch_key: NAME_VALUE_DISPATCH } attr_lists: "common-link-attrs" spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } tags: { html_format: AMP tag_name: "LINK" spec_name: "link rel=modulepreload" descriptive_name: "link rel=modulepreload" mandatory_parent: "HEAD" attrs: { name: "as" mandatory: true value: "script" } attrs: { name: "crossorigin" mandatory: true value: "anonymous" } attrs: { name: "href" mandatory: true value_regex: ".*\\.mjs$" } attrs: { name: "rel" mandatory: true value_casei: "modulepreload" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } tags: { html_format: AMP html_format: AMP4ADS tag_name: "LINK" spec_name: "link rel=preload" descriptive_name: "link rel=preload" disallowed_ancestor: "TEMPLATE" attrs: { name: "as" } attrs: { name: "href" } attrs: { name: "rel" mandatory: true value_casei: "preload" dispatch_key: NAME_VALUE_DISPATCH } attrs: { name: "imagesrcset" value_url: { protocol: "http" protocol: "https" } disallowed_value_regex: "__amp_source_origin" } attrs: { name: "imagesizes" } attr_lists: "common-link-attrs" spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # Allowlisted CSS provider tags: { html_format: AMP enabled_by: "transformed" tag_name: "LINK" spec_name: "link rel=stylesheet for amp-story-1.0 css" descriptive_name: "link rel=stylesheet for amp-story-1.0 css" mandatory_parent: "HEAD" attr_lists: "nonce-attr" attrs: { name: "crossorigin" } # SRI attribute (https://www.w3.org/TR/SRI/) attrs: { name: "href" mandatory: true value: "https://cdn.ampproject.org/v0/amp-story-1.0.css" value: "https://cdn.ampproject.org/lts/v0/amp-story-1.0.css" value: "https://ampjs.org/v0/amp-story-1.0.css" value: "https://ampjs.org/lts/v0/amp-story-1.0.css" } attrs: { name: "integrity" } # SRI attribute (https://www.w3.org/TR/SRI/) attrs: { name: "media" } attrs: { name: "rel" mandatory: true value_casei: "stylesheet" dispatch_key: NAME_VALUE_DISPATCH } attrs: { name: "type" value_casei: "text/css" } attrs: { name: "amp-extension" mandatory: true value_casei: "amp-story" } } # Allowlisted font providers tags: { html_format: AMP html_format: AMP4ADS tag_name: "LINK" spec_name: "link rel=stylesheet for fonts" descriptive_name: "link rel=stylesheet for fonts" named_id: LINK_FONT_STYLESHEET mandatory_parent: "HEAD" attr_lists: "nonce-attr" attrs: { name: "async" } attrs: { name: "crossorigin" } # SRI attribute (https://www.w3.org/TR/SRI/) attrs: { name: "href" mandatory: true value_regex: "https://cdn\\.materialdesignicons\\.com/" "([0-9]+\\.?)+/css/materialdesignicons\\.min\\.css|" "https://cloud\\.typography\\.com/" "[0-9]*/[0-9]*/css/fonts\\.css|" "https://fast\\.fonts\\.net/.*|" "https://fonts\\.googleapis\\.com/css2?\\?.*|" "https://fonts\\.googleapis\\.com/icon\\?.*|" "https://fonts\\.googleapis\\.com/earlyaccess/.*\\.css|" "https://maxcdn\\.bootstrapcdn\\.com/font-awesome/" "([0-9]+\\.?)+/css/font-awesome\\.min\\.css(\\?.*)?|" "https://(use|pro|kit)\\.fontawesome\\.com/releases/v([0-9]+\\.?)+" "/css/[0-9a-zA-Z-]+\\.css|" "https://(use|pro|kit)\\.fontawesome\\.com/[0-9a-zA-Z-]+\\.css|" "https://use\\.typekit\\.net/[\\w\\p{L}\\p{N}_]+\\.css|" "https://cdnjs\\.cloudflare\\.com/ajax/libs/font-awesome/" "([0-9]+\\.?)+/css/[0-9a-zA-Z-]+\\.min\\.css" } attrs: { name: "integrity" } # SRI attribute (https://www.w3.org/TR/SRI/) attrs: { name: "media" } attrs: { name: "rel" mandatory: true value_casei: "stylesheet" dispatch_key: NAME_VALUE_DISPATCH } attrs: { name: "type" value_casei: "text/css" } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#custom-fonts" } # itemprop=sameAs is allowed per schema.org, needs not be in head tags: { html_format: AMP html_format: AMP4ADS tag_name: "LINK" spec_name: "link itemprop=sameAs" descriptive_name: "link itemprop=sameAs" attrs: { name: "href" mandatory: true } attrs: { name: "itemprop" mandatory: true value_casei: "sameas" dispatch_key: NAME_VALUE_DISPATCH } attr_lists: "common-link-attrs" spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # rel= isn't mandatory when itemprop= is present. tags: { html_format: AMP html_format: AMP4ADS tag_name: "LINK" spec_name: "link itemprop=" descriptive_name: "link itemprop=" attrs: { name: "href" mandatory: true } attrs: { name: "itemprop" mandatory: true } attr_lists: "common-link-attrs" spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # rel= isn't mandatory when property= is present. tags: { html_format: AMP html_format: AMP4ADS tag_name: "LINK" spec_name: "link property=" descriptive_name: "link property=" attrs: { name: "href" mandatory: true } attrs: { name: "property" mandatory: true } attr_lists: "common-link-attrs" spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # 4.2.5 the meta element # Charset must be utf8, and a specific viewport is required. tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "META" spec_name: "meta charset=utf-8" descriptive_name: "meta charset=utf-8" mandatory: true mandatory_parent: "HEAD" unique: true attrs: { dispatch_key: NAME_DISPATCH name: "charset" mandatory: true value_casei: "utf-8" } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta name=viewport" descriptive_name: "meta name=viewport" mandatory: true mandatory_parent: "HEAD" unique: true attrs: { name: "content" mandatory: true value_properties: { properties: { name: "width" mandatory: true value: "device-width" } properties: { name: "height" } properties: { name: "initial-scale" } properties: { name: "minimum-scale" } properties: { name: "maximum-scale" } properties: { name: "shrink-to-fit" } properties: { name: "user-scalable" } properties: { name: "viewport-fit" } } } attrs: { name: "name" mandatory: true value: "viewport" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } # This tag is a hack to tell IE 10 to use its modern rendering engine as opposed # to the IE8 engine. So it's explicitly allowed. tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=X-UA-Compatible" descriptive_name: "meta http-equiv=X-UA-Compatible" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true value_properties: { properties: { name: "ie" value: "edge" } properties: { name: "chrome" value: "1" } } } attrs: { name: "http-equiv" mandatory: true value_casei: "x-ua-compatible" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # Tag specific to apple-itunes-app installs, see also . tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta name=apple-itunes-app" mandatory_parent: "HEAD" satisfies_condition: "amp-app-banner data source" attrs: { name: "content" mandatory: true value_regex: ".*app-id=.*" } attrs: { name: "name" value_casei: "apple-itunes-app" mandatory: true dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # AMP & AMP4ADS metadata, name=amp-experiments-opt-in # https://github.com/ampproject/amphtml/blob/main/tools/experiments/README.md tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta name=amp-experiments-opt-in" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-experiments-opt-in" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-3p-iframe-src tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-3p-iframe-src" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true value_url: { protocol: "https" } } attrs: { name: "name" mandatory: true value_casei: "amp-3p-iframe-src" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/components/amp-ad/" } # AMP metadata, name=amp-consent-blocking tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-consent-blocking" mandatory_parent: "HEAD" satisfies_condition: "meta name=amp-consent-blocking" unique: true attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-consent-blocking" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-experiment-token # Related to AMP Origin Experiments tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-experiment-token" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-experiment-token" dispatch_key: NAME_VALUE_DISPATCH } # Disabled because there are no active origin experiments; uncomment when # there is at least one corresponding `requires` clause. # satisfies_condition: "amp-experiment-token" } # AMP metadata, name=amp-link-variable-allowed-origin # https://github.com/ampproject/amphtml/issues/8132 tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-link-variable-allowed-origin" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-link-variable-allowed-origin" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-google-client-id-api tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-google-clientid-id-api" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-google-client-id-api" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-ad-doubleclick-sra # Enables SRA for amp-ad doubleclick Fast Fetch tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-ad-doubleclick-sra" mandatory_parent: "HEAD" attrs: { name: "name" mandatory: true value_casei: "amp-ad-doubleclick-sra" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-list-load-more tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-list-load-more" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-list-load-more" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-recaptcha-input tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-recaptcha-input" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-recaptcha-input" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-script-src tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-script-src" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-script-src" dispatch_key: NAME_VALUE_DISPATCH } } # AMP4ADS metadata, name=amp4ads-id # https://github.com/ampproject/amphtml/issues/7730 tags: { html_format: AMP4ADS tag_name: "META" spec_name: "meta name=amp4ads-id" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp4ads-id" dispatch_key: NAME_VALUE_DISPATCH } } tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "META" spec_name: "meta name= and content=" attrs: { name: "content" } attrs: { name: "itemprop" } # itemprop is non-standard, but commonly seen. # The validator accepts any name="..." attribute values except # for a few specific name values which have more specific rules above or # are altogether disallowed. attrs: { name: "name" disallowed_value_regex: "(^|\\s)(" "amp-.*|" "amp4ads-.*|" "apple-itunes-app|" "content-disposition|" "revisit-after|" "viewport" ")(\\s|$)" } attrs: { name: "media" } # For varying theme-color. attrs: { name: "property" } # property is non-standard, but commonly seen. # scheme is used by Dublin Core, see issue #13993 attrs: { name: "scheme" } } # This is redundant with meta charset, but also harmless as long as it's # set to utf-8. tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=Content-Type" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true value_casei: "text/html; charset=utf-8" } attrs: { name: "http-equiv" mandatory: true value_casei: "content-type" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # http-equiv content-language tag tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=content-language" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "http-equiv" mandatory: true value_casei: "content-language" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # http-equiv pics-label tag # https://www.w3.org/PICS/ tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=pics-label" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "http-equiv" mandatory: true value_casei: "pics-label" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # http-equiv imagetoolbar tag # https://msdn.microsoft.com/en-us/library/ms532986(v=vs.85).aspx tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=imagetoolbar" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "http-equiv" mandatory: true value_casei: "imagetoolbar" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # http-equiv content-style-type # https://www.w3.org/TR/REC-html40/present/styles#h-14.2.1 tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=Content-Style-Type" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true value_casei: "text/css" } attrs: { name: "http-equiv" mandatory: true value_casei: "content-style-type" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # http-equiv content-script-type # https://www.w3.org/TR/html4/interact/scripts#h-18.2.2.1 tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=Content-Script-Type" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true value_casei: "text/javascript" } attrs: { name: "http-equiv" mandatory: true value_casei: "content-script-type" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # http-equiv origin-trial tag tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=origin-trial" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "http-equiv" mandatory: true value_casei: "origin-trial" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # http-equiv resource-type # http://www.metatags.info/meta_http_equiv_resource_type tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta http-equiv=resource-type" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "http-equiv" mandatory: true value_casei: "resource-type" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # http-equiv x-dns-prefetch-control # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control tags: { html_format: AMP tag_name: "META" spec_name: "meta http-equiv=x-dns-prefetch-control" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true value_casei: "off" value_casei: "on" } attrs: { name: "http-equiv" mandatory: true value_casei: "x-dns-prefetch-control" dispatch_key: NAME_VALUE_DISPATCH } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags" } # AMP metadata, name=amp-ad-enable-refresh # Enables Refresh for amp-ad doubleclick Fast Fetch tags: { html_format: AMP html_format: AMP4ADS tag_name: "META" spec_name: "meta name=amp-ad-enable-refresh" mandatory_ancestor: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-ad-enable-refresh" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-to-amp-navigation # Enables AMP-to-AMP navigation tags: { html_format: AMP tag_name: "META" spec_name: "meta name=amp-to-amp-navigation" mandatory_parent: "HEAD" unique: true attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-to-amp-navigation" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-cta-type # Specifies the Single Page Story Ad call to action enum tags: { html_format: AMP4ADS tag_name: "META" spec_name: "meta name=amp-cta-type" mandatory_parent: "HEAD" unique: true attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-cta-type" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-cta-url # Specifies the Single Page Story Ad call to action outlink tags: { html_format: AMP4ADS tag_name: "META" spec_name: "meta name=amp-cta-url" mandatory_parent: "HEAD" unique: true attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_casei: "amp-cta-url" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp-cta-landing-page-type # Specifies the Single Page Story Ad landing page type tags: { html_format: AMP4ADS tag_name: "META" spec_name: "meta name=amp-cta-landing-page-type" mandatory_parent: "HEAD" unique: true attrs: { name: "content" mandatory: true value_casei: "amp" value_casei: "nonamp" value_casei: "story" } attrs: { name: "name" mandatory: true value_casei: "amp-cta-landing-page-type" dispatch_key: NAME_VALUE_DISPATCH } } # AMP metadata, name=amp4ads-vars-* # Allows advertisers to pass information from creatives # to be included in amp-ad-metadata. tags: { html_format: AMP4ADS tag_name: "META" spec_name: "meta name=amp4ads-vars-*" mandatory_parent: "HEAD" attrs: { name: "content" mandatory: true } attrs: { name: "name" mandatory: true value_regex: "amp4ads-vars-.+" } } # 4.2.6 The style # See `validator-css.protoascii`. # 4.3 Sections # 4.3.1 The body element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "BODY" mandatory: true unique: true mandatory_parent: "HTML" spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#required-markup" } # 4.3.2 The article element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "ARTICLE" } # 4.3.3 The section element attr_lists: { name: "poool-access-attrs" attrs: { name: "poool-access-preview" requires_extension: "amp-access-poool" } attrs: { name: "poool-access-content" requires_extension: "amp-access-poool" } } tags: { html_format: AMP html_format: AMP4ADS tag_name: "SECTION" disallowed_ancestor: "AMP-ACCORDION" attr_lists: "poool-access-attrs" } tags: { html_format: AMP4EMAIL tag_name: "SECTION" spec_name: "section (AMP4EMAIL)" disallowed_ancestor: "AMP-ACCORDION" } # 4.3.4 The nav element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "NAV" } # 4.3.5 The aside element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "ASIDE" } # 4.3.6 The h1, h2, h3, h4, h5, and h6 elements tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "H1" attrs: { name: "align" } } tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "H2" attrs: { name: "align" } } tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "H3" attrs: { name: "align" } } tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "H4" attrs: { name: "align" } } tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "H5" attrs: { name: "align" } } tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "H6" attrs: { name: "align" } } # 4.3 7 The header element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "HEADER" } # 4.3 7 The footer element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "FOOTER" } # 4.3 7 The address element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "ADDRESS" } # 4.4 Grouping Content # 4.4.1 The p element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "P" attrs: { name: "align" } } # 4.4.2 The hr element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "HR" } # 4.4.3 The pre element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "PRE" } # 4.4.4 The blockquote element attr_lists: { name: "cite-attr" attrs: { name: "cite" value_url: { protocol: "http" protocol: "https" allow_empty: true } disallowed_value_regex: "__amp_source_origin" } } tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "BLOCKQUOTE" attrs: { name: "align" } attr_lists: "cite-attr" } # 4.4.5 The ol element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "OL" attrs: { name: "reversed" value: "" } attrs: { name: "start" value_regex: "[0-9]*" } attrs: { name: "type" value_regex: "[1AaIi]" } } # 4.4.6 The ul element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "UL" } # 4.4.7 The li element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "LI" attrs: { name: "value" value_regex: "[0-9]*" } } # 4.4.8 The dl element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "DL" } # 4.4.9 The dt element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "DT" } # 4.4.10 The dd element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "DD" } # 4.4.11 The figure element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "FIGURE" } # 4.4.12 The figcaption element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "FIGCAPTION" } # 4.4.13 The div element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "DIV" attrs: { name: "align" } } # 4.4.14 The main element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "MAIN" } # 4.5 Text-level semantics # 4.5.1 The a element attr_lists: { # https://github.com/ampproject/amphtml/issues/35067 name: "click-attributions" attrs: { name: "attributiondestination" } attrs: { name: "attributionexpiry" } attrs: { name: "attributionreportto" } attrs: { name: "attributionsourceeventid" } attrs: { name: "attributionsourceid" } attrs: { name: "conversiondestination" } attrs: { name: "impressiondata" } attrs: { name: "impressionexpiry" } attrs: { name: "reportingorigin" } } tags: { html_format: AMP html_format: AMP4ADS tag_name: "A" attrs: { name: "attributionsrc" value_url: { protocol: "https" allow_empty: true } } attrs: { name: "border" } # Not valid html5 but commonly used and supported. attrs: { name: "download" } attrs: { name: "href" value_url: { # When updating this list, make sure to also update bind-validator.js. protocol: "ftp" protocol: "geo" protocol: "http" protocol: "https" protocol: "mailto" protocol: "maps" # Allowlisting additional commonly observed third party # protocols which should be safe. # BiP Messenger protocol: "bip" # Blackberry messenger # (http://devblog.blackberry.com/2015/02/cross-platform-sharing-with-bbm/) protocol: "bbmi" protocol: "chrome" # IOS over-the-air app installation # (https://github.com/nifcblm/AHPP-iOS-App/wiki/How-to-distribute-enterprise-iOS-App) protocol: "itms-services" protocol: "facetime" protocol: "fb-me" protocol: "fb-messenger" protocol: "feed" protocol: "intent" # Line messenger (https://media.line.me/howto/en/) protocol: "line" # (https://docs.microsoft.com/en-us/windows/uwp/launch-resume/launch-default-app#microsoft-edge-uri-scheme) protocol: "microsoft-edge" protocol: "skype" protocol: "sms" protocol: "snapchat" protocol: "tel" protocol: "tg" protocol: "threema" protocol: "twitter" protocol: "viber" protocol: "webcal" protocol: "web+mastodon" # See GitHub issue #14793 protocol: "wh" protocol: "whatsapp" allow_empty: true } disallowed_value_regex: "__amp_source_origin" } attrs: { name: "hreflang" } attrs: { name: "media" } attrs: { name: "referrerpolicy" } attrs: { name: "rel" # There are a wide variety of link rel attribute values used in the wild as # this attribute is used as meta-data for any html client such as search # engines. Unfortunately, there are also a number of attribute values which # have behavioral impacts in modern browsers. A few places where these are # loosely documented include: # - http://microformats.org/wiki/existing-rel-values # - http://www.iana.org/assignments/link-relations/link-relations.xhtml # - https://html.spec.whatwg.org/#linkTypes # We denylist a few specific values which have browser behavior that could # negatively impact performance. # TODO(gregable): This could be improved such that the error message would # report which value in a list is the one causing problems. disallowed_value_regex: "(^|\\s)(" # Values are space separated. "components|" "dns-prefetch|" "import|" "manifest|" "preconnect|" "prefetch|" "preload|" "prerender|" "serviceworker|" "stylesheet|" # Only allowed for link tags, specific req's for AMP. "subresource" ")(\\s|$)" } attrs: { name: "role" implicit: true } attrs: { name: "show-tooltip" value: "auto" value: "true" } attrs: { name: "tabindex" implicit: true } attrs: { name: "target" value: "_blank" value: "_self" value: "_top" } attrs: { name: "type" value_casei: "text/html" value_casei: "application/rss+xml" } attr_lists: "click-attributions" attr_lists: "name-attr" attr_lists: "private-click-measurement-attributes" # attrs: { name: "[href]" } spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#links" } # AMP4EMAIL restricts the use of mustache delimiters in href. The only allowed # protocols for href are http, https and mailto. Relative urls are disallowed. tags: { html_format: AMP4EMAIL tag_name: "A" spec_name: "A (AMP4EMAIL)" attrs: { name: "border" } # Not valid html5 but commonly used and supported. attrs: { name: "href" value_url: { protocol: "http" protocol: "https" protocol: "mailto" protocol: "tel" allow_relative: false } # Opening doubly curly brackets {{ (these are mustache delimiters) can only # appear at the beginning of the attribute's value. Likewise closing doubly # curly brackets }} can only appear at the end of the attribute's value. # Furthermore unbalanced delimiters are not allowed. # Additionally section mustache delimiters, i.e., {{#, {{^, {{/ are # disallowed. disallowed_value_regex: "__amp_source_origin|" "(.|\\s){{|" # Opening delimiter can only appear at the beginning. "}}(.|\\s)|" # Closing delimiter can only appear at the end. "^{{.*[^}][^}]$|" # Delimiters must be balanced. "^[^{][^{].*}}$|" # Delimiters must be balanced. "^}}|" # Also caught by the requirements on balanced delimiters. "{{$|" # Also caught by the requirements on balanced delimiters. "{{#|" # Section delimiters are disallowed. "{{/|" # Section delimiters are disallowed. "{{\\^" # Section delimiters are disallowed. } attrs: { name: "hreflang" } # TODO(gregable): Specify the set of allowed media queries. attrs: { name: "media" } attrs: { name: "role" implicit: true } attrs: { name: "tabindex" implicit: true } attrs: { name: "target" value: "_blank" } attrs: { name: "type" value_casei: "text/html" } } # Private Click Measurement attributes for anchor tags. # See https://github.com/ampproject/amphtml/issues/35067 attr_lists { name: "private-click-measurement-attributes" attrs: { name: "attributiondestination" } attrs: { name: "attributionexpiry" } attrs: { name: "attributionreportto" } attrs: { name: "attributionsourceeventid" } attrs: { name: "attributionsourceid" } attrs: { name: "conversiondestination" } attrs: { name: "impressiondata" } attrs: { name: "impressionexpiry" } attrs: { name: "reportingorigin" } } # 4.5.2 The em element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "EM" } # 4.5.3 The strong element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "STRONG" } # 4.5.4 The small element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "SMALL" } # 4.5.5 The s element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "S" } # 4.5.6 The cite element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "CITE" } # 4.5.7 The q element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "Q" attr_lists: "cite-attr" } # 4.5.8 The dfn element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "DFN" } # 4.5.9 The abbr element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "ABBR" } # 4.5.10 The data element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "DATA" } # 4.5.11 The time element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "TIME" attrs: { name: "datetime" } attrs: { name: "pubdate" value: "" } } # 4.5.12 The code element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "CODE" } # 4.5.13 The var element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "VAR" } # 4.5.14 The samp element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "SAMP" } # 4.5.15 The kbd element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "KBD" } # 4.5.16 The sub and sup elements tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "SUB" } tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "SUP" } # 4.5.17 The i element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "I" } # 4.5.18 The b element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "B" } # 4.5.19 The u element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "U" } # 4.5.20 The mark element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "MARK" } # 4.5.21 The ruby element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "RUBY" } # 4.5.22 The rb element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "RB" } # 4.5.23 The rt element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "RT" } # 4.5.24 The rtc element tags: { html_format: AMP html_format: AMP4ADS tag_name: "RTC" } # 4.5.25 The rp element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "RP" } # 4.5.26 The bdi element tags: { html_format: AMP html_format: AMP4ADS tag_name: "BDI" } # 4.5.27 The bdo element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "BDO" attrs: { name: "dir" } } # 4.5.28 The span element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "SPAN" } # 4.5.29 The br element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "BR" } # 4.5.30 The wbr element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "WBR" } # 4.6 Edits # 4.6.1 The ins element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "INS" # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins # These attributes have specific formatting, but as they are metadata # that can't hurt performance, rendering or security, we don't validate # the values. attrs { name: "datetime" } attr_lists: "cite-attr" } # 4.6.2 The del element tags: { html_format: AMP html_format: AMP4ADS html_format: AMP4EMAIL tag_name: "DEL" # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del # These attributes have specific formatting, but as they are metadata # that can't hurt performance, rendering or security, we don't validate # the values. attrs { name: "datetime" } attr_lists: "cite-attr" } # 4.7 Embedded Content # AMP HTML allows embedded content only via its own tags (e.g. amp-img), with # the exception of tags inside of a