CINXE.COM
Documentation: <amp-bind> - amp.dev
<!doctype html><html amp lang="en" i-amphtml-binding i-amphtml-layout i-amphtml-no-boilerplate transformed="self;v=1"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><link rel="preload" href="/static/fonts/poppins-v5-latin-700.woff2" as="font" crossorigin><link rel="preload" href="/static/fonts/noto-sans-v7-latin-700.woff2" as="font" crossorigin><meta name="theme-color" content="#005af0"><meta name="description" content="Allows elements to mutate in response to user actions or data changes via data binding and simple JS-like expressions."><meta name="twitter:card" content="summary_large_image"><meta name="twitter:description" content="Allows elements to mutate in response to user actions or data changes via data binding and simple JS-like expressions."><meta name="twitter:title" content="Documentation: amp-bind"><meta name="twitter:creator" content="@ampproject"><meta name="twitter:site" content="@ampproject"><meta name="twitter:image" content="https://amp.dev/static/img/sharing/docs-component-600x314.png"><meta property="og:title" content="Documentation: <amp-bind>"><meta property="og:url" content="https://amp.dev/documentation/components/amp-bind/"><meta property="og:image" content="https://amp.dev/static/img/sharing/docs-component-600x314.png"><meta property="og:image:width" content="600"><meta property="og:image:height" content="314"><meta name="supported-amp-formats" content="websites,ads,email"><meta name="page-locale" content="en,de,pt_br,ru,zh_cn,pl,vi"><meta http-equiv="origin-trial" content="AviuuiVhVdQ3GpVtxSpyMT+XsL/qGGYmyiyLvYSKPL3rRDLipe/ard5x+DXVlrATtolwX75VtpSKc9IEzLDd4AkAAABmeyJvcmlnaW4iOiJodHRwczovL2FtcC5kZXY6NDQzIiwiZmVhdHVyZSI6IkV4cGVyaW1lbnRhbEF1dG9wbGF5RHluYW1pY0RlbGVnYXRpb24iLCJleHBpcnkiOjE1NzA1Nzg0NDF9"><style amp-runtime i-amphtml-version="012406131415000">html{overflow-x:hidden!important}html.i-amphtml-fie{height:100%!important;width:100%!important}html:not([amp4ads]),html:not([amp4ads]) body{height:auto!important}html:not([amp4ads]) body{margin:0!important}body{-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}html.i-amphtml-singledoc.i-amphtml-embedded{-ms-touch-action:pan-y pinch-zoom;touch-action:pan-y pinch-zoom}html.i-amphtml-fie>body,html.i-amphtml-singledoc>body{overflow:visible!important}html.i-amphtml-fie:not(.i-amphtml-inabox)>body,html.i-amphtml-singledoc:not(.i-amphtml-inabox)>body{position:relative!important}html.i-amphtml-ios-embed-legacy>body{overflow-x:hidden!important;overflow-y:auto!important;position:absolute!important}html.i-amphtml-ios-embed{overflow-y:auto!important;position:static}#i-amphtml-wrapper{overflow-x:hidden!important;overflow-y:auto!important;position:absolute!important;top:0!important;left:0!important;right:0!important;bottom:0!important;margin:0!important;display:block!important}html.i-amphtml-ios-embed.i-amphtml-ios-overscroll,html.i-amphtml-ios-embed.i-amphtml-ios-overscroll>#i-amphtml-wrapper{-webkit-overflow-scrolling:touch!important}#i-amphtml-wrapper>body{position:relative!important;border-top:1px solid transparent!important}#i-amphtml-wrapper+body{visibility:visible}#i-amphtml-wrapper+body .i-amphtml-lightbox-element,#i-amphtml-wrapper+body[i-amphtml-lightbox]{visibility:hidden}#i-amphtml-wrapper+body[i-amphtml-lightbox] .i-amphtml-lightbox-element{visibility:visible}#i-amphtml-wrapper.i-amphtml-scroll-disabled,.i-amphtml-scroll-disabled{overflow-x:hidden!important;overflow-y:hidden!important}amp-instagram{padding:54px 0px 0px!important;background-color:#fff}amp-iframe iframe{box-sizing:border-box!important}[amp-access][amp-access-hide]{display:none}[subscriptions-dialog],body:not(.i-amphtml-subs-ready) [subscriptions-action],body:not(.i-amphtml-subs-ready) [subscriptions-section]{display:none!important}amp-experiment,amp-live-list>[update]{display:none}amp-list[resizable-children]>.i-amphtml-loading-container.amp-hidden{display:none!important}amp-list [fetch-error],amp-list[load-more] [load-more-button],amp-list[load-more] [load-more-end],amp-list[load-more] [load-more-failed],amp-list[load-more] [load-more-loading]{display:none}amp-list[diffable] div[role=list]{display:block}amp-story-page,amp-story[standalone]{min-height:1px!important;display:block!important;height:100%!important;margin:0!important;padding:0!important;overflow:hidden!important;width:100%!important}amp-story[standalone]{background-color:#000!important;position:relative!important}amp-story-page{background-color:#757575}amp-story .amp-active>div,amp-story .i-amphtml-loader-background{display:none!important}amp-story-page:not(:first-of-type):not([distance]):not([active]){transform:translateY(1000vh)!important}amp-autocomplete{position:relative!important;display:inline-block!important}amp-autocomplete>input,amp-autocomplete>textarea{padding:0.5rem;border:1px solid rgba(0,0,0,.33)}.i-amphtml-autocomplete-results,amp-autocomplete>input,amp-autocomplete>textarea{font-size:1rem;line-height:1.5rem}[amp-fx^=fly-in]{visibility:hidden}amp-script[nodom],amp-script[sandboxed]{position:fixed!important;top:0!important;width:1px!important;height:1px!important;overflow:hidden!important;visibility:hidden} /*# sourceURL=/css/ampdoc.css*/[hidden]{display:none!important}.i-amphtml-element{display:inline-block}.i-amphtml-blurry-placeholder{transition:opacity 0.3s cubic-bezier(0.0,0.0,0.2,1)!important;pointer-events:none}[layout=nodisplay]:not(.i-amphtml-element){display:none!important}.i-amphtml-layout-fixed,[layout=fixed][width][height]:not(.i-amphtml-layout-fixed){display:inline-block;position:relative}.i-amphtml-layout-responsive,[layout=responsive][width][height]:not(.i-amphtml-layout-responsive),[width][height][heights]:not([layout]):not(.i-amphtml-layout-responsive),[width][height][sizes]:not(img):not([layout]):not(.i-amphtml-layout-responsive){display:block;position:relative}.i-amphtml-layout-intrinsic,[layout=intrinsic][width][height]:not(.i-amphtml-layout-intrinsic){display:inline-block;position:relative;max-width:100%}.i-amphtml-layout-intrinsic .i-amphtml-sizer{max-width:100%}.i-amphtml-intrinsic-sizer{max-width:100%;display:block!important}.i-amphtml-layout-container,.i-amphtml-layout-fixed-height,[layout=container],[layout=fixed-height][height]:not(.i-amphtml-layout-fixed-height){display:block;position:relative}.i-amphtml-layout-fill,.i-amphtml-layout-fill.i-amphtml-notbuilt,[layout=fill]:not(.i-amphtml-layout-fill),body noscript>*{display:block;overflow:hidden!important;position:absolute;top:0;left:0;bottom:0;right:0}body noscript>*{position:absolute!important;width:100%;height:100%;z-index:2}body noscript{display:inline!important}.i-amphtml-layout-flex-item,[layout=flex-item]:not(.i-amphtml-layout-flex-item){display:block;position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.i-amphtml-layout-fluid{position:relative}.i-amphtml-layout-size-defined{overflow:hidden!important}.i-amphtml-layout-awaiting-size{position:absolute!important;top:auto!important;bottom:auto!important}i-amphtml-sizer{display:block!important}@supports (aspect-ratio:1/1){i-amphtml-sizer.i-amphtml-disable-ar{display:none!important}}.i-amphtml-blurry-placeholder,.i-amphtml-fill-content{display:block;height:0;max-height:100%;max-width:100%;min-height:100%;min-width:100%;width:0;margin:auto}.i-amphtml-layout-size-defined .i-amphtml-fill-content{position:absolute;top:0;left:0;bottom:0;right:0}.i-amphtml-replaced-content,.i-amphtml-screen-reader{padding:0!important;border:none!important}.i-amphtml-screen-reader{position:fixed!important;top:0px!important;left:0px!important;width:4px!important;height:4px!important;opacity:0!important;overflow:hidden!important;margin:0!important;display:block!important;visibility:visible!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:8px!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:12px!important}.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader~.i-amphtml-screen-reader{left:16px!important}.i-amphtml-unresolved{position:relative;overflow:hidden!important}.i-amphtml-select-disabled{-webkit-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.i-amphtml-notbuilt,[layout]:not(.i-amphtml-element),[width][height][heights]:not([layout]):not(.i-amphtml-element),[width][height][sizes]:not(img):not([layout]):not(.i-amphtml-element){position:relative;overflow:hidden!important;color:transparent!important}.i-amphtml-notbuilt:not(.i-amphtml-layout-container)>*,[layout]:not([layout=container]):not(.i-amphtml-element)>*,[width][height][heights]:not([layout]):not(.i-amphtml-element)>*,[width][height][sizes]:not([layout]):not(.i-amphtml-element)>*{display:none}amp-img:not(.i-amphtml-element)[i-amphtml-ssr]>img.i-amphtml-fill-content{display:block}.i-amphtml-notbuilt:not(.i-amphtml-layout-container),[layout]:not([layout=container]):not(.i-amphtml-element),[width][height][heights]:not([layout]):not(.i-amphtml-element),[width][height][sizes]:not(img):not([layout]):not(.i-amphtml-element){color:transparent!important;line-height:0!important}.i-amphtml-ghost{visibility:hidden!important}.i-amphtml-element>[placeholder],[layout]:not(.i-amphtml-element)>[placeholder],[width][height][heights]:not([layout]):not(.i-amphtml-element)>[placeholder],[width][height][sizes]:not([layout]):not(.i-amphtml-element)>[placeholder]{display:block;line-height:normal}.i-amphtml-element>[placeholder].amp-hidden,.i-amphtml-element>[placeholder].hidden{visibility:hidden}.i-amphtml-element:not(.amp-notsupported)>[fallback],.i-amphtml-layout-container>[placeholder].amp-hidden,.i-amphtml-layout-container>[placeholder].hidden{display:none}.i-amphtml-layout-size-defined>[fallback],.i-amphtml-layout-size-defined>[placeholder]{position:absolute!important;top:0!important;left:0!important;right:0!important;bottom:0!important;z-index:1}amp-img[i-amphtml-ssr]:not(.i-amphtml-element)>[placeholder]{z-index:auto}.i-amphtml-notbuilt>[placeholder]{display:block!important}.i-amphtml-hidden-by-media-query{display:none!important}.i-amphtml-element-error{background:red!important;color:#fff!important;position:relative!important}.i-amphtml-element-error:before{content:attr(error-message)}i-amp-scroll-container,i-amphtml-scroll-container{position:absolute;top:0;left:0;right:0;bottom:0;display:block}i-amp-scroll-container.amp-active,i-amphtml-scroll-container.amp-active{overflow:auto;-webkit-overflow-scrolling:touch}.i-amphtml-loading-container{display:block!important;pointer-events:none;z-index:1}.i-amphtml-notbuilt>.i-amphtml-loading-container{display:block!important}.i-amphtml-loading-container.amp-hidden{visibility:hidden}.i-amphtml-element>[overflow]{cursor:pointer;position:relative;z-index:2;visibility:hidden;display:initial;line-height:normal}.i-amphtml-layout-size-defined>[overflow]{position:absolute}.i-amphtml-element>[overflow].amp-visible{visibility:visible}template{display:none!important}.amp-border-box,.amp-border-box *,.amp-border-box :after,.amp-border-box :before{box-sizing:border-box}amp-pixel{display:none!important}amp-analytics,amp-auto-ads,amp-story-auto-ads{position:fixed!important;top:0!important;width:1px!important;height:1px!important;overflow:hidden!important;visibility:hidden}amp-story{visibility:hidden!important}html.i-amphtml-fie>amp-analytics{position:initial!important}[visible-when-invalid]:not(.visible),form [submit-error],form [submit-success],form [submitting]{display:none}amp-accordion{display:block!important}@media (min-width:1px){:where(amp-accordion>section)>:first-child{margin:0;background-color:#efefef;padding-right:20px;border:1px solid #dfdfdf}:where(amp-accordion>section)>:last-child{margin:0}}amp-accordion>section{float:none!important}amp-accordion>section>*{float:none!important;display:block!important;overflow:hidden!important;position:relative!important}amp-accordion,amp-accordion>section{margin:0}amp-accordion:not(.i-amphtml-built)>section>:last-child{display:none!important}amp-accordion:not(.i-amphtml-built)>section[expanded]>:last-child{display:block!important} /*# sourceURL=/css/ampshared.css*/</style><script async src="https://cdn.ampproject.org/v0.mjs" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0.js" crossorigin="anonymous"></script><script async src="https://cdn.ampproject.org/v0/amp-analytics-0.1.mjs" custom-element="amp-analytics" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js" crossorigin="anonymous" custom-element="amp-analytics"></script><script async src="https://cdn.ampproject.org/v0/amp-animation-0.1.mjs" custom-element="amp-animation" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-animation-0.1.js" crossorigin="anonymous" custom-element="amp-animation"></script><script custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.mjs" async type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-bind-0.1.js" crossorigin="anonymous" custom-element="amp-bind"></script><script async src="https://cdn.ampproject.org/v0/amp-consent-0.1.mjs" custom-element="amp-consent" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-consent-0.1.js" crossorigin="anonymous" custom-element="amp-consent"></script><script async src="https://cdn.ampproject.org/v0/amp-geo-0.1.mjs" custom-element="amp-geo" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-geo-0.1.js" crossorigin="anonymous" custom-element="amp-geo"></script><script custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.mjs" async type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js" crossorigin="anonymous" custom-element="amp-iframe"></script><script async src="https://cdn.ampproject.org/v0/amp-install-serviceworker-0.1.mjs" custom-element="amp-install-serviceworker" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-install-serviceworker-0.1.js" crossorigin="anonymous" custom-element="amp-install-serviceworker"></script><script async src="https://cdn.ampproject.org/v0/amp-position-observer-0.1.mjs" custom-element="amp-position-observer" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-position-observer-0.1.js" crossorigin="anonymous" custom-element="amp-position-observer"></script><script async src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.mjs" custom-element="amp-sidebar" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js" crossorigin="anonymous" custom-element="amp-sidebar"></script><script async src="https://cdn.ampproject.org/v0/amp-user-notification-0.1.mjs" custom-element="amp-user-notification" type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-user-notification-0.1.js" crossorigin="anonymous" custom-element="amp-user-notification"></script><script custom-element="amp-video" src="https://cdn.ampproject.org/v0/amp-video-0.1.mjs" async type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-video-0.1.js" crossorigin="anonymous" custom-element="amp-video"></script><script custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.mjs" async type="module" crossorigin="anonymous"></script><script async nomodule src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js" crossorigin="anonymous" custom-element="amp-youtube"></script><link rel="shortcut icon" href="/static/img/favicon.png"><link rel="canonical" href="https://amp.dev/documentation/components/amp-bind/"><link rel="alternate" hreflang="x-default" href="https://amp.dev/documentation/components/amp-bind/"><link rel="alternate" hreflang="fr" href="https://amp.dev/fr/documentation/components/amp-bind/"><link rel="alternate" hreflang="ar" href="https://amp.dev/ar/documentation/components/amp-bind/"><link rel="alternate" hreflang="es" href="https://amp.dev/es/documentation/components/amp-bind/"><link rel="alternate" hreflang="it" href="https://amp.dev/it/documentation/components/amp-bind/"><link rel="alternate" hreflang="id" href="https://amp.dev/id/documentation/components/amp-bind/"><link rel="alternate" hreflang="ja" href="https://amp.dev/ja/documentation/components/amp-bind/"><link rel="alternate" hreflang="ko" href="https://amp.dev/ko/documentation/components/amp-bind/"><link rel="alternate" hreflang="pt_BR" href="https://amp.dev/pt_br/documentation/components/amp-bind/"><link rel="alternate" hreflang="tr" href="https://amp.dev/tr/documentation/components/amp-bind/"><link rel="alternate" hreflang="zh_CN" href="https://amp.dev/zh_cn/documentation/components/amp-bind/"><title>Documentation: <amp-bind> - amp.dev</title><script type="application/ld+json">{"@context":"http://schema.org","@type":"Webpage","url":"https://amp.dev/documentation/components/amp-bind/ ","name":"amp.dev","headline":"Documentation: \u0026lt;amp-bind\u0026gt;","description":"Allows elements to mutate in response to user actions or data changes via data binding and simple JS-like expressions.","mainEntityOfPage":{"@type":"WebPage","@id":"https://amp.dev"},"publisher":{"@type":"Organization","name":"AMP Project","logo":{"url":"https://amp.dev/static/img/icons/icon-512x512.png","width":512,"height":512,"@type":"ImageObject"}},"image":{"@type":"ImageObject","url":"https://amp.dev/static/img/sharing/docs-component-600x314.png","width":600,"height":314}}</script><style amp-custom>@font-face{font-family:system;font-style:normal;font-weight:300;src:local(".SFNSText-Light"),local(".HelveticaNeueDeskInterface-Light"),local(".LucidaGrandeUI"),local("Ubuntu Light"),local("Segoe UI Light"),local("Roboto-Light"),local("DroidSans"),local("Tahoma")}@font-face{font-family:system;font-style:italic;font-weight:300;src:local(".SFNSText-LightItalic"),local(".HelveticaNeueDeskInterface-Italic"),local(".LucidaGrandeUI"),local("Ubuntu Light Italic"),local("Segoe UI Light Italic"),local("Roboto-LightItalic"),local("DroidSans"),local("Tahoma")}@font-face{font-family:system;font-style:normal;font-weight:400;src:local(".SFNSText-Regular"),local(".HelveticaNeueDeskInterface-Regular"),local(".LucidaGrandeUI"),local("Ubuntu"),local("Segoe UI"),local("Roboto-Regular"),local("DroidSans"),local("Tahoma")}@font-face{font-family:system;font-style:italic;font-weight:400;src:local(".SFNSText-Italic"),local(".HelveticaNeueDeskInterface-Italic"),local(".LucidaGrandeUI"),local("Ubuntu Italic"),local("Segoe UI Italic"),local("Roboto-Italic"),local("DroidSans"),local("Tahoma")}@font-face{font-family:system;font-style:normal;font-weight:500;src:local(".SFNSText-Medium"),local(".HelveticaNeueDeskInterface-MediumP4"),local(".LucidaGrandeUI"),local("Ubuntu Medium"),local("Segoe UI Semibold"),local("Roboto-Medium"),local("DroidSans-Bold"),local("Tahoma Bold")}@font-face{font-family:system;font-style:italic;font-weight:500;src:local(".SFNSText-MediumItalic"),local(".HelveticaNeueDeskInterface-MediumItalicP4"),local(".LucidaGrandeUI"),local("Ubuntu Medium Italic"),local("Segoe UI Semibold Italic"),local("Roboto-MediumItalic"),local("DroidSans-Bold"),local("Tahoma Bold")}@font-face{font-family:system;font-style:normal;font-weight:700;src:local(".SFNSText-Bold"),local(".HelveticaNeueDeskInterface-Bold"),local(".LucidaGrandeUI"),local("Ubuntu Bold"),local("Roboto-Bold"),local("DroidSans-Bold"),local("Segoe UI Bold"),local("Tahoma Bold")}@font-face{font-family:system;font-style:italic;font-weight:700;src:local(".SFNSText-BoldItalic"),local(".HelveticaNeueDeskInterface-BoldItalic"),local(".LucidaGrandeUI"),local("Ubuntu Bold Italic"),local("Roboto-BoldItalic"),local("DroidSans-Bold"),local("Segoe UI Bold Italic"),local("Tahoma Bold")}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-display:optional;src:local("Noto Sans"),local("NotoSans"),url(https://amp.dev/static/fonts/noto-sans-v7-latin-regular.woff2) format("woff2"),url(https://amp.dev/static/fonts/noto-sans-v7-latin-regular.woff) format("woff")}@font-face{font-family:Noto Sans;font-style:normal;font-weight:700;font-display:optional;src:local("Noto Sans Bold"),local("NotoSans-Bold"),url(https://amp.dev/static/fonts/noto-sans-v7-latin-700.woff2) format("woff2"),url(https://amp.dev/static/fonts/noto-sans-v7-latin-700.woff) format("woff")}@font-face{font-family:Poppins;font-style:normal;font-weight:700;font-display:optional;src:local("Poppins Bold"),local("Poppins-Bold"),url(https://amp.dev/static/fonts/poppins-v5-latin-700.woff2) format("woff2"),url(https://amp.dev/static/fonts/poppins-v5-latin-700.woff) format("woff")}@font-face{font-family:Fira Mono;font-style:normal;font-weight:400;font-display:optional;src:local("Fira Mono"),local("FiraMono"),url(https://amp.dev/static/fonts/fira-mono-v7-latin-500.woff2) format("woff2"),url(https://amp.dev/static/fonts/fira-mono-v7-latin-500.woff) format("woff")}*{box-sizing:border-box}body,html{padding:0;margin:0;min-width:240px;color:#48525c;background-color:#fff;font-size:16px;font-family:Noto Sans,system;overflow-x:hidden;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;touch-action:manipulation}@media(max-width:240px){body,html{font-size:14px}}body>*>:not(.ap-o-code-preview)>*>.amp-carousel-button{width:3em;height:3em;border-radius:50%;box-shadow:0 10px 15px 0 rgba(0,0,0,.4);transition:.4s;background-color:#fff;position:relative;box-sizing:border-box;margin:1em;border-style:none;background-position:50% 50%;background-repeat:no-repeat;z-index:10;pointer-events:all}body>*>:not(.ap-o-code-preview)>*>.amp-carousel-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' fill='%23005AF0'%3E%3Cpath d='M15 8.25H5.87l4.19-4.19L9 3 3 9l6 6 1.06-1.06-4.19-4.19H15v-1.5z'/%3E%3C/svg%3E")}body>*>:not(.ap-o-code-preview)>*>.amp-carousel-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' fill='%23005AF0' %3E%3Cpath d='M9 3L7.94 4.06l4.19 4.19H3v1.5h9.13l-4.19 4.19L9 15l6-6z'/%3E%3C/svg%3E")}body>*>:not(.ap-o-code-preview)>*>.amp-carousel-button:hover{cursor:pointer;box-shadow:0 20px 30px 0 rgba(0,0,0,.2);background-color:#fff}:target:before{content:"";display:block;visibility:hidden;height:120px;margin-top:-120px}@media(min-width:1024px){h1:target:before{height:75px;margin-top:-75px}h2:target:before{height:81px;margin-top:-81px}h3:target:before{height:87px;margin-top:-87px}h4:target:before{height:90px;margin-top:-90px}h5:target:before{height:93px;margin-top:-93px}h6:target:before{height:97px;margin-top:-97px}}h1,h2,h3,h4,h5{margin-top:1.5rem;margin-bottom:.75em;font-family:Poppins,system;font-weight:700;line-height:1.2em;color:#20202a}h1{font-size:2.2rem;margin-top:3rem}section.-t h1:first-of-type{margin-top:0}@media(min-width:768px){section.-t h1:first-of-type{margin-bottom:2rem}}h2{font-size:1.8rem;margin-top:2rem}h3{font-size:1.414rem;margin-top:1.8rem}h4{font-size:1.2rem}h5{font-size:1rem}.-t .intro,.ap--section .intro{font-size:1rem;padding:0}.-t .intro *,.ap--section .intro *{font-size:inherit}.-t p,.ap--section p{line-height:1.6rem;font-weight:400;color:#48525c;display:block;margin-top:1.1em;margin-bottom:0;font-size:1rem}.-t p small,.ap--section p small{font-size:.875rem}.-t code,.ap--section code{display:inline;padding:2px 4px;font-family:Fira Mono,monospace;font-weight:500;word-break:normal;color:#000;background-color:#e2e5e6;font-size:.9em}.-t code,.-t p,.ap--section code,.ap--section p{overflow-wrap:break-word}.-t a,.ap--section a{position:relative;z-index:10}.-t a code,.ap--section a code{color:#005af0;z-index:-1}.-t pre,.ap--section pre{font-family:Fira Mono,monospace;font-weight:500;font-size:1rem;white-space:pre-wrap}.-t>ol,.-t>ul,.ap--section>ol,.ap--section>ul{line-height:1.6rem;font-weight:400;color:#48525c;display:block;padding-left:2em;margin:1.5em 0}.-t>ol ol,.-t>ol ul,.-t>ul ol,.-t>ul ul,.ap--section>ol ol,.ap--section>ol ul,.ap--section>ul ol,.ap--section>ul ul{padding-left:2em;margin:0}.-t>ol li,.-t>ul li,.ap--section>ol li,.ap--section>ul li{padding-left:.5em}.-t>ol li p,.-t>ul li p,.ap--section>ol li p,.ap--section>ul li p{font-size:1em}.-t figure figcaption,.ap--section figure figcaption{line-height:1.6rem;font-weight:400;color:#48525c;font-size:.8125rem;margin-top:.3em}.-t hr,.ap--section hr{height:1px;margin:.75em 0;background-color:#ebebf0;border:none}.-n{display:flex;align-items:center;text-decoration:none;padding:0 0 1.5em;margin:0}.-r{line-height:1.6rem;font-weight:400;color:#48525c;font-size:.875rem;font-weight:700;color:#005af0;line-height:1.3;transition:transform .3s ease}.-i{fill:#005af0;padding:.438em 0;margin-bottom:auto;margin-right:.625em;box-sizing:initial;transition:transform .3s ease}.-n:hover .-i,.-n:hover .-r{transform:translateX(10px)}.-s{border-bottom:1px solid #ebebf0}.-s .-r{font-size:1rem;font-family:Poppins,system;font-weight:700;color:#000;padding-left:10px}.-s .-i{width:1.375em;height:1.375em;fill:#fff;background-color:#005af0;overflow:hidden;padding:.563em}.-s .-i,.-s:hover .-i{box-shadow:0 10px 20px 0 rgba(0,0,0,.25)}.-s:hover .-i svg{animation:duepduep .3s ease}a{font-weight:700;text-decoration:none;color:#005af0}a code{display:inline;padding:2px 4px;font-family:Fira Mono,monospace;font-weight:500;word-break:normal;color:#000;background-color:#e2e5e6;font-size:.9em;color:#005af0}.ap-a-ico{display:flex;font-size:medium;box-sizing:initial;justify-content:center;width:1em;height:1em}.ap-a-btn{font-family:Poppins,system;font-weight:700;line-height:1.2em;color:#20202a;font-size:1em;color:#fff;display:inline-block;max-width:100%;width:auto;height:auto;padding:.75em 1.75em;margin:0;text-decoration:none;text-align:center;border-radius:3px;background-color:#005af0;border:none;cursor:pointer;box-shadow:0 15px 35px -5px rgba(0,0,0,.25);transition:transform .3s ease,box-shadow .3s ease}.ap-a-btn:hover{transform:translateY(-.125em);box-shadow:0 25px 20px -15px rgba(0,0,0,.15)}@media(min-width:768px){.ap-a-btn{padding:1em 2em}}.-o{right:20px;left:auto;bottom:20px;width:calc(100% - 40px);padding:15px;line-height:1.6rem;font-weight:400;color:#48525c;font-size:.875rem;background-color:#fff;box-shadow:0 15px 30px 0 rgba(0,0,0,.15);border-radius:8px}@media(min-width:768px){.-o{max-width:500px}}.-u{position:absolute;right:15px;top:15px;-webkit-appearance:none;background-color:transparent;border:none;padding:0}.-u svg{width:10px;height:10px}.-o button{cursor:pointer}.ap--footer{position:relative;z-index:15;padding:3em 0 2em;line-height:1.6rem;font-weight:400;color:#48525c;font-size:1rem;color:#fff;background:linear-gradient(45deg,#48525c,#20202a)}.-a{width:100%;max-width:1440px;padding:0 20px;margin:0 auto}.-f{padding-bottom:4em}@media(min-width:768px){.-f{display:flex;align-items:center}}.-l{display:flex;flex-direction:column;margin-left:auto}@media(min-width:1024px){.-l{flex-direction:row}}.-c{margin:3em 2em 1em 0;color:#fff}@media(min-width:768px){.-c{margin:auto 2em auto 1em}}.-h{display:flex;list-style:none;padding:0;margin:0}.-p{flex:1 0 auto}@media(min-width:768px){.-p{margin:16px}}.-d{width:2.5em;height:2.5em;fill:#fff}@media(max-width:240px){.-d{font-size:14px}}@media(min-width:768px){.-v{display:grid;grid-gap:30px;grid-template-columns:repeat(12,1fr)}}.-m{flex:1 1 100%}.-m:nth-child(odd){grid-column:span 3}@media(max-width:1023px){.-m:nth-child(odd){grid-column:span 6}}.-m:nth-child(2n+2){grid-column:span 3}@media(max-width:1023px){.-m:nth-child(2n+2){grid-column:span 6}}.-g{color:#fff}.-y{list-style:none;padding:0}@media(min-width:768px){.-y+.-g{margin-top:2.5em}}.-b{position:relative}.-w{padding-left:35px;font-size:.8125rem;color:#fff}.-x{position:absolute;left:10px;top:8px;width:12px;height:12px;fill:#fff}.-k{display:flex;flex-direction:column;padding-top:4em}@media(min-width:768px){.-k{flex-direction:row;align-items:flex-end}}.-_{width:50%;max-width:200px;margin-bottom:40px;margin-right:auto}@media(min-width:768px){.-_{margin-bottom:0}}.-j{list-style:none;padding:0;margin:0}.-q{display:inline-block;margin-right:1em}.-z{font-size:.8125rem;font-weight:400;color:#fff}.-te{display:block;font-size:.875rem;margin-top:2em;color:#e2e5e6}.-te a{color:#fafafc}.ap-m-format-toggle{position:-webkit-sticky;position:sticky;top:0;margin:0 10px;padding:10px 0 0;width:100%;max-width:85%;z-index:12}@media(min-width:768px){.ap-m-format-toggle{padding:0;margin:0 15px 0 0;max-width:100%}}.ap-m-format-toggle-selected{border:0}.amp-mode-touch .ap-m-format-toggle-selected{position:relative}.ap-m-format-toggle-selected:focus:after,.ap-m-format-toggle-selected:hover:after{position:absolute;top:0;left:0;content:"";display:block;height:300%;width:100%}.ap-m-format-toggle-link,.ap-m-format-toggle-selected{z-index:3;display:flex;align-items:center;width:100%;margin:0 0 2px;padding:5px 8px;overflow:hidden;line-height:1.6rem;font-weight:400;color:#48525c;font-family:Poppins,system;font-weight:700;font-size:12px;text-align:left;border-radius:4px;color:#000;background:#ebebf0;transition:opacity .2s ease;box-shadow:0 5px 15px -5px rgba(0,0,0,.25)}.ap-m-format-toggle-link .ap-a-ico,.ap-m-format-toggle-selected .ap-a-ico{width:14px;height:14px;margin-right:8px;fill:#000}.ap-m-format-toggle-link{color:#000;background:#ebebf0}.ap-m-format-toggle-link .ap-a-ico{fill:#000}.ap-m-format-toggle-link-websites.ap-m-format-toggle-selected,.ap-m-format-toggle-link-websites:hover{background:linear-gradient(225deg,#00dcc0,#005af0 75%);color:#fff}.ap-m-format-toggle-link-websites.ap-m-format-toggle-selected .ap-a-ico,.ap-m-format-toggle-link-websites:hover .ap-a-ico{fill:#fff}.ap-m-format-toggle-link-stories.ap-m-format-toggle-selected,.ap-m-format-toggle-link-stories:hover{background:linear-gradient(225deg,#ec6600,#ffdc00 75%);color:#20202a}.ap-m-format-toggle-link-stories.ap-m-format-toggle-selected .ap-a-ico,.ap-m-format-toggle-link-stories:hover .ap-a-ico{fill:#20202a}.ap-m-format-toggle-link-ads.ap-m-format-toggle-selected,.ap-m-format-toggle-link-ads:hover{background:linear-gradient(225deg,#eb49e1,#5500d7 75%);color:#fff}.ap-m-format-toggle-link-ads.ap-m-format-toggle-selected .ap-a-ico,.ap-m-format-toggle-link-ads:hover .ap-a-ico{fill:#fff}.ap-m-format-toggle-link-email.ap-m-format-toggle-selected,.ap-m-format-toggle-link-email:hover{background:linear-gradient(225deg,#09a600,#e1eb64 75%);color:#20202a}.ap-m-format-toggle-link-email.ap-m-format-toggle-selected .ap-a-ico,.ap-m-format-toggle-link-email:hover .ap-a-ico{fill:#20202a}.ap-m-format-toggle-angle{margin-right:0;margin-left:auto}.ap-m-format-toggle-formats{position:absolute;width:100%;z-index:2;pointer-events:none;opacity:0;transform:translateY(-20px);transition:all .2s ease;transition-delay:.05s}.ap-m-format-toggle-formats:focus-within,.ap-m-format-toggle-formats:hover,.ap-m-format-toggle-selected:focus+.ap-m-format-toggle-formats,.ap-m-format-toggle-selected:hover+.ap-m-format-toggle-formats{pointer-events:auto;opacity:1;transform:translateY(0)}body{top:0;left:0;background-repeat:no-repeat;background-size:100% auto;background-position:100% 0;background-attachment:fixed}body.ap--websites{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 768'%3E%3Cdefs%3E%3ClinearGradient id='a' x1='239.67' y1='855.23' x2='606.28' y2='-152.04' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23fff' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23d5e6f2'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg%3E%3Cpath fill='url(%23a)' d='M0 0h1024v214L786.37 768H0V0z'/%3E%3C/g%3E%3C/svg%3E%0A")}body.ap--ads{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 768'%3E%3Cdefs%3E%3ClinearGradient id='a' x1='239.67' x2='606.28' y1='855.23' y2='-152.04' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23fff' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23ddd3eb'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg%3E%3Cpath fill='url(%23a)' d='M0 0h1024v214L786.37 768H0V0z'/%3E%3C/g%3E%3C/svg%3E%0A")}body.ap--stories{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 768'%3E%3Cdefs%3E%3ClinearGradient id='a' x1='239.67' x2='606.28' y1='855.23' y2='-152.04' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23fff' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23ebdfd3'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg%3E%3Cpath fill='url(%23a)' d='M0 0h1024v214L786.37 768H0V0z'/%3E%3C/g%3E%3C/svg%3E%0A")}body.ap--email{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 768'%3E%3Cdefs%3E%3ClinearGradient id='a' x1='239.67' x2='606.28' y1='855.23' y2='-152.04' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23fff' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23d7ebd3'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg%3E%3Cpath fill='url(%23a)' d='M0 0h1024v214L786.37 768H0V0z'/%3E%3C/g%3E%3C/svg%3E%0A")}.ap--ampsidebar{width:100%;max-width:90vw;background:#fafafc}.ap--ampsidebar-toolbar{top:86px;height:100vh;max-height:calc(100vh - 86px)}@media(min-width:768px){.ap--ampsidebar-toolbar{position:-webkit-sticky;position:sticky;overflow:auto}}.ap--ampsidebar-toolbar>ul{-webkit-overflow-scrolling:touch;margin:0;padding:0}@media(min-width:768px){.ap--ampsidebar-toolbar>ul{overflow:auto;max-height:100%}}.ap--ampsidebar-toolbar>ul::-webkit-scrollbar{width:6px;height:6px}.ap--ampsidebar-toolbar>ul::-webkit-scrollbar-thumb{border-radius:3px;background-color:#91979d}.ap--ampsidebar-toolbar>ul::-webkit-scrollbar-corner{background-color:transparent}.ap--ampsidebar-toolbar>ul::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.1)}.ap-o-sidebar-component{max-width:100%}@media(min-width:768px){.ap-o-sidebar-component .ap-o-sidebar{width:auto;min-height:400px;padding-bottom:0;margin-right:0;margin-left:-10px;background:0 0;box-shadow:none}}.ap-o-sidebar-component .nav{margin:15px 0 0;padding-bottom:15px}.ap-o-sidebar-component .nav-list{max-width:300px;list-style:none;padding:0;margin:0}.ap-o-sidebar-component .nav-list.level-1{margin:0 15px}.ap-o-sidebar-component .nav-list .nav-list{padding-bottom:10px;margin-bottom:10px}.ap-o-sidebar-component .nav-item{position:relative;margin:0;padding:0}.ap-o-sidebar-component .nav-item.level-1{pointer-events:none}.ap-o-sidebar-component .nav-item.level-1 .nav-link{font-family:Poppins,system;font-weight:700;line-height:1.2em;color:#20202a;font-size:1.8rem;padding:0;margin:0;line-height:1;word-break:break-all;pointer-events:auto;color:#e2e5e6}.ap-o-sidebar-component .nav-item.level-1 .nav-link:only-child:not(a){margin:-20px;font-size:0;pointer-events:none;z-index:-1}.ap-o-sidebar-component .nav-item.level-1>.nav-link{padding-top:10px;pointer-events:none;z-index:1;transition:color .15s ease}.ap-o-sidebar-component .nav-item.level-1.active>.nav-link,.ap-o-sidebar-component .nav-item.level-1:hover>.nav-link{color:#91979d}.ap-o-sidebar-component .nav-item.level-2 .nav-link{text-transform:unset;line-height:1.6rem;font-weight:400;color:#48525c;font-family:Noto Sans,system;font-size:.875rem;line-height:1.4em;padding:3px 25px 3px 0;margin:0}.ap-o-sidebar-component .nav-item.active>.nav-link{font-weight:700;color:#005af0}.ap-o-sidebar-component .nav-item:hover>.nav-link{color:#005af0}.ap-o-sidebar-component .nav-link{position:relative;display:block;padding:0;margin:0;color:rgba(0,0,0,.75);border:none;background-color:transparent}.ap-a-img{position:relative}.image-preview-1 .ap-a-img{overflow:hidden;border-radius:50%}.image-preview-2 .ap-a-img{margin-right:-30px;filter:drop-shadow(0 30px 30px -15px rgba(0,0,0,.25))}@media(min-width:768px){.image-preview-2 .ap-a-img{margin-right:0}}.-is{display:block;width:100%;height:1px;margin-bottom:.813em;background-color:#fafafc}@media(min-width:768px){.-is{display:none}.-io{display:block}}.-ff{padding:84px 15px 0}@media(min-width:768px){.-ff{padding-left:0;padding-right:0}}.-fl{margin-bottom:.75em;font-size:1.8rem;margin-top:2rem;padding:20px 0}.-fl,.-fc{font-family:Poppins,system;font-weight:700;line-height:1.2em;color:#20202a}.-fc{margin-top:1.5rem;font-size:1.2rem;padding-left:20px;margin-bottom:0}.-fh{line-height:1.6rem;font-weight:400;color:#48525c;font-size:1rem}.-fp{display:block;background-color:#ebebf0;height:1px;margin:30px 20px 30px 0}.ap-m-clip{position:relative}.ap-m-clip-expand{position:absolute;z-index:10;bottom:0;left:0;display:flex;justify-content:center;align-items:flex-end;height:65px;width:100%;border:none;background:#fff;background:linear-gradient(180deg,hsla(0,0%,100%,0),#fff 40%);cursor:pointer}.ap-m-clip-expand-icon{max-height:21px;max-width:21px;margin-top:35px;fill:#48525c;transition:transform .3s}.ap-m-clip-expand:hover .ap-m-clip-expand-icon{fill:#005af0;transform:translate3d(0,-2px,0)}.ap-a-copy-script{display:flex;align-items:center;flex-basis:100%}.ap-a-copy-script pre{overflow-x:scroll;flex:1 0;margin:6px 8px 6px 0;padding:4px 6px;white-space:wrap;background:#e2e5e6;font-size:12.6px}.ap-a-copy-script pre::-webkit-scrollbar{width:6px;height:6px}.ap-a-copy-script pre::-webkit-scrollbar-thumb{border-radius:3px;background-color:#91979d}.ap-a-copy-script pre::-webkit-scrollbar-corner{background-color:transparent}.ap-a-copy-script pre::-webkit-scrollbar{height:4px}.ap-a-copy-script pre::-webkit-scrollbar-thumb{border-radius:0}.ap-o-component-intro-row{padding:15px;background-color:#fff;border:1px solid #e2e5e6}.ap-o-component-intro-row+.ap-o-component-intro-row{margin-top:10px}@media(min-width:768px){.ap-o-component-intro-row-inline{display:flex;align-items:baseline;flex-wrap:wrap}}.ap-o-component-intro-headline{font-size:16px;margin:0 0 10px}.ap-o-component-intro-row-inline .ap-o-component-intro-headline{white-space:nowrap;margin-right:10px}.ap-o-component-intro-headline .active{color:#00f}.ap-o-component-intro-filter{margin-left:auto}.ap-o-component-intro-filter *{font-size:.875rem}.ap-o-component-intro-text{margin:5px 0}.ap-o-component-intro-list{max-height:142px;overflow:hidden}@media(min-width:768px){.ap-o-component-intro-list{display:flex;flex-wrap:wrap}}.ap-o-component-intro-list-item{display:block;margin-bottom:6px;font-size:.875rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@media(min-width:768px){.ap-o-component-intro-list-item{width:50%;padding-right:12px}}.expanded .ap-o-component-intro-list{max-height:none}.ap-m-tip{display:flex;padding:15px;margin-bottom:20px;border-radius:4px;background-color:#ebebf0;border:1px solid #e2e5e6}@media(min-width:768px){.ap-m-tip{padding:30px}}.ap-m-tip code{white-space:normal}.ap-m-tip-icon{width:36px;height:36px;margin-top:5px;margin-right:14px}@media(min-width:768px){.ap-m-tip-icon{margin-right:26px}}.ap-m-tip-content{font-size:.875rem;min-width:0}.ap-m-tip-content h4{font-size:1rem;margin:0 0 .75em}.ap-m-tip-content ol,.ap-m-tip-content p,.ap-m-tip-content ul{font-size:.875rem}.ap-m-tip-content ol:first-child,.ap-m-tip-content p:first-child,.ap-m-tip-content ul:first-child{margin-top:0}.ap-breadcrumbs,.-ou{display:flex;align-items:center;font-family:Poppins,system;font-weight:700;font-size:.8125rem}.ap-breadcrumbs-angle,.-oa{width:10px;height:10px;margin:0 6px;transform:rotate(-90deg)}.ap--toc{width:100%}@media(min-width:1024px){.ap--toc{background:0 0;box-shadow:none;padding-right:10px}}.ap-o-toc{--spacing-top:90px;position:relative;z-index:1;top:0;right:0;width:calc(100% - 20px);overflow-y:auto;-webkit-overflow-scrolling:touch;background-color:#fff;box-shadow:0 2px 10px 0 rgba(0,0,0,.07);border-radius:8px;padding:15px;margin-bottom:10px}.ap-o-toc::-webkit-scrollbar{width:6px;height:6px}.ap-o-toc::-webkit-scrollbar-thumb{border-radius:3px;background-color:#91979d}.ap-o-toc::-webkit-scrollbar-corner{background-color:transparent}.ap-o-toc::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.1)}@media(min-width:768px){.ap-o-toc{width:100%}}@media(min-width:1024px){.ap-o-toc{position:-webkit-sticky;position:sticky;z-index:1;padding:0 10px 0 0;margin:0;height:auto;top:var(--spacing-top);right:auto;padding-bottom:var(--spacing-top);background:0 0;box-shadow:none;overflow-y:scroll;max-height:calc(100vh - var(--spacing-top))}}.ap-o-toc-hl{font-family:Poppins,system;font-weight:700;cursor:pointer;width:100%;margin-bottom:0}@media(min-width:1024px){.ap-o-toc-hl{margin-bottom:10px}}.ap-o-toc-toggle{display:flex;align-items:center;justify-content:space-between;outline:0}@media(min-width:1024px){.ap-o-toc-toggle{position:-webkit-sticky;position:sticky;top:0;background:#fafafc}}.ap-o-toc ul{list-style:none;margin:0;padding:0;transition:.4s}.ap-o-toc ul>li a{display:block;padding-bottom:20px;line-height:1.6rem;font-weight:400;color:#48525c;font-size:.8125rem;font-weight:700;line-height:1rem}.ap-o-toc ul>li>ul{padding-left:10px;text-transform:none}.ap-o-toc ul>li>ul li a{font-weight:400}@media(max-width:1023px){.ap-o-toc .-of:not(:checked)+ul{display:none;transition:.2s}.ap-o-toc .-of:checked+ul{margin-top:15px}}.ap-o-toc .nav-icon svg{width:15px;height:15px}@media(min-width:1024px){.ap-o-toc .nav-icon{display:none}}.ap-o-toc .nav-icon .ap-a-ico{display:inline-block;transform:rotate(-90deg)}.ap-o-toc.contentmenuopen .nav-icon .ap-a-ico{transform:rotate(0)}#sidebar-left[aria-hidden=true]:not([hidden])~.ap--main .-ol{animation:moveSidebarToggleBackwards .233s cubic-bezier(0,0,.21,1) forwards}#sidebar-left[aria-hidden=true]:not([hidden])~.ap--main .-ol .label-icon svg{transform:rotate(180deg)}#sidebar-left[aria-hidden=true]:not([hidden])~.ap--main .-ol .label-title{transform:translateX(0) scaleX(1);transform-origin:left center}#sidebar-left[open]~.ap--main .-ol{left:0;margin-left:0;animation:moveSidebarToggleForwards .233s cubic-bezier(0,0,.21,1) forwards}#sidebar-left[open]~.ap--main .-ol .label-icon svg{transform:rotate(0)}#sidebar-left[open]~.ap--main .-ol .label-title{transform:translateX(-150vw) scaleX(0);transform-origin:left center}#sidebar-left[aria-hidden=true]:not([hidden])~.ap--main .-ol,#sidebar-left[open]~.ap--main .-ol{z-index:9999999999}.-oc{position:absolute;top:50px}.-oh{position:fixed;top:-99px}.-op{position:fixed;z-index:15;font-size:12px;font-family:Poppins,system;font-weight:700;color:#fff;fill:#fff;cursor:pointer;display:flex;align-items:center}.-op .label-icon{border-radius:4px;background:#005af0;height:35px;width:32px;padding-left:2px;display:flex;justify-content:center;align-items:center;box-shadow:0 10px 20px -5px rgba(0,0,0,.25);z-index:1}.-op .label-icon svg{height:14px;width:14px;transition:transform .233s cubic-bezier(0,0,.21,1)}.-op .label-title{left:32px;display:flex;align-items:center;height:35px;margin-left:-5px;padding:5px 10px 5px 5px;white-space:nowrap;border-radius:0 4px 4px 0;background:#005af0;box-shadow:0 10px 20px -5px rgba(0,0,0,.25);transform:scaleX(0);transform-origin:left;transition:transform .233s cubic-bezier(0,0,.21,1)}.-od{position:fixed;top:-99px}.-ol{margin-top:-52px;margin-left:-25px}@media(min-width:768px){.-ol{display:none}}.-ol .label-icon svg{transform:rotate(180deg)}.-ov{display:none}.-om{position:fixed;top:-99px}.-og{display:none}@media(min-width:768px)and (max-width:1440px){.-ov{display:inline-block}.-og{position:-webkit-sticky;position:sticky;top:138px;display:inline-flex;transform:translate(-40px,-52px)}.-om:checked~.-oy{grid-column:1/2}.-om:checked~.-oy nav{display:none}.-om:checked~.-oy svg{transform:rotate(180deg)}}@media(min-width:768px)and (max-width:1440px)and (max-width:1023px){.-om:checked~.ap--toc{grid-column:2/25}}@media(min-width:768px)and (max-width:1440px){.-om:checked~.ap--toc~.-t{padding-left:80px;padding-right:80px;grid-column:2/20}}@media(min-width:768px)and (max-width:1440px)and (max-width:1023px){.-om:checked~.ap--toc~.-t{grid-column:2/25}}@media(min-width:768px)and (max-width:1440px){.-om:checked~.-t,.-om:checked~.ap--help{grid-column-start:2;padding-left:80px;padding-right:80px}.-om:checked~.-t .-og,.-om:checked~.ap--help .-og{margin-left:-88px}.-om:checked~.-t .-og .label-icon svg,.-om:checked~.ap--help .-og .label-icon svg{transform:rotate(180deg)}}.-fd{display:none}.-fv.amp-active~.-fd{height:42px;max-width:2020px;margin:0 auto;color:#fff;background-color:#20202a;font-size:.875rem;z-index:100;position:absolute;width:100%;left:0;right:0}@media(min-width:768px){.-fv.amp-active~.-fd{display:block}}.-fv.amp-active~.-fd .-fm{position:relative;display:flex;align-items:center;width:100%;height:100%;max-width:1440px;padding:0 30px;margin:0 auto}@media(min-width:1024px){.-fv.amp-active~.-fd .-fm{padding:0 15px}}.-fv.amp-active~.-fd .-fm:after{position:absolute;content:"";top:42px;left:50px;width:0;height:0;border-color:#20202a transparent transparent;border-style:solid;border-width:8px 10px 0}.-fv.amp-active~.-fd .-fg{flex:1 0;padding-right:10px}.-fv.amp-active~.-fd .-fy{height:20px;width:20px;background-color:transparent;border:0;cursor:pointer;padding:3px}.-fv.amp-active~.-fd .-fy svg{fill:#fff;width:100%;height:100%}.ap-o-burger-menu{display:none;position:fixed;top:0;left:0;width:100vw;height:100vh;padding:110px 20px 80px;z-index:16;background-color:#fff}@media(max-width:240px){.ap-o-burger-menu{padding:37px 20px 0}.has-banner~.ap-o-burger-menu{padding:calc(37px + 31px) 0 0 20px}}.ap-o-burger-menu-label{position:fixed;z-index:1001;top:12px;right:20px;cursor:pointer}.ap-o-burger-menu-label.mainmenuopen{z-index:1004}.has-banner+.ap-o-burger-menu-label{top:calc(12px + 31px)}.amp-hidden+.has-banner+.ap-o-burger-menu-label,amp-user-notification[hidden]+.has-banner+.ap-o-burger-menu-label{top:12px}@media(min-width:768px){.ap-o-burger-menu-label{right:30px}}@media(min-width:1024px){.ap-o-burger-menu-label{display:none}}.ap-o-burger-menu-icon{width:30px;height:30px}@media(min-width:1024px){.ap-o-burger-menu{display:none}}.ap-o-burger-menu.mainmenuopen{display:block;z-index:1003}.ap-o-burger-menu.mainmenuopen~.ap--main{max-height:calc(100vh - 55px)}.has-banner+.ap-o-burger-menu.mainmenuopen~.ap--main{max-height:calc(100vh - 55px - 31px)}.ap-o-burger-menu.mainmenuopen~.ap--footer{display:none}.-th{list-style:none;display:flex;flex-direction:column;height:100%;margin:1rem 0 0;padding:0;overflow-y:auto;-webkit-overflow-scrolling:touch}@media(max-width:240px){.-th{padding:1rem 0}}.-th .-th{margin-top:1rem}.-th .-th .-tp:last-child{margin-bottom:0}.-tp{margin-bottom:1rem;position:relative}.-tp:last-child{margin-top:auto}.-tp ul{display:none}.-td{position:absolute;left:0;top:0;width:100%;height:36px;padding:0;margin:0;background:none transparent;border:none;cursor:pointer;-webkit-appearance:none}.-td:focus{outline:5px auto -webkit-focus-ring-color}.-td:checked~ul{display:block}.-td:checked+.nav-icon .ap-a-ico{transform:rotate(0)}.-td+.nav-icon .ap-a-ico{display:inline-block;transform:rotate(-90deg)}.-tp .ap-a-ico{height:.6em;margin-bottom:.3em;margin-left:.3em;width:.6em}.-tv{position:relative;margin-right:20px;padding-bottom:10px;display:none}@media(max-width:240px){.-tv{margin-right:0}}@media(min-width:1024px){.-tv{margin-right:0;padding-right:30px;display:block}}.-tm{display:flex;align-items:center;font-size:11px;border:none;background:0 0}.-tm:hover{color:#005af0}.-tg{position:absolute;left:0;top:0;width:100%;height:100%;margin:0;padding:0;border:0;-webkit-appearance:none}@media(min-width:1024px){.-tg{width:calc(100% - 30px)}}.-ty{width:10px;height:10px;margin-left:5px}.-tb{list-style:none;display:none;position:absolute;right:15%;margin:0;padding:2px 8px;background:#fff;box-shadow:0 2px 10px 0 rgba(0,0,0,.07)}@media(max-width:240px){.-tb{overflow:auto;max-height:calc(100vh - 55px - 31px)}}.-tb:hover,.-tg:checked~.-tb,.-tg:hover~.-tb,.-tv .-tw{display:block}.-tb:focus-within{display:block}.mainmenuopen .-tv{display:block}.-tw{font-family:Poppins,system;font-weight:700;font-size:1.5em;color:#000}@media(min-width:1024px){.-tw{font-size:1rem}}.-tx{line-height:1.6rem;font-weight:400;color:#48525c;font-size:1rem}@media(min-width:1024px){.-tx{font-size:.875rem}}.-tx.active{text-decoration:underline}.-tw:hover{color:#005af0}.-tw.active{font-weight:700;color:#005af0}.ap--header{width:100%;max-width:2020px;margin:0 auto;position:-webkit-sticky;position:sticky;top:0;z-index:1001;background-color:#fff;box-shadow:0 2px 10px 0 rgba(0,0,0,.07)}.ap--header.mainmenuopen{z-index:1004}.ap--header.mainmenuopen~.ap--main{max-width:100vw;overflow-x:hidden}@media(min-width:1024px){.ap--header{top:0}.ap--header.has-banner{top:-31px}}.ap-o-header{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;max-width:1460px;padding:10px 0 0 20px;margin:0 auto}@media(min-width:1024px){.ap-o-header{display:flex;padding-left:30px}}.ap-o-header-home{position:-webkit-sticky;position:sticky;top:10px;display:flex;align-items:center;margin-right:auto;padding-bottom:10px;overflow:hidden}.ap-o-header-home-logo{height:30px;margin-right:6px;width:30px}.ap-o-header-home-sub-title,.ap-o-header-home-title{margin-left:4px;font-family:Poppins,system;font-weight:700;font-size:1.5em;color:#005af0}@media(min-width:1024px){.ap-o-header-home-sub-title,.ap-o-header-home-title{font-size:1.125rem}}.ap-o-header-home-sub-title{color:#000;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ap-o-header-main{display:none;flex:1 1 auto;padding:0 30px}@media(min-width:1024px){.ap-o-header-main{display:flex}}.ap-o-header-main-item{position:relative;display:flex;align-items:center;margin:0 18px -5px}.ap-o-header-main-link{display:flex;align-items:center;padding:0 0 14px;border:0;background:0 0}.ap-o-header-main-link-icon{font-size:8px;margin-left:5px;transform:rotate(0);transition:transform .2s ease}.ap-o-header-flyout:hover,.ap-o-header-main-link:focus~.ap-o-header-flyout,.ap-o-header-main-link:hover~.ap-o-header-flyout{opacity:1;pointer-events:all;transition:opacity .2s ease}.ap-o-header-flyout:focus-within{opacity:1;pointer-events:all;transition:opacity .2s ease}.ap-o-header-flyout{box-shadow:0 10px 25px 0 rgba(0,0,0,.2);position:absolute;top:95%;left:0;margin:0;padding:0 0 10px;pointer-events:none;opacity:0;list-style:none;background:#fff;border-radius:0 0 4px 4px;transition:opacity .2s ease}.ap-o-header-flyout:before{content:"";display:block;background:linear-gradient(180deg,rgba(0,0,0,.07) 0,hsla(0,0%,100%,.07));height:8px;margin-bottom:10px}.ap-o-header-flyout-item-secondary{margin:20px 0;white-space:nowrap;min-width:200px}.ap-o-header-flyout-item-secondary a:hover{color:#005af0}.ap-o-header-flyout-item-title{line-height:1.6rem;font-weight:400;color:#48525c;font-size:.875rem;font-family:Poppins,system;font-weight:700;color:#000;line-height:1.4em}.ap-o-header-flyout-item-title.secondary{padding:0 15px}.ap-o-header-flyout-item-description{line-height:1.6rem;font-weight:400;color:#48525c;font-size:.8125rem;opacity:.75;line-height:1.25em}.ap-o-header-flyout-primary-item{position:relative;width:300px}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link{box-shadow:0 10px 25px 0 rgba(0,0,0,.2);background-color:#005af0}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link-info>*{color:#fff}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link-info-stories .ap-o-header-flyout-item-description,.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link-info-stories .ap-o-header-flyout-item-title{color:#20202a}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link-info-email .ap-o-header-flyout-item-description,.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link-info-email .ap-o-header-flyout-item-title{color:#20202a}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link-icon{fill:#fff}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link-icon.email,.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link-icon.stories{fill:#20202a}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link.websites{background:linear-gradient(225deg,#00dcc0,#005af0 75%)}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link.stories{background:linear-gradient(225deg,#ec6600,#ffdc00 75%)}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link.ads{background:linear-gradient(225deg,#eb49e1,#5500d7 75%)}.ap-o-header-flyout-primary-item:hover .ap-o-header-flyout-primary-item-link.email{background:linear-gradient(225deg,#09a600,#e1eb64 75%)}.ap-o-header-flyout-primary-item-link{display:flex;align-items:center;border-radius:4px;padding:10px;margin:0 5px}.ap-o-header-flyout-primary-item-link-info{margin:0 20px 0 15px}.ap-o-header-flyout-primary-item-link-icon{display:flex;font-size:medium;box-sizing:initial;justify-content:center;width:2em;height:2em}.ap-o-header-flyout-primary-item-link-icon.websites{fill:url(#gradient-websites) #000}.ap-o-header-flyout-primary-item-link-icon.stories{fill:url(#gradient-stories) #000}.ap-o-header-flyout-primary-item-link-icon.ads{fill:url(#gradient-ads) #000}.ap-o-header-flyout-primary-item-link-icon.email{fill:url(#gradient-email) #000}#blm-banner{background:#111;color:#eee;display:block;text-align:center;padding:.5em}.ap--main>.-tf:first-child{padding-top:54px;padding-bottom:3rem}body{background-color:#fafafc}.-fb .-tf{position:relative;display:flex;flex-wrap:wrap;width:100%;max-width:1440px;padding:0 20px;margin-left:auto;margin-right:auto}@media(max-width:767px){.-fb .-tf{padding:0 15px}.-fb .-tf>div,.-fb .-tf section{min-width:0}}@media(min-width:768px){.-fb .-tf{display:grid;grid-gap:30px;grid-template-columns:repeat(24,minmax(0,1fr));padding:0 30px;grid-gap:0}}@media(min-width:1024px){.-fb .-tf{padding:0 15px}}.-fb .-t,.-fb .ap--help{grid-column:1;position:relative;width:100%;background:#fafafc;box-shadow:0 25px 40px 0 rgba(0,0,0,.05);padding-left:0;padding-right:0}@media(min-width:768px){.-fb .-t,.-fb .ap--help{grid-column:9/25}}@media(min-width:1024px){.-fb .-t,.-fb .ap--help{grid-column:7/25}.-fb .-t p.limit,.-fb .ap--help p.limit{max-width:70%}}@media(min-width:768px){.-fb .-t,.-fb .ap--help{grid-column:8/25}}@media(min-width:1024px){.-fb .-t,.-fb .ap--help{grid-column:6/25}}.-fb .-oy{grid-column:auto;padding:0}@media(min-width:768px){.-fb .-oy{grid-column:1/8;grid-row:span 6;margin-right:20px}}@media(min-width:1024px){.-fb .-oy{grid-column:1/6}}.-fb .ap--toc{box-shadow:20px 25px 40px 0 rgba(0,0,0,.05)}.-fb .ap--toc~.-t{box-shadow:-30px -5px 30px -20px rgba(0,0,0,.05)}@media(min-width:768px){.-fb .ap--toc{grid-column:8/25}.-fb .ap--toc~.-t{padding-top:0}}@media(min-width:768px)and (min-width:768px){.-fb .ap--toc~.-t{grid-column:8/25;padding-left:30px}}@media(min-width:768px)and (min-width:1024px){.-fb .ap--toc~.-t{grid-column:6/20;padding-left:30px;padding-right:30px}}@media(min-width:768px)and (min-width:768px){.-fb .ap--toc~.ap--help~.-t{grid-column-end:25}}@media(min-width:768px)and (min-width:1024px){.-fb .ap--toc~.ap--help~.-t{grid-column-end:25}}@media(min-width:1024px){.-fb .ap--toc{background:#fafafc;grid-column:20/25;grid-row:span 3;padding-top:93px;padding-bottom:25px}.-fb .ap--toc~.-t{padding-top:62px}}@media(min-width:1024px)and (max-width:767px){.-fb .ap--toc~.-t{padding-left:15px;padding-right:15px}}.-fb .-oy+.-t,.-fb .ap--toc+.-t{padding-top:62px}@media(max-width:767px){.-fb .-oy+.-t,.-fb .ap--toc+.-t{padding-left:15px;padding-right:15px}}@media(min-width:1024px){.-fb .-oy+.-t:nth-of-type(2),.-fb .-oy+.-t:nth-of-type(3),.-fb .ap--toc+.-t:nth-of-type(2),.-fb .ap--toc+.-t:nth-of-type(3){grid-row:1}}.-fb .ap--versions{position:relative;display:inline-flex;align-items:center;background:#fff;border:1px solid #e2e5e6;margin-top:5px}.-fb .ap--versions-toggle{border:0;padding:0 32px 0 8px;background:#fff;font-family:inherit;font-size:inherit;font-weight:inherit;-moz-appearance:none;-webkit-appearance:none;appearance:none}.-fb .ap--versions:after{content:"";position:absolute;right:8px;width:16px;height:35px;background:#fff;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64' fill='%2320202A'%3E%3Cpath d='M59.863 17.14l4.137 5.488-32 24.232-32-24.232 4.137-5.488 27.863 21.108z'%3E%3C/path%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;pointer-events:none}.-fb .ap--component-tags{margin-top:-1.5rem;margin-bottom:2rem}@media(min-width:768px){.-fb .-t,.-fb .ap--help{padding-left:30px;padding-right:30px}}.ap-code-preview,.ap-o-code-preview{position:relative;margin:1rem 0;background:#20202a}.ap-code-preview-controls,.ap-o-code-preview-controls{width:100%;display:flex;justify-content:center;align-items:center;margin:0 auto;padding:9px 0}.ap-code-preview-controls-button,.ap-o-code-preview-controls-button{-webkit-appearance:none;background-color:transparent;border:none;position:relative;padding:6px;cursor:pointer}.ap-code-preview-controls-icon,.ap-o-code-preview-controls-icon{width:22px;height:22px;fill:#fff;opacity:.6;transition:opacity .25s ease-out}.ap-code-preview-controls-button:focus .ap-code-preview-controls-icon,.ap-code-preview-controls-button:focus .ap-o-code-preview-controls-icon,.ap-code-preview-controls-button:hover .ap-code-preview-controls-icon,.ap-code-preview-controls-button:hover .ap-o-code-preview-controls-icon,.ap-o-code-preview-controls-button:focus .ap-code-preview-controls-icon,.ap-o-code-preview-controls-button:focus .ap-o-code-preview-controls-icon,.ap-o-code-preview-controls-button:hover .ap-code-preview-controls-icon,.ap-o-code-preview-controls-button:hover .ap-o-code-preview-controls-icon{opacity:1}.ap-code-preview-preview,.ap-o-code-preview-preview{position:relative;top:1em;margin:1em;background:#fff;box-shadow:0 2px 10px 0 rgba(0,0,0,.07)}@media(min-height:768px){.ap-code-preview-preview+div.-ta,.ap-o-code-preview-preview+div.-ta{min-height:0}}.ap-code-preview-preview-iframe,.ap-o-code-preview-preview-iframe{display:flex;justify-content:center;position:relative;margin:0 1em}@media screen and (max-width:412px){.ap-code-preview-preview-iframe amp-iframe,.ap-o-code-preview-preview-iframe amp-iframe{width:240px;height:427px}}@media screen and (min-width:413px){.ap-code-preview-preview-iframe amp-iframe,.ap-o-code-preview-preview-iframe amp-iframe{width:320px;height:569px}}.ap-code-preview-top-preview,.ap-o-code-preview-top-preview{position:relative;padding:0 1em;z-index:1;display:flex;flex-direction:column;justify-content:center;align-items:start}@media(min-width:1024px){.ap-code-preview-top-preview,.ap-o-code-preview-top-preview{padding:0 15%}}.ap-code-preview-top-preview+div.-ta,.ap-o-code-preview-top-preview+div.-ta{position:relative;width:100%;min-height:0;padding:1em 1em 0;margin-top:0}.ap-code-preview-top-preview amp-iframe,.ap-o-code-preview-top-preview amp-iframe{align-self:center}.ap-code-preview-side-preview,.ap-o-code-preview-side-preview{width:100%;height:100%;position:absolute;top:0;right:0;bottom:0;left:0;padding:0;margin:0}@media(min-width:768px){.ap-code-preview-side-preview,.ap-o-code-preview-side-preview{width:auto;left:60%;background-color:#1c1c24}}@media(max-width:767px){.ap-code-preview-side-preview,.ap-o-code-preview-side-preview{overflow:hidden;pointer-events:none}.ap-code-preview-side-preview-active,.ap-o-code-preview-side-preview-active{pointer-events:auto}}.ap-code-preview-side-preview-frame,.ap-o-code-preview-side-preview-frame{position:absolute;max-height:100%;right:15px;top:auto;background-color:#fff}@media(max-width:767px){.ap-code-preview-side-preview-frame,.ap-o-code-preview-side-preview-frame{position:static;background:#fff;pointer-events:none;transform:translateY(100%);transition:transform .2s cubic-bezier(0,0,.3,1)}.ap-code-preview-side-preview-frame.show,.ap-o-code-preview-side-preview-frame.show{transform:translateY(0);pointer-events:auto;height:100%}}.ap-code-preview-iframe,.ap-o-code-preview-iframe{background:#fff;margin-bottom:1em}.ap-code-preview.side-frame .-ta,.ap-code-preview.top-frame .-ta,.ap-o-code-preview.side-frame .-ta,.ap-o-code-preview.top-frame .-ta{min-height:150px;max-height:450px}.ap-code-preview.side-frame .-ta,.ap-o-code-preview.side-frame .-ta{width:100%;margin:0;background:0 0}@media(min-width:768px){.ap-code-preview.side-frame .-ta,.ap-o-code-preview.side-frame .-ta{width:60%;min-height:580px}}@media(min-width:1024px){.ap-code-preview.side-frame .-ta,.ap-o-code-preview.side-frame .-ta{min-height:738px}}@media(min-width:1280px){.ap-code-preview.side-frame .-ta,.ap-o-code-preview.side-frame .-ta{min-height:842px}}@media(min-width:1441px){.ap-code-preview.side-frame .-ta,.ap-o-code-preview.side-frame .-ta{min-height:746px}}.ap-a-fab{display:flex;justify-content:center;width:56px;position:absolute;bottom:16px;right:16px;padding:0;font-size:24px;line-height:56px;user-select:none;cursor:pointer;z-index:14;color:#fff;background-color:#005af0;border:none;border-radius:50%;box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);transition:box-shadow .28s cubic-bezier(.4,0,.2,1);pointer-events:auto}.ap-a-fab:active{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.ap-a-fab-show{transform:scale(0);animation:expand .25s ease-in-out .25s both}.ap-a-fab-hide{transform:scale(1);animation:collapse .25s ease-in-out both}@media(min-width:768px){.ap-a-fab{display:none}}.-ta{display:flex;overflow-x:auto;margin:1.1rem 0 0;padding:0 1em;color:#fff;line-height:1.3em;background:#20202a;font-size:.9em}.-ta:after{content:" ";-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.-ta::-webkit-scrollbar{width:6px;height:6px}.-ta::-webkit-scrollbar-thumb{border-radius:3px;background-color:#91979d}.-ta::-webkit-scrollbar-corner{background-color:transparent}.-ta::-webkit-scrollbar-thumb{border-radius:0}@media(min-width:768px){.-ta{max-width:100%;margin-right:-30px}}.-ta code,.-ta pre{font-family:Fira Mono,monospace;font-weight:500;white-space:pre;font-size:.9rem;padding:unset;word-break:normal;color:inherit;background:0 0}.-ta .hll{background-color:#49483e}.-ta .c{color:#75715e}.-ta .k{color:#66d9ef}.-ta .l{color:#ae81ff}.-ta .n{color:#f8f8f2}.-ta .o{color:#f15a5a}.-ta .p{color:#f8f8f2}.-ta .c1,.-ta .ch,.-ta .cm,.-ta .cp,.-ta .cpf,.-ta .cs{color:#75715e}.-ta .gd{color:#f15a5a}.-ta .ge{font-style:italic}.-ta .gi{color:#a6e22e}.-ta .gs{font-weight:700}.-ta .gu{color:#75715e}.-ta .kc,.-ta .kd{color:#66d9ef}.-ta .kn{color:#f15a5a}.-ta .kp,.-ta .kr,.-ta .kt{color:#66d9ef}.-ta .ld{color:#e6db74}.-ta .m{color:#ae81ff}.-ta .s{color:#e6db74}.-ta .na{color:#a6e22e}.-ta .nb{color:#f8f8f2}.-ta .nc{color:#a6e22e}.-ta .no{color:#66d9ef}.-ta .nd{color:#a6e22e}.-ta .ni{color:#f8f8f2}.-ta .ne,.-ta .nf{color:#a6e22e}.-ta .nl,.-ta .nn{color:#f8f8f2}.-ta .nx{color:#fff}.-ta .py{color:#f8f8f2}.-ta .nt{color:#f15a5a}.-ta .nv{color:#f8f8f2}.-ta .ow{color:#f15a5a}.-ta .w{color:#f8f8f2}.-ta .mb,.-ta .mf,.-ta .mh,.-ta .mi,.-ta .mo{color:#ae81ff}.-ta .dl,.-ta .s2,.-ta .sa,.-ta .sb,.-ta .sc,.-ta .sd{color:#e6db74}.-ta .se{color:#ae81ff}.-ta .s1,.-ta .sh,.-ta .si,.-ta .sr,.-ta .ss,.-ta .sx{color:#e6db74}.-ta .bp{color:#f8f8f2}.-ta .fm{color:#a6e22e}.-ta .vc,.-ta .vg,.-ta .vi,.-ta .vm{color:#f8f8f2}.-ta .il{color:#ae81ff}table{table-layout:fixed;width:100%;position:relative;border-collapse:collapse;padding:0 0 0 20px;margin:1.5em -20px 2em;display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;line-height:1.6rem;font-weight:400;color:#48525c;font-size:.875rem}@media(min-width:768px){table{padding:0;margin:1.5em 0 2em}}thead{font-weight:700}thead tr{text-align:left}thead tr th{padding:20px}tbody tr,thead tr th{border-bottom:1px solid #e2e5e6}tbody tr:nth-child(odd){background-color:hsla(0,0%,100%,.5)}tbody tr td:first-child{border-right:1px solid #e2e5e6}tbody td{padding:10px 20px;text-align:left;vertical-align:top;width:50%}@media(min-width:768px){tbody td{padding:20px}}@media(min-width:1024px){tbody td{width:25%}}tbody td code{display:inline;padding:2px 4px;font-family:Fira Mono,monospace;font-weight:500;word-break:normal;color:#000;background-color:#e2e5e6;font-size:.9em;color:#005af0}</style><link rel="manifest" href="/manifest.json"></head><body class="ap--websites"> <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <symbol id="stackoverflow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 25"><path d="M14.2 14.7h1.6V25H0V14.7h1.6v8.6h12.5c.1-2.8.1-5.7.1-8.6zM9.5 3.2c1.8 2.7 3.6 5.4 5.4 8.2.6-.4 1.1-.8 1.7-1.2C14.8 7.5 13 4.8 11.2 2c-.5.5-1.1.8-1.7 1.2zm5.1 8.5c-2.8-1.7-5.5-3.3-8.2-5-.4.6-.7 1.2-1.1 1.8 2.7 1.7 5.5 3.3 8.2 5 .4-.6.8-1.2 1.1-1.8zM17.4 0c-.7.1-1.3.2-2 .4.5 3.2 1.1 6.5 1.6 9.7.7-.1 1.3-.2 2-.4-.5-3.2-1.1-6.5-1.6-9.7zm-4 14.1c-3.1-.9-6.2-1.7-9.2-2.6-.2.7-.4 1.4-.5 2 3.1.9 6.2 1.7 9.2 2.6.1-.6.3-1.3.5-2zm-.9 5.5H3v2.1h9.5v-2.1zm.3-2.7c-3.2-.3-6.3-.6-9.5-.9-.1.7-.1 1.4-.2 2.1 3.2.3 6.3.6 9.5.9 0-.8.1-1.4.2-2.1z"/></symbol><symbol id="github" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <path d="M32 0.792c-17.68 0-32 14.328-32 32 0 14.141 9.168 26.133 21.88 30.36 1.6 0.301 2.187-0.688 2.187-1.539 0-0.76-0.027-2.773-0.040-5.44-8.901 1.931-10.779-4.293-10.779-4.293-1.456-3.693-3.56-4.68-3.56-4.68-2.899-1.984 0.224-1.944 0.224-1.944 3.213 0.224 4.901 3.296 4.901 3.296 2.853 4.893 7.491 3.48 9.32 2.661 0.288-2.069 1.112-3.48 2.027-4.28-7.107-0.8-14.576-3.552-14.576-15.813 0-3.493 1.24-6.347 3.293-8.587-0.36-0.808-1.44-4.061 0.28-8.469 0 0 2.68-0.859 8.8 3.28 2.56-0.712 5.28-1.064 8-1.080 2.72 0.016 5.44 0.368 8 1.080 6.080-4.139 8.76-3.28 8.76-3.28 1.72 4.408 0.64 7.661 0.32 8.469 2.040 2.24 3.28 5.093 3.28 8.587 0 12.293-7.48 15-14.6 15.787 1.12 0.96 2.16 2.923 2.16 5.92 0 4.283-0.040 7.723-0.040 8.763 0 0.84 0.56 1.84 2.2 1.52 12.803-4.197 21.963-16.197 21.963-30.317 0-17.672-14.328-32-32-32z"/> </symbol><symbol id="wordpress" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M57.251 18.2A28.688 28.688 0 0 1 60.766 32c0 10.611-5.749 19.883-14.301 24.867l8.787-25.405c1.64-4.107 2.187-7.389 2.187-10.304 0-1.08-.069-2.08-.187-2.96zm-21.283.277c1.725-.08 3.285-.28 3.285-.28 1.552-.2 1.371-2.48-.179-2.397 0 0-4.68.36-7.68.36-2.837 0-7.6-.4-7.6-.4-1.56-.08-1.763 2.28-.2 2.36 0 0 1.44.163 3 .24l4.48 12.28-6.32 18.88L14.277 18.4c1.731-.08 3.291-.267 3.291-.267 1.56-.2 1.376-2.48-.173-2.389 0 0-4.656.368-7.664.368-.533 0-1.168-.021-1.84-.04C13.096 8.4 21.96 3.24 32 3.24a28.642 28.642 0 0 1 19.429 7.555c-.123-.008-.243-.024-.376-.024-2.827 0-4.832 2.461-4.832 5.104 0 2.373 1.368 4.381 2.827 6.749 1.096 1.92 2.373 4.381 2.373 7.939 0 2.44-.944 5.317-2.189 9.277l-2.867 9.56-10.4-30.96.003.037zM32 60.757c-2.824 0-5.549-.408-8.128-1.165l8.632-25.083 8.84 24.232c.064.141.133.269.208.397A28.794 28.794 0 0 1 32 60.762zM3.229 32c0-4.171.896-8.133 2.493-11.707L19.439 57.89C9.85 53.226 3.231 43.389 3.228 31.999zM32 0C14.36 0 0 14.36 0 32s14.36 32 32 32 32-14.36 32-32S49.64 0 32 0z"/></symbol><symbol id="youtube" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M62.664 16.542c-.773-2.708-2.862-4.797-5.514-5.556l-.057-.014c-4.989-1.336-25.065-1.336-25.065-1.336s-20.026-.027-25.065 1.337c-2.708.773-4.797 2.862-5.556 5.514l-.014.057C.507 21.107 0 26.354 0 31.72l.001.327v-.017.252a83.84 83.84 0 0 0 1.475 15.695l-.083-.521c.773 2.708 2.862 4.797 5.513 5.556l.057.014c4.983 1.339 25.065 1.339 25.065 1.339s20.023 0 25.065-1.339c2.708-.773 4.797-2.862 5.556-5.514l.014-.057c.85-4.469 1.336-9.609 1.336-14.863l-.002-.595v.03c.002-.184.002-.403.002-.621 0-5.255-.486-10.396-1.416-15.38l.08.515zM25.621 41.608V22.42l16.71 9.609z"/></symbol><symbol id="twitter" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <path d="M63.875 12.186c-2.36 1.037-4.88 1.744-7.533 2.067 2.704-1.629 4.784-4.197 5.768-7.261-2.536 1.48-5.346 2.557-8.338 3.157-2.389-2.557-5.794-4.157-9.576-4.157-7.245 0-13.119 5.874-13.119 13.111 0 1.040 0.12 2.040 0.339 2.997-10.906-0.515-20.572-5.752-27.042-13.669-1.139 1.925-1.776 4.162-1.776 6.6 0 4.56 2.32 8.568 5.834 10.922-2.152-0.069-4.176-0.661-5.941-1.643v0.163c0 6.36 4.514 11.663 10.522 12.871-1.101 0.296-2.264 0.456-3.456 0.456-0.837 0-1.64-0.080-2.443-0.229 1.683 5.208 6.52 9.005 12.277 9.112-4.48 3.517-10.157 5.613-16.271 5.613-1.040 0-2.077-0.061-3.12-0.179 5.837 3.717 12.714 5.89 20.151 5.89 24.143 0 37.329-19.989 37.329-37.294 0-0.557 0-1.12-0.040-1.68 2.563-1.837 4.8-4.16 6.56-6.794l-0.125-0.053z"/> </symbol><symbol id="download" viewBox="0 0 64 64"> <path d="M8.8 62.32c0-0.88 0.72-1.68 1.68-1.68 10.8 0 32.32 0 43.040 0 0.88 0 1.68 0.72 1.68 1.68 0 0.88-0.72 1.68-1.68 1.68-10.8 0-32.32 0-43.040 0-0.96 0-1.68-0.72-1.68-1.68z"/> <path d="M49.44 34.56c0.72-0.72 0.72-1.84 0-2.56s-1.84-0.72-2.56 0l-13.040 13.040v-43.28c0-0.96-0.88-1.76-1.84-1.76-1.040 0-1.84 0.8-1.84 1.76v43.28l-13.040-13.12c-0.72-0.72-1.84-0.72-2.56 0s-0.72 1.84 0 2.56l16.24 16.24c0.72 0.72 1.84 0.72 2.56 0l16.080-16.16z"/> </symbol><symbol id="internal" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M43.16 10.18c-0.881-0.881-2.322-0.881-3.203 0s-0.881 2.322 0 3.203l16.335 16.335h-54.051c-1.281 0-2.242 1.041-2.242 2.242 0 1.281 0.961 2.322 2.242 2.322h54.051l-16.415 16.335c-0.881 0.881-0.881 2.322 0 3.203s2.322 0.881 3.203 0l20.259-20.259c0.881-0.881 0.881-2.322 0-3.203l-20.179-20.179z"/></symbol><symbol id="external" viewBox="0 0 64 64"> <path d="M28.879 11.24c-0.841-0.841-2.206-0.841-3.048 0s-0.841 2.207 0 3.048l15.543 15.543h-39.241c-1.219 0-2.133 0.987-2.133 2.133 0 1.219 0.914 2.207 2.133 2.207h39.241l-15.616 15.543c-0.841 0.841-0.841 2.206 0 3.048 0.835 0.841 2.206 0.841 3.048 0l19.273-19.279c0.841-0.841 0.841-2.206 0-3.048l-19.2-19.194zM59.429 27.392c2.511 0 4.571 2.060 4.571 4.571s-2.060 4.571-4.571 4.571-4.571-2.060-4.571-4.571 2.060-4.571 4.571-4.571z"/> </symbol><symbol id="speech-bubble" viewBox="0 0 38 38"><g fill="none" fill-rule="evenodd"><path stroke="#005AF0" stroke-width="1.94" d="M1.544 19.002c0 9.64 7.816 17.457 17.457 17.457 3.707 0 6.783-.838 9.61-2.809.936-.653 7.057 3.628 7.848 2.809.71-.737-3.264-7.394-2.69-8.247 1.868-2.78 2.69-5.61 2.69-9.21C36.459 9.36 28.642 1.544 19 1.544c-9.639 0-17.456 7.817-17.456 17.458z"/><path fill="#005AF0" fill-rule="nonzero" d="M17.621 28.71h-1.14l1.127-6.824-3.49.005-.049.001c-.314 0-.569-.255-.569-.57 0-.134.126-.362.126-.362l6.272-10.46 1.159.005-1.156 6.834 3.509-.004.055-.001c.315 0 .57.254.57.569 0 .127-.05.24-.122.335L17.621 28.71z"/></g></symbol><symbol id="warning-sign" viewBox="0 0 38 38"><g fill="none" fill-rule="evenodd"><path stroke="#F3C000" stroke-width="2" d="M19.843 2.29l16.643 33.671c.177.356.03.788-.326.964-.1.05-.208.075-.319.075H2.171c-.398 0-.72-.322-.72-.72 0-.113.026-.224.077-.325l17.028-33.67c.179-.355.612-.497.967-.318.139.07.251.184.32.324z"/><path fill="#F3C000" fill-rule="nonzero" d="M17.621 32.71h-1.14l1.127-6.824-3.49.005-.049.001c-.314 0-.569-.255-.569-.57 0-.134.126-.362.126-.362l6.272-10.46 1.159.005-1.156 6.834 3.509-.004.055-.001c.315 0 .57.254.57.569 0 .127-.05.24-.122.335L17.621 32.71z"/></g></symbol><symbol id="sidebar-toggle" viewBox="0 0 64 64"> <path d="M36.032 7.9c0.985-0.996 2.624-0.996 3.643 0 0.985 0.963 0.985 2.565 0 3.526l-18.471 18.060h40.246c1.421 0.002 2.55 1.107 2.55 2.496s-1.129 2.529-2.55 2.529h-40.246l18.471 18.026c0.985 0.996 0.985 2.601 0 3.562-1.019 0.996-2.66 0.996-3.643 0l-22.844-22.336c-1.019-0.963-1.019-2.565 0-3.526l22.844-22.338z"/> <path d="M2.071 3.012c1.144 0 2.071 0.927 2.071 2.071v53.835c0 1.144-0.927 2.071-2.071 2.071s-2.071-0.927-2.071-2.071v-53.835c0-1.144 0.927-2.071 2.071-2.071z"/> </symbol><symbol id="contentmenu" viewBox="0 0 64 64"> <path d="M1.351 46.865h36.036c0.746 0 1.351 0.605 1.351 1.351s-0.605 1.351-1.351 1.351h-36.036c-0.746 0-1.351-0.605-1.351-1.351s0.605-1.351 1.351-1.351zM1.351 14.432h40.541c0.746 0 1.351 0.605 1.351 1.351s-0.605 1.351-1.351 1.351h-40.541c-0.746 0-1.351-0.605-1.351-1.351s0.605-1.351 1.351-1.351zM1.351 38.757h31.532c0.746 0 1.351 0.605 1.351 1.351s-0.605 1.351-1.351 1.351h-31.532c-0.746 0-1.351-0.605-1.351-1.351s0.605-1.351 1.351-1.351zM1.351 30.649h37.838c0.746 0 1.351 0.605 1.351 1.351s-0.605 1.351-1.351 1.351h-37.838c-0.746 0-1.351-0.605-1.351-1.351s0.605-1.351 1.351-1.351zM1.351 22.541h34.234c0.746 0 1.351 0.605 1.351 1.351s-0.605 1.351-1.351 1.351h-34.234c-0.746 0-1.351-0.605-1.351-1.351s0.605-1.351 1.351-1.351zM52.249 29.371c-0.992 0-1.231-0.566-0.525-1.272l5.296-5.296c0.353-0.353 0.931-0.348 1.279 0l5.296 5.296c0.702 0.702 0.466 1.272-0.525 1.272h-10.822zM63.069 35.153c0.992 0 1.231 0.566 0.525 1.272l-5.296 5.296c-0.353 0.353-0.931 0.348-1.279 0l-5.296-5.296c-0.702-0.702-0.466-1.272 0.525-1.272h10.822z"/> </symbol><symbol id="close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <path d="M39.503 32l22.963-22.963c2.046-2.046 2.046-5.457 0-7.503s-5.456-2.046-7.503 0l-22.963 22.963-22.963-22.963c-2.046-2.046-5.457-2.046-7.503 0s-2.046 5.457 0 7.503l22.963 22.963-22.963 22.963c-2.046 2.046-2.046 5.456 0 7.503s5.457 2.046 7.503 0l22.963-22.963 22.963 22.963c2.046 2.046 5.456 2.046 7.503 0s2.046-5.456 0-7.503l-22.963-22.963z"/> </symbol><symbol id="menu" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <path d="M2.133 13.867h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"/> <path d="M2.133 28.8h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"/> <path d="M2.133 43.733h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"/> </symbol><symbol id="wrench" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <path d="M64 18.267c0 1.608-0.214 3.21-0.636 4.767l0.008 0.169c0.028 0.598-0.186 1.18-0.592 1.619-2.713 7.035-9.527 11.712-17.107 11.712-1.852 0-3.671-0.275-5.427-0.819l-25.943 25.854c-1.573 1.567-3.667 2.431-5.889 2.431s-4.318-0.864-5.89-2.431l-0.087-0.087c-3.25-3.238-3.25-8.508 0-11.747l23.75-23.669c0.66-0.657 1.046-1.529 1.090-2.456l0.173-3.404c-0.070-0.657-0.105-1.308-0.105-1.939 0-10.074 8.221-18.267 18.327-18.267 3.298 0 6.532 0.883 9.353 2.555 0.602 0.357 1.005 0.979 1.083 1.675 0.011 0.098 0.017 0.161 0.020 0.237 0.044 1.158-0.297 1.536-9.858 10.586l3.847 3.921c1.149-1.058 3.185-2.929 8.997-8.27 0.542-0.497 1.293-0.697 2.010-0.534 0.719 0.163 1.311 0.668 1.583 1.351 0.856 2.147 1.291 4.418 1.292 6.745zM59.819 22.4c0.395-1.346 0.595-2.737 0.594-4.132 0-1.194-0.141-2.367-0.422-3.507-2.922 2.685-8.959 8.231-9.040 8.307-0.536 0.494-1.37 0.474-1.88-0.046l-6.953-7.087c-0.252-0.258-0.39-0.605-0.384-0.965s0.158-0.702 0.42-0.95c2.985-2.825 7.47-7.107 9.54-9.166-1.884-0.84-3.936-1.278-6.022-1.278-8.129 0-14.742 6.59-14.742 14.691 0 0.533 0.032 1.090 0.096 1.654 0.007 0.071 0.010 0.142 0.007 0.214l-0.174 3.646c-0.087 1.818-0.847 3.528-2.138 4.816l-23.75 23.668c-1.85 1.844-1.85 4.844 0 6.688l0.087 0.087c0.897 0.893 2.088 1.385 3.356 1.385s2.46-0.492 3.355-1.385l26.429-26.338c0.2-0.199 0.419-0.39 0.693-0.601 0.377-0.292 0.882-0.363 1.326-0.187 1.743 0.692 3.578 1.044 5.456 1.044 6.243 0 11.831-3.943 13.905-9.811 0.044-0.126 0.107-0.244 0.187-0.351-0.002-0.134 0.016-0.268 0.054-0.396z"/> </symbol><symbol id="template" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M1.44 0h62.56v64h-64v-64h1.44zM20.64 60.88v-39.52h-17.76v39.6h17.76zM23.44 21.36v39.6h37.44v-39.6h-37.44zM2.88 18.24h58.080v-15.36h-58.080v15.36z"/></symbol><symbol id="learn" viewBox="0 0 64 64"> <path d="M57.674 35.257c0 1.779 1.416 3.221 3.163 3.221s3.163-1.442 3.163-3.221c0-1.155-0.602-2.16-1.498-2.728v-8.973c0-0.682-0.401-1.297-1.018-1.563l-29.585-12.716c-0.413-0.178-0.881-0.178-1.295 0l-29.586 12.716c-0.617 0.265-1.018 0.881-1.018 1.563s0.401 1.297 1.018 1.562l6.662 2.863v17.587c0 4.624 7.288 9.29 23.571 9.29s23.571-4.666 23.571-9.29v-17.587l4.349-1.869v6.417c-0.896 0.569-1.497 1.573-1.497 2.728zM51.491 45.567c0 1.575-4.797 5.898-20.24 5.898s-20.24-4.323-20.24-5.898v-16.155l19.593 8.421c0.207 0.089 0.427 0.134 0.647 0.134s0.441-0.045 0.647-0.134l19.593-8.421v16.155zM31.251 34.43l-25.303-10.875 25.303-10.875 25.302 10.875-25.302 10.875z"/> </symbol><symbol id="examples-flyout" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 20"><g><path d="M20 19.3a.9.9 0 1 1 0-1.7 1.9 1.9 0 0 0 1.9-1.9v-3a3.6 3.6 0 0 1 1.3-2.7 3.6 3.6 0 0 1-1.3-2.8v-3A1.9 1.9 0 0 0 20 2.3a.9.9 0 1 1 0-1.7 3.6 3.6 0 0 1 3.6 3.6v3a1.9 1.9 0 0 0 2 2v1.6a1.9 1.9 0 0 0-2 2v3a3.6 3.6 0 0 1-3.6 3.5zm-14 0a3.6 3.6 0 0 1-3.6-3.6v-3a1.9 1.9 0 0 0-2-1.9V9.1a1.9 1.9 0 0 0 2-1.9v-3A3.6 3.6 0 0 1 6 .6a.9.9 0 1 1 0 1.8A1.9 1.9 0 0 0 4 4.2v3A3.6 3.6 0 0 1 2.8 10a3.6 3.6 0 0 1 1.3 2.7v3A1.9 1.9 0 0 0 6 17.6a.9.9 0 1 1 0 1.7z"/><g transform="translate(5.8 8.5)"><circle cx="12.3" cy="1.4" r="1.4"/><circle cx="7.3" cy="1.4" r="1.4"/><circle cx="2.2" cy="1.4" r="1.4"/></g></g></symbol><symbol id="components-flyout" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 22"><path d="M8.7 17l-2.5-2.2-4-3.5-.9-.8v1l2.5-2.2 4-3.5 1-.8c.2-.3.2-.8 0-1a.8.8 0 0 0-1.2 0L5.1 6l-4 3.6-.8.8c-.3.2-.3.8 0 1l2.5 2.2 4 3.6.8.8c.3.2.8.3 1.1 0 .3-.3.3-.8 0-1.1zM19.3 5l2.5 2.2 4 3.5.9.8v-1l-2.5 2.2-4 3.5-.9.8c-.3.3-.3.8 0 1 .3.4.8.3 1 0L23 16l4-3.6.9-.8c.3-.2.3-.8 0-1l-2.5-2.3-4-3.5-1-.8c-.2-.3-.7-.3-1 0-.3.3-.3.8 0 1zm-8 16.4l.7-2 1.6-5a3563.7 3563.7 0 0 1 2-5.8l1.7-5.1.8-2.5c.2-.4-.1-.9-.5-1a.8.8 0 0 0-1 .6c-.1.7-.4 1.3-.6 2l-1.6 4.9-2 5.9-1.7 5-.8 2.6c-.2.4.1.8.5 1a.8.8 0 0 0 1-.6z"/></symbol><symbol id="guides-documents" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 31 32"><path d="M6.7 28H1.2c-.4 0-.6-.4-.6-.8L.5.7c0-.4.3-.7.7-.7h21.1c.5 0 .7.3.7.7V2c0 .5-.2.7-.7.7-.4 0-.6-.2-.6-.7v-.6H1.8L2 26.6h4.8c.4 0 .7.2.7.6 0 .4-.3.7-.7.7z"/><path d="M8 6.8H6c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7h2c.5 0 .7.3.7.7 0 .4-.2.7-.7.7zM8 10.9H6c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7h2c.5 0 .7.3.7.7 0 .4-.2.7-.7.7zM8 15H6c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7h2c.5 0 .7.3.7.7 0 .4-.2.7-.7.7zM8 19H6c-.4 0-.7-.2-.7-.6 0-.4.3-.7.7-.7h2c.5 0 .7.3.7.7 0 .4-.2.7-.7.7z"/><path d="M29.8 4H8.7c-.5 0-.7.4-.7.8v26.5c0 .4.3.7.7.7h21.1c.4 0 .7-.3.7-.7V4.8c0-.4-.3-.7-.7-.7zm-.6 26.6H9.4V5.4h19.8v25.2z"/><path d="M18.1 22.8h-.6l.6-3.8h-1.9c-.2 0-.3-.1-.3-.3v-.2l3.4-5.8h.7l-.7 3.8h2c.2 0 .3.1.3.3v.2L18 22.8z"/></symbol><symbol id="start" viewBox="0 0 64 64"> <path d="M63.195 1.874c-0.143-0.52-0.549-0.926-1.069-1.069-10.765-2.978-20.385 2.978-24.355 6.948l-11.452 11.452-5.421-1.756c-3.551-1.163-7.454-0.217-10.078 2.443l-3.359 3.359c-0.582 0.594-0.582 1.544 0 2.138l7.329 7.329-4.199 6.948c-0.343 0.593-0.25 1.342 0.229 1.832l11.681 11.605c0.471 0.504 1.223 0.63 1.832 0.305l6.948-4.123h0.076l7.329 7.329c0.594 0.582 1.544 0.582 2.138 0l3.359-3.359c2.66-2.624 3.606-6.527 2.443-10.078l-1.756-5.421 11.452-11.452c3.894-4.047 9.849-13.666 6.871-24.431zM23.799 50.126l-9.925-9.925 3.13-5.268 12.063 12.063-5.268 3.13zM54.109 24.015l-12.139 12.139c-0.4 0.399-0.547 0.987-0.382 1.527l2.061 6.337c0.783 2.448 0.136 5.128-1.68 6.948l-2.29 2.29-29.012-29.012 2.29-2.29c1.819-1.815 4.5-2.463 6.948-1.68l6.337 2.061c0.54 0.165 1.128 0.018 1.527-0.382l12.216-12.063c3.436-3.359 11.452-8.398 20.461-6.337 2.061 9.085-2.978 17.102-6.337 20.461z"/> <path d="M10.667 51.195l-9.009 9.009c-0.478 0.358-0.703 0.963-0.576 1.547s0.583 1.040 1.167 1.167c0.584 0.127 1.188-0.098 1.547-0.576l9.009-9.009c0.456-0.608 0.396-1.459-0.142-1.996s-1.388-0.598-1.996-0.142z"/> <path d="M11.66 63.563c0.594 0.582 1.544 0.582 2.138 0l4.581-4.581c0.456-0.608 0.395-1.459-0.142-1.996s-1.388-0.598-1.996-0.142l-4.581 4.581c-0.582 0.594-0.582 1.544 0 2.138z"/> <path d="M1.505 52.798c0.403-0.006 0.787-0.17 1.069-0.458l4.581-4.581c0.478-0.358 0.703-0.963 0.576-1.547s-0.583-1.040-1.167-1.167c-0.584-0.127-1.188 0.098-1.547 0.576l-4.581 4.581c-0.428 0.436-0.554 1.086-0.322 1.65s0.78 0.937 1.391 0.945z"/> <path d="M43.726 13.021c-2.003 2.003-2.003 5.25 0 7.253s5.25 2.003 7.253 0c2.003-2.003 2.003-5.25 0-7.253s-5.25-2.003-7.253 0zM48.841 18.136c-0.699 0.692-1.79 0.794-2.605 0.243s-1.127-1.601-0.745-2.508c0.382-0.907 1.351-1.417 2.315-1.219s1.653 1.050 1.646 2.033c-0.004 0.545-0.223 1.067-0.611 1.451z"/> </symbol><symbol id="amp-email" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <defs> <linearGradient id="gradient-email" x1="76.2776137%" x2="20.8316146%" y1="-25.8400575%" y2="121.578822%"> <stop offset="0%" stop-color="#F1F068"/> <stop offset="46.2139774%" stop-color="#96D64F"/> <stop offset="100%" stop-color="#2DB932"/> </linearGradient> </defs> <path d="M64 14.080c0-3.291-2.56-5.851-5.851-5.851h-52.297c-3.291 0-5.851 2.56-5.851 5.851v35.84c0 3.291 2.56 5.851 5.851 5.851h52.297c3.291 0 5.851-2.56 5.851-5.851v-35.84zM5.851 11.154h52.297c0.183 0 0.366 0 0.549 0l-24.503 25.417c-0.549 0.549-1.28 0.914-2.194 0.914-0.731 0-1.646-0.366-2.194-0.914l-24.32-25.417c0 0 0.183 0 0.366 0zM2.926 14.080c0-0.366 0-0.731 0.183-1.097l15.36 16.091-15.543 19.2v-34.194zM58.149 52.846h-52.297c-0.731 0-1.646-0.366-2.194-0.914l16.823-20.663 7.131 7.497c1.097 1.097 2.56 1.829 4.206 1.829s3.109-0.731 4.206-1.829l6.583-6.949 17.371 20.114c-0.366 0.549-1.097 0.914-1.829 0.914v0zM61.074 48.274l-16.091-18.834 15.909-16.64c0.183 0.366 0.183 0.731 0.183 1.097v34.377z"/> </symbol><symbol id="amp-ads" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <defs> <linearGradient id="gradient-ads" x1="100%" x2="14.5415777%" y1="0%" y2="123.368881%"> <stop offset="0%" stop-color="#FF52E1"/> <stop offset="100%" stop-color="#5500D7"/> </linearGradient> </defs> <path d="M56.399 14.68c3.654-3.846 9.616-10.963 6.924-13.847-2.885-2.885-10.001 3.269-13.847 6.731l-0.577-0.577c-0.385-0.385-0.962-0.577-1.539-0.385l-15.963 3.077c-0.385 0-0.577 0.192-0.769 0.385l-30.195 30.195c-0.577 0.577-0.577 1.731 0 2.308l20.963 20.963c0.385 0.385 0.769 0.385 1.154 0.385s0.769-0.192 1.154-0.385l30.003-30.003c0.192-0.192 0.385-0.577 0.385-0.769v0l3.077-15.963c0.192-0.577 0-1.154-0.385-1.539l-0.385-0.577zM53.899 16.988l-2.885 14.424-28.464 28.656-18.655-18.655 28.656-28.656 14.424-2.885c-1.539 1.731-4.039 4.423-5.962 7.116-1.923-0.192-3.654 0.385-5.193 1.923-2.5 2.5-2.5 6.731 0 9.232s6.731 2.5 9.232 0c1.346-1.346 2.116-3.27 1.923-5.193-0.192-1.154-0.577-2.308-1.154-3.077-0.192-0.385-0.385-0.577-0.769-0.769-0.192-0.192-0.577-0.577-0.769-0.769 1.154-1.731 2.885-3.654 5.193-5.962l2.5 2.5 1.923 2.116zM43.321 24.873c-0.192 0.385-0.385 0.577-0.577 0.962-1.346 1.346-3.27 1.346-4.616 0s-1.346-3.27 0-4.616c0.192-0.192 0.577-0.385 0.962-0.577 1.154-0.577 2.308-0.385 3.462 0.385 0.192 0 0.192 0.192 0.385 0.192 0 0 0.192 0.192 0.192 0.385 0.577 0.962 0.769 2.116 0.192 3.27zM54.091 12.372l-2.5-2.5c4.039-3.846 7.308-5.77 8.847-6.347-0.577 1.539-2.5 4.616-6.347 8.847z"/> </symbol><symbol id="amp-stories" viewBox="0 0 36 32"> <defs> <linearGradient id="gradient-stories" x1="81.726943%" x2="23.7165981%" y1="-28.3832685%" y2="119.978062%"> <stop offset="0%" stop-color="#FFF300"/> <stop offset="100%" stop-color="#FF8F00"/> </linearGradient> </defs> <path d="M7.111 0h21.333v32h-21.333v-32zM9.481 2.37v27.259h16.593v-27.259h-16.593zM0 4.741h2.37v22.519h-2.37v-22.519zM33.185 4.741h2.37v22.519h-2.37v-22.519z"/> </symbol><symbol id="amp-websites" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <defs> <linearGradient id="gradient-websites" x1="81.8129399%" x2="33.8766928%" y1="0%" y2="94.4849088%"> <stop offset="0%" stop-color="#00DCC0"/> <stop offset="100%" stop-color="#005AF0"/> </linearGradient> </defs> <path d="M63.196 4.646h-62.253c-0.566 0-0.943 0.377-0.943 0.755v53.010c0 0.566 0.377 0.943 0.943 0.943h62.253c0.566 0 0.755-0.377 0.755-0.755v-53.198c0.189-0.377-0.189-0.755-0.755-0.755zM3.395 18.040h57.348v33.202h-57.348v-33.202zM60.744 7.853v6.98h-57.348v-6.98h57.348zM3.395 56.147v-1.509h57.348v1.509h-57.348zM9.055 7.853c1.132 0 1.886 0.754 1.886 1.886s-0.755 1.886-1.886 1.886-1.886-0.755-1.886-1.886 0.943-1.886 1.886-1.886zM12.828 7.853c1.132 0 1.886 0.754 1.886 1.886s-0.755 1.886-1.886 1.886-1.886-0.755-1.886-1.886 0.943-1.886 1.886-1.886zM18.487 7.853c1.132 0 1.886 0.754 1.886 1.886s-0.755 1.886-1.886 1.886-1.886-0.755-1.886-1.886 0.943-1.886 1.886-1.886zM51.123 39.734l-11.13-13.96c-0.189-0.189-0.377-0.377-0.755-0.377v0c-0.189 0-0.566 0-0.755 0.377l-8.3 9.621-4.716-6.225c-0.189-0.189-0.377-0.377-0.755-0.377s-0.566 0-0.755 0.377l-8.866 10.376c-0.377 0.377-0.189 0.943 0 1.132s0.377 0.189 0.566 0.189c0.189 0 0.566 0 0.754-0.377l8.3-9.621 4.528 5.471-2.452 3.018c-0.377 0.377-0.189 0.943 0 1.132 0.377 0.189 0.943 0.189 1.132 0l11.319-13.017 10.376 13.205c0.189 0.189 0.377 0.377 0.755 0.377 0.189 0 0.377 0 0.566-0.189 0.377-0.377 0.566-0.943 0.189-1.132zM27.165 26.718c1.509 0 2.641-1.132 2.641-2.641 0-1.321-1.132-2.641-2.641-2.641s-2.641 1.132-2.641 2.641c0 1.509 1.132 2.641 2.641 2.641zM27.165 23.322c0.566 0 0.943 0.377 0.943 0.943s-0.377 0.943-0.943 0.943-0.943-0.377-0.943-0.943c0-0.566 0.377-0.943 0.943-0.943z"/> </symbol><symbol id="angle-down-solid" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> <path d="M56.293 16.003c1.761-1.645 4.553-1.645 6.314 0 1.857 1.734 1.857 4.623 0 6.357l-27.45 25.638c-1.761 1.645-4.553 1.645-6.314 0l-27.45-25.638c-0.899-0.839-1.393-1.963-1.393-3.178s0.494-2.339 1.393-3.178c1.761-1.645 4.553-1.645 6.314 0l24.293 22.689 24.293-22.689z"/> </symbol><symbol id="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><g fill="none" fill-rule="evenodd"><path fill="#FFF" d="M0 15c0 8.284 6.716 15 15 15 8.285 0 15-6.716 15-15 0-8.284-6.715-15-15-15C6.716 0 0 6.716 0 15z"/><path fill="#005AF0" fill-rule="nonzero" d="M13.85 24.098h-1.14l1.128-6.823-3.49.005h-.05a.57.57 0 0 1-.568-.569c0-.135.125-.363.125-.363l6.272-10.46 1.16.005-1.156 6.834 3.508-.004h.056c.314 0 .569.254.569.568 0 .128-.05.24-.121.335L13.85 24.098zM15 0C6.716 0 0 6.716 0 15c0 8.284 6.716 15 15 15 8.285 0 15-6.716 15-15 0-8.284-6.715-15-15-15z"/></g></symbol><symbol id="orientation-toggle" viewBox="0 0 64 64"> <path d="M62.149 0h-30.149c-1.058 0-1.851 0.793-1.851 1.851v22.215c0 1.058 0.793 1.851 1.851 1.851s1.851-0.793 1.851-1.851v-20.364h26.446v42.843h-4.231c-1.058 0-1.851 0.793-1.851 1.851s0.793 1.851 1.851 1.851h6.083c1.058 0 1.851-0.793 1.851-1.851v-46.545c0-0.793-0.793-1.851-1.851-1.851z"/> <path d="M48.132 30.413h-46.281c-1.058 0-1.851 0.793-1.851 1.851v29.884c0 1.058 0.793 1.851 1.851 1.851h46.281c1.058 0 1.851-0.793 1.851-1.851v-29.884c0-1.058-0.793-1.851-1.851-1.851zM46.281 60.297h-42.578v-26.182h42.578v26.182z"/> <path d="M4.76 25.124c1.058 0 1.851-0.793 1.851-1.851 0-6.612 5.289-11.901 11.901-11.901h1.058l-0.529 0.529c-0.793 0.793-0.793 1.851 0 2.645 0.264 0.264 0.793 0.529 1.322 0.529s1.058-0.264 1.322-0.529l3.703-3.703c0.793-0.793 0.793-1.851 0-2.645l-3.703-3.703c-0.793-0.793-1.851-0.793-2.645 0s-0.793 1.851 0 2.645l0.529 0.529h-1.058c-8.727 0-15.603 7.141-15.603 15.603 0 1.058 0.793 1.851 1.851 1.851z"/> </symbol><symbol id="reload" viewBox="0 0 64 64"> <path d="M58.303 24.441c-4.535-10.583-14.614-17.386-25.953-17.638l2.772-2.772c1.008-1.008 1.008-2.268 0-3.276s-2.268-1.008-3.276 0l-7.055 7.307c-1.008 1.008-1.008 2.268 0 3.276l7.055 7.055c0.504 0.504 1.008 0.756 1.512 0.756s1.26-0.252 1.512-0.756c1.008-1.008 1.008-2.268 0-3.276l-3.779-3.78c9.827-0.252 18.898 5.543 22.929 14.614 4.535 10.583 0.756 22.929-9.071 29.48-9.575 6.299-22.425 4.787-30.488-3.528s-8.819-21.165-2.016-30.488c0.756-1.008 0.504-2.52-0.504-3.276s-2.52-0.504-3.024 0.504c-8.063 11.087-7.055 26.457 2.52 36.535 5.543 5.795 13.102 8.819 20.661 8.819 5.291 0 10.835-1.512 15.622-4.787 11.339-7.559 15.874-22.173 10.583-34.772z"/> </symbol> </defs> </svg> <header class="ap--header " [class]="'ap--header ' + (mainmenuopen ? 'mainmenuopen' : '')" i-amphtml-binding> <div class="ap-o-header"> <a class="ap-o-header-home" href="/"> <svg class="ap-o-header-home-logo"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#logo"/></svg> <span class="ap-o-header-home-title">AMP</span> </a> <nav class="ap-o-header-main"> <div class="ap-o-header-main-item"> <button class="ap-o-header-main-link -tw "> About <div class="ap-a-ico ap-o-header-main-link-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </div> </button> <ul class="ap-o-header-flyout"> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link websites" href="/about/websites/"> <div class="ap-o-header-flyout-primary-item-link-icon websites"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#amp-websites"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info ap-o-header-flyout-primary-item-link-info-websites"> <div class="ap-o-header-flyout-item-title">AMP Websites</div> <div class="ap-o-header-flyout-item-description">Create flawless web experiences</div> </div> </a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link stories" href="/about/stories/"> <div class="ap-o-header-flyout-primary-item-link-icon stories"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#amp-stories"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info ap-o-header-flyout-primary-item-link-info-stories"> <div class="ap-o-header-flyout-item-title">Web Stories</div> <div class="ap-o-header-flyout-item-description">Snackable Stories for everyone</div> </div> </a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link ads" href="/about/ads/"> <div class="ap-o-header-flyout-primary-item-link-icon ads"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#amp-ads"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info ap-o-header-flyout-primary-item-link-info-ads"> <div class="ap-o-header-flyout-item-title">AMP Ads</div> <div class="ap-o-header-flyout-item-description">Super fast ads on the web</div> </div> </a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link email" href="/about/email/"> <div class="ap-o-header-flyout-primary-item-link-icon email"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#amp-email"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info ap-o-header-flyout-primary-item-link-info-email"> <div class="ap-o-header-flyout-item-title">AMP Email</div> <div class="ap-o-header-flyout-item-description">Next gen email</div> </div> </a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/about/how-amp-works/">How AMP works</a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/about/mission-and-vision/">Vision & Mission</a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/about/use-cases/">Use cases</a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/success-stories/">Success Stories</a> </li> </ul> </div> <div class="ap-o-header-main-item"> <button class="ap-o-header-main-link -tw active"> Documentation <div class="ap-a-ico ap-o-header-main-link-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </div> </button> <ul class="ap-o-header-flyout"> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/documentation/">Get Started</a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link " href="/documentation/guides-and-tutorials/"> <div class="ap-o-header-flyout-primary-item-link-icon "> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#guides-documents"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info"> <div class="ap-o-header-flyout-item-title">Guides & Tutorials</div> <div class="ap-o-header-flyout-item-description">Get started with AMP</div> </div> </a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link " href="/documentation/components/"> <div class="ap-o-header-flyout-primary-item-link-icon "> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#components-flyout"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info"> <div class="ap-o-header-flyout-item-title">Components</div> <div class="ap-o-header-flyout-item-description">The complete AMP library</div> </div> </a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link " href="/documentation/examples/"> <div class="ap-o-header-flyout-primary-item-link-icon "> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#examples-flyout"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info"> <div class="ap-o-header-flyout-item-title">Examples</div> <div class="ap-o-header-flyout-item-description">Hands-on introduction to AMP</div> </div> </a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link " href="/documentation/courses/"> <div class="ap-o-header-flyout-primary-item-link-icon "> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#learn"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info"> <div class="ap-o-header-flyout-item-title">Courses</div> <div class="ap-o-header-flyout-item-description">Learn AMP with free courses</div> </div> </a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link " href="/documentation/templates/"> <div class="ap-o-header-flyout-primary-item-link-icon "> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#template"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info"> <div class="ap-o-header-flyout-item-title">Templates</div> <div class="ap-o-header-flyout-item-description">Ready to use</div> </div> </a> </li> <li class="ap-o-header-flyout-primary-item"> <a class="ap-o-header-flyout-primary-item-link " href="/documentation/tools/"> <div class="ap-o-header-flyout-primary-item-link-icon "> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#wrench"/></svg> </div> <div class="ap-o-header-flyout-primary-item-link-info"> <div class="ap-o-header-flyout-item-title">Tools</div> <div class="ap-o-header-flyout-item-description">Begin building</div> </div> </a> </li> </ul> </div> <div class="ap-o-header-main-item"> <button class="ap-o-header-main-link -tw "> Community <div class="ap-a-ico ap-o-header-main-link-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </div> </button> <ul class="ap-o-header-flyout"> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/documentation/guides-and-tutorials/contribute/">Contribute</a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/community/roadmap/">Roadmap</a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/community/governance/">Governance</a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/community/working-groups/access-subscriptions/">Working Groups</a> </li> </ul> </div> <div class="ap-o-header-main-item"> <button class="ap-o-header-main-link -tw "> Events <div class="ap-a-ico ap-o-header-main-link-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </div> </button> <ul class="ap-o-header-flyout"> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/events/amp-fest-2020/">AMP Fest 2020</a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/events/amp-roadshow/">AMP Roadshow</a> </li> </ul> </div> <div class="ap-o-header-main-item"> <a class="ap-o-header-main-link -tw" href="https://blog.amp.dev">Blog</a> </div> <div class="ap-o-header-main-item"> <button class="ap-o-header-main-link -tw "> Support <div class="ap-a-ico ap-o-header-main-link-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </div> </button> <ul class="ap-o-header-flyout"> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/support/">Help</a> </li> <li class="ap-o-header-flyout-item-secondary"> <a class="ap-o-header-flyout-item-title secondary" href="/support/faq/">FAQ</a> </li> </ul> </div> </nav> <div class="-tv"> <span class="-tm" aria-label="Select a language" tabindex="-1"> <span class="-tw">EN</span> <div class="ap-a-ico -ty"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </div> </span> <input class="-tg" type="checkbox" name="language-selector"> <div class="-tb" role="list"> <a class="-tw" href="/de/documentation/components/amp-bind/" role="listitem">Deutsch</a> <a class="-tw" href="/fr/documentation/components/amp-bind/" role="listitem">Français</a> <a class="-tw" href="/ar/documentation/components/amp-bind/" role="listitem">العربية</a> <a class="-tw" href="/es/documentation/components/amp-bind/" role="listitem">Español</a> <a class="-tw" href="/it/documentation/components/amp-bind/" role="listitem">Italiano</a> <a class="-tw" href="/id/documentation/components/amp-bind/" role="listitem">Indonesia</a> <a class="-tw" href="/ja/documentation/components/amp-bind/" role="listitem">日本語</a> <a class="-tw" href="/ko/documentation/components/amp-bind/" role="listitem">한국어</a> <a class="-tw" href="/pt_br/documentation/components/amp-bind/" role="listitem">Português</a> <a class="-tw" href="/ru/documentation/components/amp-bind/" role="listitem">Русский</a> <a class="-tw" href="/tr/documentation/components/amp-bind/" role="listitem">Türkçe</a> <a class="-tw" href="/zh_cn/documentation/components/amp-bind/" role="listitem">中文</a> <a class="-tw" href="/pl/documentation/components/amp-bind/" role="listitem">Polski</a> <a class="-tw" href="/vi/documentation/components/amp-bind/" role="listitem">Tiếng việt</a> </div> </div> </div> </header> <label class="ap-o-burger-menu-label" on="tap:AMP.setState({mainmenuopen: !mainmenuopen, noScrollState: !noScrollState})" [class]="'ap-o-burger-menu-label ' + (mainmenuopen ? 'mainmenuopen ' : '')" for="burger-menu" tabindex="0" role="button" aria-label="Burger Menu" i-amphtml-binding> <div class="ap-a-ico ap-o-burger-menu-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu"/></svg> </div> </label> <nav class="ap-o-burger-menu" [class]="mainmenuopen ? 'ap-o-burger-menu mainmenuopen' : 'ap-o-burger-menu'" i-amphtml-binding> <ul class="-th"> <li class="-tp"> <label class="ap-o-burger-menu-link -tw "> About </label> <input class="-td" type="checkbox" aria-label="About"> <span class="nav-icon"> <svg class="ap-a-ico"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </span> <ul class="-th"> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/about/websites/"> AMP Websites </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/about/stories/"> Web Stories </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/about/ads/"> AMP Ads </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/about/email/"> AMP Email </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/about/how-amp-works/"> How AMP works </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/about/mission-and-vision/"> Vision & Mission </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/about/use-cases/"> Use cases </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/success-stories/"> Success Stories </a> </li> </ul> </li> <li class="-tp"> <label class="ap-o-burger-menu-link -tw active"> Documentation </label> <input class="-td" type="checkbox" aria-label="Documentation" checked> <span class="nav-icon"> <svg class="ap-a-ico"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </span> <ul class="-th"> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/documentation/"> Get Started </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/documentation/guides-and-tutorials/"> Guides & Tutorials </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/documentation/components/"> Components </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/documentation/examples/"> Examples </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/documentation/courses/"> Courses </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/documentation/templates/"> Templates </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/documentation/tools/"> Tools </a> </li> </ul> </li> <li class="-tp"> <label class="ap-o-burger-menu-link -tw "> Community </label> <input class="-td" type="checkbox" aria-label="Community"> <span class="nav-icon"> <svg class="ap-a-ico"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </span> <ul class="-th"> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/documentation/guides-and-tutorials/contribute/"> Contribute </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/community/roadmap/"> Roadmap </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/community/governance/"> Governance </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/community/working-groups/access-subscriptions/"> Working Groups </a> </li> </ul> </li> <li class="-tp"> <label class="ap-o-burger-menu-link -tw "> Events </label> <input class="-td" type="checkbox" aria-label="Events"> <span class="nav-icon"> <svg class="ap-a-ico"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </span> <ul class="-th"> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/events/amp-fest-2020/"> AMP Fest 2020 </a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tx" href="/events/amp-roadshow/"> AMP Roadshow </a> </li> </ul> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tw" href="https://blog.amp.dev">Blog</a> </li> <li class="-tp"> <a class="ap-o-burger-menu-link -tw " href="/support/"> Help </a> </li> </ul> </nav> <div class="-oc"> <amp-position-observer on="enter:slideTransition.start; exit:slideTransition.start,slideTransition.reverse" intersection-ratios="1" layout="nodisplay" class="i-amphtml-layout-nodisplay" hidden="hidden" i-amphtml-layout="nodisplay"> </amp-position-observer> <amp-animation id="slideTransition" layout="nodisplay" class="i-amphtml-layout-nodisplay" hidden="hidden" i-amphtml-layout="nodisplay"> <script type="application/json">{"duration":"150ms","fill":"both","easing":"ease-out","iterations":"1","animations":[{"selector":".label-title","keyframes":[{"transform":"scale3d(0, 1, 1)"},{"transform":"scale3d(1, 1, 1)"}]}]}</script> </amp-animation> </div> <amp-user-notification class="-fv i-amphtml-layout-nodisplay" id="format-filter-hint" layout="nodisplay" hidden="hidden" i-amphtml-layout="nodisplay"> </amp-user-notification> <div class="-fd" aria-hidden="true"> <div class="-fm"> <div class="-fg">Select your format for a more streamlined experience</div> <button class="-fy" on="tap:format-filter-hint.dismiss"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#close"/></svg> </button> </div> </div> <main class="ap--main -fb"> <div class="-tf"> <input class="-od ap-a-sidebar-mobile-toggle-input-sidebar" type="checkbox" name="sidebar" id="sidebar" autocomplete="off"> <input class="-om ap-a-sidebar-desktop-toggle-input-sidebar" type="checkbox" name="sidebar-desktop" id="sidebar-desktop" autocomplete="off"> <span id="ap--sidebar-content" class="-oy"></span> <section class="ap--toc"> <div class="ap-o-toc" [class]="contentmenuopen ? 'ap-o-toc contentmenuopen' : 'ap-o-toc'" i-amphtml-binding> <label class="ap-o-toc-toggle" for="toc" on="tap:AMP.setState({contentmenuopen: !contentmenuopen})" role="contentmenutrigger" tabindex="0"> <span class="ap-o-toc-hl">Table of contents</span> <span class="nav-icon"> <svg class="ap-a-ico"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </span> </label> <input class="-oh -of" type="checkbox" name="toc" id="toc" autocomplete="off"> <ul><li><a href="#usage">Usage</a><ul> <li><a href="#example-without-declared-state">Example without declared state</a></li> <li><a href="#example-with-declared-state">Example with declared state</a></li> <li><a href="#<amp-state>-specification"><amp-state> specification</a></li> </ul> </li> <li><a href="#attributes">Attributes</a><ul> <li><a href="#src-(optional)">src (optional)</a></li> <li><a href="#credentials-(optional)">credentials (optional)</a></li> </ul> </li> <li><a href="#actions">Actions</a><ul> <li><a href="#refresh">refresh</a></li> </ul> </li> <li><a href="#state">State</a><ul> <li><a href="#size">Size</a></li> <li><a href="#defining-and-initializing-state-with-<amp-state>">Defining and initializing state with <amp-state></a></li> <li><a href="#updating-state-variables-with-amp.setstate()">Updating state variables with AMP.setState()</a><ul> <li><a href="#event-triggering-and-data">Event triggering and data</a></li> <li><a href="#updating-nested-variables">Updating nested variables</a></li> <li><a href="#circular-references">Circular references</a></li> <li><a href="#removing-a-variable">Removing a variable</a></li> <li><a href="#deep-merge-with-amp.setstate()">Deep-merge with AMP.setState()</a></li> </ul> </li> <li><a href="#modifying-history-with-amp.pushstate()">Modifying history with AMP.pushState()</a></li> </ul> </li> <li><a href="#expressions">Expressions</a><ul> <li><a href="#differences-from-javascript">Differences from JavaScript</a></li> <li><a href="#allowlisted-functions">Allowlisted functions</a><ul> <li><a href="#array">Array</a></li> <li><a href="#number">Number</a></li> <li><a href="#string">String</a></li> <li><a href="#math">Math</a></li> <li><a href="#object">Object</a></li> <li><a href="#global">Global</a></li> </ul> </li> <li><a href="#defining-macros-with-amp-bind-macro">Defining macros with amp-bind-macro</a></li> </ul> </li> <li><a href="#bindings">Bindings</a><ul> <li><a href="#react-and-xml-compatibility">React and XML compatibility</a></li> <li><a href="#binding-types">Binding types</a></li> <li><a href="#amp-component-specific-attributes">AMP component specific attributes</a></li> <li><a href="#html-attributes">HTML attributes</a></li> <li><a href="#disallowed-bindings">Disallowed bindings</a></li> </ul> </li> <li><a href="#debugging">Debugging</a><ul> <li><a href="#warnings">Warnings</a></li> <li><a href="#errors">Errors</a></li> <li><a href="#debugging-state">Debugging State</a></li> <li><a href="#expression-grammar">Expression grammar</a></li> </ul> </li></ul> </div> </section> <section class="-t"> <label class="-op -ol ap-a-sidebar-mobile-toggle-label-sidebar" for="sidebar" on="tap:sidebar-left.toggle" role="categoriemenutrigger" tabindex="0"> <span class="label-icon"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sidebar-toggle"/></svg></span> <span class="label-title">Toggle Sidebar</span> </label> <label class="-op -og ap-a-sidebar-desktop-toggle-label-sidebar" for="sidebar-desktop" role="categoriemenutrigger-desktop" tabindex="0"> <span class="label-icon"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sidebar-toggle"/></svg></span> <span class="label-title">Toggle Sidebar</span> </label> <nav class="-ou"> <a class="ap-m-breadcrumbs-crumb" href="/documentation/">Documentation</a> <span class="ap-m-breadcrumbs-divider"> <svg class="ap-a-ico -oa"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </span> <a class="ap-m-breadcrumbs-crumb" href="/documentation/components/">Components</a> </nav> <h1> amp-bind </h1> <div class="ap-o-component-intro"> <div class="ap-o-component-intro-row"> <h4 class="ap-o-component-intro-headline">Description</h4> <p class="ap-o-component-intro-text">Allows elements to mutate in response to user actions or data changes via data binding and simple JS-like expressions.</p> </div> <div class="ap-o-component-intro-row ap-o-component-intro-row-inline"> <h4 class="ap-o-component-intro-headline">Required Scripts</h4> <div id="amp-script" class="ap-a-copy-script"> <pre><script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script></pre> <amp-iframe width="24" height="24" layout="fixed" sandbox="allow-scripts" src="https://amp.dev/shared/copy-script/#%3Cscript%20async%20custom-element%3D%22amp-bind%22%20src%3D%22https%3A//cdn.ampproject.org/v0/amp-bind-0.1.js%22%3E%3C/script%3E" class="i-amphtml-layout-fixed i-amphtml-layout-size-defined" style="width:24px;height:24px;" i-amphtml-layout="fixed"> <div placeholder></div> </amp-iframe> </div> </div> <div class="ap-o-component-intro-row"> <div id="examples" class="ap-m-clip"> <h4 class="ap-o-component-intro-headline">Examples</h4> <div class="ap-o-component-intro-list"> <a class='ap-o-component-intro-list-item' href='/documentation/examples/e-commerce/amp_for_e-commerce_getting_started/'>AMP for E-Commerce Getting Started</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/e-commerce/product_browse_page/'>Product Browse Page</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/e-commerce/product_page/'>Product Page</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-autocomplete/'>amp-autocomplete</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-bind-macro/'>amp-bind-macro</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-bind-recaptcha/'>amp-bind-recaptcha</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-bind/'>amp-bind</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-date-picker/'>amp-date-picker</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-geo/'>amp-geo</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-iframe/'>amp-iframe</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-img/'>amp-img</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-lightbox/'>amp-lightbox</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-list/'>amp-list</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-selector/'>amp-selector</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/client-side_filtering/'>Client-side filtering</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/conditional_state/'>Conditional State</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/copy_button/'>Copy Button</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/currency_conversion/'>Currency Conversion</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/dynamic_accordion/'>Dynamic Accordion</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/dynamic_content_after_user-interaction/'>Dynamic Content After User-Interaction</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/linked_dropdowns/'>Linked Dropdowns</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/multi_page_flow/'>Multi Page Flow</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/restrict_duplicate_selection/'>Restrict Duplicate Selection</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/show_more_button/'>Show More Button</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/tic_tac_toe/'>Tic-Tac-Toe</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/multimedia-animations/image_galleries_with_amp-carousel/'>Image Galleries with amp-carousel</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/visual-effects/animated_snackbar/'>Animated Snackbar</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/e-commerce/checkout_flow/'>Checkout Flow</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/e-commerce/hotel/'>Hotel</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/e-commerce/shopping_cart/'>Shopping Cart</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/components/amp-analytics/'>amp-analytics</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/favorite_button/'>Favorite Button</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/paged_list/'>Paged List</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/seatmap/'>SeatMap</a> <a class='ap-o-component-intro-list-item' href='/documentation/examples/interactivity-dynamic-content/seatmap_multiple_selection/'>SeatMap Multiple Selection</a> </div> <button id="examples-expand" class="ap-m-clip-expand" on="tap:examples.toggleClass(class='expanded', force=true),examples-expand.hide()"> <svg class="ap-m-clip-expand-icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </button> </div> </div> </div> <h2 id="usage">Usage</h2> <p>The <code>amp-bind</code> component enables custom stateful interactivity on AMP pages.</p> <p>For performance, and to avoid the risk of unexpected content jumping, <code>amp-bind</code> does not evaluate expressions on page load. This means visual elements should be given a default state and not rely on <code>amp-bind</code> for initial render.</p> <figure class="alignment-wrapper margin-"> <amp-youtube data-videoid="xzCFU8b5fCU" layout="responsive" width="480" height="270" class="i-amphtml-layout-responsive i-amphtml-layout-size-defined" i-amphtml-layout="responsive"><i-amphtml-sizer slot="i-amphtml-svc" style="display:block;padding-top:56.25%"></i-amphtml-sizer></amp-youtube> <figcaption>Watch this video for an introduction to amp-bind.</figcaption></figure> <p><code>amp-bind</code> has three main concepts:</p> <ol> <li><a href="#state">State</a>: A document-scope, mutable JSON state. State variables update in response to user actions. <code>amp-bind</code> does not evaluate expressions on page load. Visual elements should have their default "state" defined and not rely <code>amp-bind</code> for initial render.</li> <li><a href="#expressions">Expressions</a>: JavaScript-like expressions that can reference the <strong>state</strong>.</li> <li><a href="#bindings">Bindings</a>: Special attributes that link an element's property to a <strong>state</strong> via an <strong>expression</strong>. A property is bound by wrapping it inside brackets, in the form of <code>[property]</code>.</li> </ol> <h3 id="example-without-declared-state">Example without declared state</h3><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <p [text]="'Hello ' + foo" i-amphtml-binding>Hello World</p> <button on="tap:AMP.setState({foo: 'Interactivity'})"> Say "Hello Interactivity" </button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'Hello ' + foo"</span><span class="p">></span>Hello World<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({foo: 'Interactivity'})"</span><span class="p">></span> Say "Hello Interactivity" <span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.1.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p>In the example above:</p> <ul> <li>The <strong>state</strong> begins as empty.</li> <li>It has a single <strong>binding</strong> to <code>[text]</code>, the text content of a node, on the <code><p></code> element.</li> <li>The <code>[text]</code> value contains the <strong>expression</strong>, <code>'Hello ' + foo</code>. This expression concatenates the string 'Hello ' and the value of the <strong>state variable</strong> foo.</li> </ul> <p>When the user taps/clicks the button:</p> <ol> <li>It triggers the <code>tap</code> event.</li> <li>The <code>tap</code> event invokes the <code>AMP.setState()</code> method.</li> <li>The <code>AMP.setState()</code> methods sets the <code>foo</code> <strong>state variable</strong> to the value of <code>Interactivity</code>.</li> <li>The state is no longer empty, so the page updates the bound property to its state.</li> </ol> <p> </p><div class="ap-m-tip"> <div class="ap-a-ico ap-m-tip-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#speech-bubble"/></svg> </div> <div class="ap-m-tip-content"> Calling <code>AMP.setState()</code> in some examples may set or change states of other examples on page. Refresh this page to see examples before <code>AMP.setState()</code>. </div> </div><p></p> <h3 id="example-with-declared-state">Example with declared state</h3> <p> </p><div class="ap-code-preview top-frame"> <amp-state id="orientation2" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">true</script> </amp-state> <amp-state id="dimension2" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">{"width":533,"height":300}</script> </amp-state> <amp-state id="example2" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">"https://preview.amp.dev/documentation/components/amp-bind.example.2.html"</script> </amp-state> <div class="ap-code-preview-top-preview ap-code-preview-top-preview-2"> <div class="ap-code-preview-controls"> <button [hidden]="!orientation2" class="ap-code-preview-controls-button" on="tap: AMP.setState({ orientation2: true, dimension2: { width: dimension2.height, height: dimension2.width, } })" i-amphtml-binding> <div class="ap-a-ico ap-code-preview-controls-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#orientation-toggle"/></svg> </div> </button> <button class="ap-code-preview-controls-button" on="tap:AMP.setState({'example2': 'https://preview.amp.dev/documentation/components/amp-bind.example.2.html?' + random()})"> <div class="ap-a-ico ap-code-preview-controls-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#reload"/></svg> </div> </button> </div> <amp-iframe id="iframeContainer2" class="ap-code-preview-iframe i-amphtml-layout-intrinsic i-amphtml-layout-size-defined" src="https://preview.amp.dev/documentation/components/amp-bind.example.2.html" layout="intrinsic" width="533" [width]="dimension2.width" height="300" [height]="dimension2.height" [src]="example2" sandbox="allow-scripts allow-popups allow-same-origin" frameborder="0" i-amphtml-binding i-amphtml-layout="intrinsic"><i-amphtml-sizer slot="i-amphtml-svc" class="i-amphtml-sizer"><img alt aria-hidden="true" class="i-amphtml-intrinsic-sizer" role="presentation" src="data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgd2lkdGg9IjUzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4="></i-amphtml-sizer> <div placeholder></div> </amp-iframe> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">head</span><span class="p">></span> <span class="p"><</span><span class="nt">style</span> <span class="na">amp-custom</span><span class="p">></span> <span class="p">.</span><span class="nc">greenBorder</span> <span class="p">{</span> <span class="k">border</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span> <span class="kc">solid</span> <span class="kc">green</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">redBorder</span> <span class="p">{</span> <span class="k">border</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span> <span class="kc">solid</span> <span class="kc">red</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">defaultBorder</span> <span class="p">{</span> <span class="k">border</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span> <span class="kc">solid</span> <span class="kc">transparent</span><span class="p">;</span> <span class="p">}</span> <span class="p"></</span><span class="nt">style</span><span class="p">></span> <span class="p"></</span><span class="nt">head</span><span class="p">></span> <span class="p"><</span><span class="nt">body</span><span class="p">></span> <span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"theFood"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span> <span class="s2">"cupcakes"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"imageUrl"</span><span class="o">:</span> <span class="s2">"https://amp.dev/static/samples/img/image2.jpg"</span><span class="p">,</span> <span class="s2">"style"</span><span class="o">:</span> <span class="s2">"greenBorder"</span> <span class="p">},</span> <span class="s2">"sushi"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"imageUrl"</span><span class="o">:</span> <span class="s2">"https://amp.dev/static/samples/img/image3.jpg"</span><span class="p">,</span> <span class="s2">"style"</span><span class="o">:</span> <span class="s2">"redBorder"</span> <span class="p">}</span> <span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"defaultBorder"</span> <span class="na">[class]</span><span class="o">=</span><span class="s">"theFood[currentMeal].style || 'defaultBorder'"</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span><span class="p">></span>Each food has a different border color.<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'I want to eat ' + currentMeal + '.'"</span><span class="p">></span>I want to eat cupcakes.<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">amp-img</span> <span class="na">width</span><span class="o">=</span><span class="s">"300"</span> <span class="na">height</span><span class="o">=</span><span class="s">"200"</span> <span class="na">src</span><span class="o">=</span><span class="s">"https://amp.dev/static/samples/img/image2.jpg"</span> <span class="na">[src]</span><span class="o">=</span><span class="s">"theFood[currentMeal].imageUrl"</span> <span class="p">></span> <span class="p"></</span><span class="nt">amp-img</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({currentMeal: 'sushi'})"</span><span class="p">></span>Set to sushi<span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({currentMeal: 'cupcakes'})"</span><span class="p">></span> Set to cupcakes <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p"></</span><span class="nt">body</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.2.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p>In the example above:</p> <ul> <li>The <code><amp-state></code> component declares state using JSON. The <code><amp-state></code> element has an <code>id</code> of <code>theFood</code> to allow us to reference the defined data. But because <code><amp-bind></code> does not evaluate <code><amp-state></code> on page load, the <strong>state</strong> is empty.</li> <li>The page loads with visual defaults.<ul> <li>The <code><div></code> element has <code>class="greenBorder"</code> defined.</li> <li>The second <code><p></code> element has "I want cupcakes." defined within the tags.</li> <li>The <code><amp-img></code> <code>src</code> points to a url.</li> </ul> </li> <li>Changeable elements have <strong>bindings</strong> that point to <strong>expressions</strong>.<ul> <li>The <code>[class]</code> attribute on the <code><div></code> is bound to the <code>theFood[currentMeal].style</code> <strong>expression</strong>.</li> <li>The <code>[text]</code> attribute on the second <code><p></code> is bound to the <code>'I want to eat ' + currentMeal + '.'</code> <strong>expression</strong>.</li> <li>The <code>[src]</code> attribute is bound to the <code>theFood[currentMeal].imageUrl</code> <strong>expression</strong>.</li> </ul> </li> </ul> <p>If a user clicks the "Set to sushi" button:</p> <ol> <li>The <code>tap</code> event trigger the <code>AMP.setState</code> action.</li> <li>The setState action turns <code>currentMeal</code> into a state and sets it to <code>sushi</code>.</li> <li>AMP evaluates <strong>bindings</strong> with <strong>expressions</strong> that contain the state <code>currentMeal</code>.</li> <li><code>[class]="theFood[currentMeal].style"</code> updates <code>class</code> to <code>redBorder</code>.</li> <li><code>[text]="'I want to eat ' + currentMeal + '.'"</code> updates the inner text of the second <code><p></code> element to "I want to eat sushi".</li> <li><code>[src]="theFood[currentMeal].imageUrl</code> updates the <code>src</code> of <code><amp-img></code> to <code>https://amp.dev/static/samples/img/image3.jpg</code></li> </ol> <p>Using <code>[class]="theFood[currentMeal].style"</code> as an example of <strong>expression</strong> syntax evaluation:</p> <ul> <li><code>[class]</code> is the property to update.</li> <li><code>theFood</code> is the id of the <code><amp-state></code> component.</li> <li><code>currentMeal</code> is the state name. In the case of <code>theFood</code> it will be <code>cupcakes</code> or <code>sushi</code>.</li> <li><code>style</code> is the <strong>state variable</strong>. It corresponds to the matching JSON key, and sets the bound property to that key's value.</li> </ul> <p> </p> <p> </p> <h3 id="<amp-state>-specification"><code><amp-state></code> specification</h3> <p> </p> <p>An <code>amp-state</code> element may contain either a child <code><script></code> element <strong>OR</strong> a <code>src</code> attribute containing a CORS URL to a remote JSON endpoint, but not both.</p> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myLocalState"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span> <span class="s2">"foo"</span><span class="o">:</span> <span class="s2">"bar"</span> <span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myRemoteState"</span> <span class="na">src</span><span class="o">=</span><span class="s">"https://data.com/articles.json"</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> </pre></div> <p>As an <code>amp-state</code> element stores a JSON object literal, you can also initialize it with an object, as above, or with a constant.</p> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"singleton"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="s1">'I am a string'</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> </pre></div> <p> </p> <p> </p> <p> </p> <h2 id="attributes">Attributes</h2> <h3 id="src-(optional)"><code>src</code> (optional)</h3> <p>The URL of the remote endpoint that must return JSON, which is used to this <code>amp-state</code>. This must be a HTTP service with a proper CORS configuration for the page. The <code>src</code> attribute allows all standard URL variable substitutions. See the <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-bind/../../docs/spec/amp-var-substitutions.md">Substitutions Guide</a> for more info.</p> <p>AMP batches XMLHttpRequests (XHRs) to JSON endpoints, that is, you can use a single JSON data request as a data source for multiple consumers (e.g., multiple <code>amp-state</code> elements) on an AMP page.</p> <p>For example, if your <code>amp-state</code> element makes an XHR to an endpoint, while the XHR is in flight, all subsequent XHRs to the same endpoint won't trigger and will instead return the results from the first XHR.</p> <p> </p><div class="ap-m-tip"> <div class="ap-a-ico ap-m-tip-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#warning-sign"/></svg> </div> <div class="ap-m-tip-content"> The endpoint must implement the requirements specified in the <a href="https://amp.dev/documentation/guides-and-tutorials/learn/amp-caches-and-cors/amp-cors-requests">CORS Requests in AMP</a> spec. </div> </div><p></p> <h3 id="credentials-(optional)"><code>credentials</code> (optional)</h3> <p>Defines a <code>credentials</code> option as specified by the <a href="https://fetch.spec.whatwg.org/">Fetch API</a>.</p> <ul> <li>Supported values: <code>omit</code>, <code>include</code></li> <li>Default: <code>omit</code></li> </ul> <p>To send credentials, pass the value of <code>include</code>. If this value is set, the response must follow the <a href="https://amp.dev/documentation/guides-and-tutorials/learn/amp-caches-and-cors/amp-cors-requests/#cors-security-in-amp">AMP CORS security guidelines</a>.</p> <h2 id="actions">Actions</h2> <h3 id="refresh"><code>refresh</code></h3> <p>The <code>refresh</code> action refetches data from data point the <code>src</code> attribute points to. This action will make a network request bypassing the browser's caching mechanisms.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-state id="currentTime" src="/documentation/examples/api/time" class="i-amphtml-layout-container" i-amphtml-layout="container"></amp-state> <button on="tap:currentTime.refresh"> Refresh </button> <div [text]="currentTime.time" i-amphtml-binding></div> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"currentTime"</span> <span class="na">src</span><span class="o">=</span><span class="s">"/documentation/examples/api/time"</span><span class="p">></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:currentTime.refresh"</span><span class="p">></span> Refresh <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"currentTime.time"</span><span class="p">></</span><span class="nt">div</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.4.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p>We recommend <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-bind/../amp-script/amp-script.md"><code>amp-script</code></a> for most use cases working with live content. In a subset of cases, <code>refresh</code> with <code>amp-bind</code> will work.</p> <p> </p> <h2 id="state">State</h2> <p>Each AMP document that uses <code>amp-bind</code> has document-scope mutable JSON data, or <strong>state</strong>.</p> <h3 id="size">Size</h3> <p>An <code><amp-state></code> element's JSON data has a maximum size of 100KB.</p> <h3 id="defining-and-initializing-state-with-<amp-state>">Defining and initializing state with <code><amp-state></code></h3> <p>Expressions are not evaluated on page load, but you may define an initial state. The <code><amp-state></code> component contains different <strong>states</strong> and their <strong>state variables</strong>. While this defines a <strong>state</strong>, it will not reflect on the page until after a user interacts.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-state id="myDefinedState" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">{"foo":"bar"}</script> </amp-state> <p [text]="myDefinedState.foo" i-amphtml-binding></p> <button on="tap:AMP.setState({})">See value of initialized state</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myDefinedState"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span> <span class="s2">"foo"</span><span class="o">:</span> <span class="s2">"bar"</span> <span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"myDefinedState.foo"</span><span class="p">></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>See value of initialized state<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.5.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p>Use <a href="#expressions">expressions</a> to reference <strong>state variables</strong>. If the JSON data is not nested in the <code><amp-state></code> component, reference the states via dot syntax. In the above example, <code>myState.foo</code> evaluates to "bar".</p> <p>An <code><amp-state></code> element can also specify a CORS URL instead of a child JSON script. See the <a href="#amp-state-specification"><code><amp-state></code> specification</a> for details.</p> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myRemoteState"</span> <span class="na">src</span><span class="o">=</span><span class="s">"/static/samples/json/websites.json"</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> </pre></div> <h3 id="updating-state-variables-with-amp.setstate()">Updating state variables with <code>AMP.setState()</code></h3> <p>The <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-bind/../../docs/spec/amp-actions-and-events.md#amp"><code>AMP.setState()</code></a> action merges an object literal into the state. This means you can update the value of a defined state variable.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-state id="myUpdateState" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">{"foo":"bar","baz":"hello"}</script> </amp-state> <p [text]="myUpdateState.foo" i-amphtml-binding></p> <p [text]="myUpdateState.baz" i-amphtml-binding></p> <button on="tap:AMP.setState({})">See value of set state</button> <button on="tap:AMP.setState({myUpdateState:{baz: myUpdateState.foo}})"> Set value of baz to value of foo </button> <button on="tap:AMP.setState({myUpdateState:{baz: 'world'}})"> Set value of baz to "world" </button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myUpdateState"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span> <span class="s2">"foo"</span><span class="o">:</span> <span class="s2">"bar"</span><span class="p">,</span> <span class="s2">"baz"</span><span class="o">:</span> <span class="s2">"hello"</span> <span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"myUpdateState.foo"</span><span class="p">></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"myUpdateState.baz"</span><span class="p">></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>See value of set state<span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- Like JavaScript, you can reference existing</span> <span class="c"> variables in the values of the object literal. --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({myUpdateState:{baz: myUpdateState.foo}})"</span><span class="p">></span> Set value of baz to value of foo <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({myUpdateState:{baz: 'world'}})"</span><span class="p">></span> Set value of baz to "world" <span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.6.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p>In the example above, triggering the <code>AMP.setState({})</code> action on the first button evaluates the <code>[text]</code> binding expression. It then inserts the defined <strong>state variable's</strong> value into the <code><p></code> tag.</p> <p>When the clicking the second button, with <code>AMP.setState({myState:{baz: myState.foo}})</code> action defined, it <a href="#deep-merge-with-ampsetstate">deep-merges</a> the "baz" <strong>state variable</strong> value to the same as the "foo" <strong>state variable</strong> value. Both <code><p></code> tags display "bar".</p> <p><strong>State variable</strong> values can update to values not defined in the initial state. When clicking the third button, with <code>"tap:AMP.setState({myState:{baz: 'world'}})"</code> action defined, it deep merges the "baz" <strong>state variable</strong> value, overriding it to "world".</p> <p>Clicking the first button after the other two sets the current state. Nothing will change.</p> <p>The <strong>state variables</strong> reverts back to the defined JSON in <code><amp-state></code> on page refresh.</p> <h5 id="event-triggering-and-data">Event triggering and data</h5> <p>When triggered by certain events, <code>AMP.setState()</code> can access event-related data on the <code>event</code> property.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <select on="change:AMP.setState({ option: event.value })"> <option value="0">No selection</option> <option value="1">Option 1</option> <option value="2">Option 2</option> </select> <div hidden [hidden]="option != 1" i-amphtml-binding> Option 1 </div> <div hidden [hidden]="option != 2" i-amphtml-binding> Option 2 </div> </div> <div class="-ta"><pre><span></span><span class="c"><!-- The "change" event of this <input> element contains</span> <span class="c"> a "value" variable that can be referenced via "event.value". --></span> <span class="p"><</span><span class="nt">select</span> <span class="na">on</span><span class="o">=</span><span class="s">"change:AMP.setState({ option: event.value })"</span><span class="p">></span> <span class="p"><</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">"0"</span><span class="p">></span>No selection<span class="p"></</span><span class="nt">option</span><span class="p">></span> <span class="p"><</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">"1"</span><span class="p">></span>Option 1<span class="p"></</span><span class="nt">option</span><span class="p">></span> <span class="p"><</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">"2"</span><span class="p">></span>Option 2<span class="p"></</span><span class="nt">option</span><span class="p">></span> <span class="p"></</span><span class="nt">select</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">hidden</span> <span class="na">[hidden]</span><span class="o">=</span><span class="s">"option != 1"</span><span class="p">></span> Option 1 <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">hidden</span> <span class="na">[hidden]</span><span class="o">=</span><span class="s">"option != 2"</span><span class="p">></span> Option 2 <span class="p"></</span><span class="nt">div</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.7.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h4 id="updating-nested-variables">Updating nested variables</h4> <p>Nested objects are generally merged to a maximum depth of 10. All variables, including those defined in <code><amp-state></code>, can be overidden.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-state id="myState" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">{"foo":"bar","first":{"a":"nested once","ab":{"b":"nested twice","bc":{"c":"nested three times","cd":{"d":"nested four times","de":{"e":"nested five times","ef":{"f":"nested six times","fg":{"g":"nested seven times","gh":{"h":"nested nine times","hi":{"i":"nested ten times"}}}}}}}}}}</script> </amp-state> <p [text]="myState.foo" i-amphtml-binding></p> <p [text]="myState.first.ab.bc.cd.de.ef.fg.gh.hi.i" i-amphtml-binding></p> <button on="tap:AMP.setState({})">See value of set state</button> <button on="tap:AMP.setState({ myState: {first: {ab: {bc: {cd: {de: {ef: {fg: {gh: {hi: {i:'this is as far as you should merge nested values'} } } } } } } } } } })"> Merge 10th nested object </button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myState"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span> <span class="s2">"foo"</span><span class="o">:</span> <span class="s2">"bar"</span><span class="p">,</span> <span class="s2">"first"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"a"</span><span class="o">:</span> <span class="s2">"nested once"</span><span class="p">,</span> <span class="s2">"ab"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"b"</span><span class="o">:</span> <span class="s2">"nested twice"</span><span class="p">,</span> <span class="s2">"bc"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"c"</span><span class="o">:</span> <span class="s2">"nested three times"</span><span class="p">,</span> <span class="s2">"cd"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"d"</span><span class="o">:</span> <span class="s2">"nested four times"</span><span class="p">,</span> <span class="s2">"de"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"e"</span><span class="o">:</span> <span class="s2">"nested five times"</span><span class="p">,</span> <span class="s2">"ef"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"f"</span><span class="o">:</span> <span class="s2">"nested six times"</span><span class="p">,</span> <span class="s2">"fg"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"g"</span><span class="o">:</span> <span class="s2">"nested seven times"</span><span class="p">,</span> <span class="s2">"gh"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"h"</span><span class="o">:</span> <span class="s2">"nested nine times"</span><span class="p">,</span> <span class="s2">"hi"</span><span class="o">:</span> <span class="p">{</span> <span class="s2">"i"</span><span class="o">:</span> <span class="s2">"nested ten times"</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"myState.foo"</span><span class="p">></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"myState.first.ab.bc.cd.de.ef.fg.gh.hi.i"</span><span class="p">></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>See value of set state<span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({ myState: {first: {ab: {bc: {cd: {de: {ef: {fg: {gh: {hi: {i:'this is as far as you should merge nested values'} } } } } } } } } } })"</span> <span class="p">></span> Merge 10th nested object <span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.8.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h4 id="circular-references">Circular references</h4> <p><code>AMP.setState(object)</code> throws an error if <code>object</code> contains a circular reference.</p> <h4 id="removing-a-variable">Removing a variable</h4> <p>Remove an existing state variable by setting its value to <code>null</code> in <code>AMP.setState()</code>.</p> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({removeMe: null})"</span><span class="p">></</span><span class="nt">button</span><span class="p">></span> </pre></div> <h4 id="deep-merge-with-amp.setstate()">Deep-merge with <code>AMP.setState()</code></h4> <p>Calling <code>AMP.setState()</code> deep-merges the provided object literal with the current state. <code>amp-bind</code> writes all literals to the state directly, except for nested objects, which are recursively merged. Primitives and arrays are in the state are always overwritten by variables of the same name in the object literal.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <p [text]="employee.name" i-amphtml-binding>Name</p> <p [text]="employee.age" i-amphtml-binding>Age</p> <p [text]="employee.vehicle" i-amphtml-binding>Vehicle</p> <button on="tap:AMP.setState({ employee: { name: 'John Smith', age: 47, vehicle: 'Car' } })"> Set employee to John Smith </button> <button on="tap:AMP.setState({ employee: { age: 64 } })"> Set employee age to 64 </button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"employee.name"</span><span class="p">></span>Name<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"employee.age"</span><span class="p">></span>Age<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"employee.vehicle"</span><span class="p">></span>Vehicle<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="c"><!-- Pressing this button changes state to: --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({</span> <span class="s"> employee: {</span> <span class="s"> name: 'John Smith',</span> <span class="s"> age: 47,</span> <span class="s"> vehicle: 'Car'</span> <span class="s"> }</span> <span class="s"> })"</span> <span class="p">></span> Set employee to John Smith <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- Pressing this button recursively merges the object literal argument, --></span> <span class="c"><!-- `{employee: {age: 64}}`, into the existing state. --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({</span> <span class="s"> employee: {</span> <span class="s"> age: 64</span> <span class="s"> }</span> <span class="s"> })"</span> <span class="p">></span> Set employee age to 64 <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- The value updates from 47 to 64 at employee.age. --></span> <span class="c"><!-- No other values change. --></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.9.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p> </p> <h3 id="modifying-history-with-amp.pushstate()">Modifying history with <code>AMP.pushState()</code></h3> <p><code>AMP.pushState()</code> writes state changes to the history. Navigating back, will restore the previous state. To test this, increase the count in the example below and use your browser's back button to decrease the count.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-state id="count" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">1</script> </amp-state> <div>Item <span [text]="count" i-amphtml-binding>1</span></div> <button on="tap:AMP.pushState({ count: count + 1 })">Increase count</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"count"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="mi">1</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span><span class="p">></span>Item <span class="p"><</span><span class="nt">span</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"count"</span><span class="p">></span>1<span class="p"></</span><span class="nt">span</span><span class="p">></</span><span class="nt">div</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.pushState({ count: count + 1 })"</span><span class="p">></span>Increase count<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.10.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p>Using <code>AMP.pushState()</code> sets the current state to the most recent pushed state.</p> <p> </p> <h2 id="expressions">Expressions</h2> <p><code>amp-bind</code> uses JavaScript-like expressions that can reference the state.</p> <h3 id="differences-from-javascript">Differences from JavaScript</h3> <ul> <li>Expressions may only access the containing document's <a href="#state">state</a>.</li> <li>Expressions <strong>do not</strong> have access to <code>window</code> or <code>document</code>. <code>global</code> references the top-level state.</li> <li>Only <code>amp-bind</code> <a href="#allowlisted-functions">allowlisted functions</a> and operators are usable. are usable. Use of arrow functions are allowed as function parameters, e.g. <code>[1, 2, 3].map(x => x + 1)</code>.<ul> <li>Custom functions, classes and loops are disallowed.</li> </ul> </li> <li>Undefined variables and array-index-out-of-bounds return <code>null</code> instead of <code>undefined</code> or throwing errors.</li> <li>A single expression is currently capped at 250 operands for performance. Please <a href="https://github.com/ampproject/amphtml/issues/new/choose">contact us</a> if this is insufficient for your use case.</li> </ul> <p>The following are all valid expressions:</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <p [text]="myExpressionsState.foo" i-amphtml-binding></p> <button on="tap:AMP.setState({myExpressionsState: {foo: 1 + '1'}})"> foo: 1 + "1" </button> <button on="tap:AMP.setState({myExpressionsState: {foo: 1 + + '1'}})"> foo: 1 + + "1" </button> <button on="tap:AMP.setState({myExpressionsState: {foo: !0}})">foo: !0</button> <button on="tap:AMP.setState({myExpressionsState: {foo: null || 'default'}})"> null || "default" </button> <button on="tap:AMP.setState({myExpressionsState: {foo: [1, 2, 3].map(x => x + 1)}})"> [1, 2, 3].map(x => x + 1) </button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"myExpressionsState.foo"</span><span class="p">></</span><span class="nt">p</span><span class="p">></span> <span class="c"><!-- 1 + '1'; // 11 --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({myExpressionsState: {foo: 1 + '1'}})"</span><span class="p">></span> foo: 1 + "1" <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- 1 + +'1'; // 2 --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({myExpressionsState: {foo: 1 + + '1'}})"</span><span class="p">></span> foo: 1 + + "1" <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- !0; // true --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({myExpressionsState: {foo: !0}})"</span><span class="p">></span>foo: !0<span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- null || 'default'; // 'default' --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({myExpressionsState: {foo: null || 'default'}})"</span><span class="p">></span> null || "default" <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- [1, 2, 3].map(x => x + 1); // 2,3,4 --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({myExpressionsState: {foo: [1, 2, 3].map(x => x + 1)}})"</span> <span class="p">></span> [1, 2, 3].map(x => x + 1) <span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.11.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p>Find the full expression grammar and implementation in <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-bind/./0.1/bind-expr-impl.jison">bind-expr-impl.jison</a> and <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-bind/./0.1/bind-expression.js">bind-expression.js</a>.</p> <h3 id="allowlisted-functions">Allowlisted functions</h3> <h4 id="array"><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Methods"><code>Array</code></a></h4> <p>Single-parameter arrow functions can't have parentheses, e.g. use <code>x => x + 1</code> instead of <code>(x) => x + 1</code>. <code>sort()</code> and <code>splice()</code> return modified copies instead of operating in-place.</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">concat</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">filter</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">includes</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">indexOf</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">join</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf">lastIndexOf</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce">reduce</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">slice</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some">some</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">sort</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">splice</a> (not-in-place)</li> </ul><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-state id="myArrayState" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">{"foo":[1,2,3],"bar":["hello","world","bar","baz"],"baz":"Hello world, welcome to amp-bind"}</script> </amp-state> <p [text]="'concat: ' + myArrayState.foo.concat(4)" i-amphtml-binding>concat: 1, 2, 3</p> <p [text]="'filter: ' + myArrayState.bar.filter(word => word.length > 3)" i-amphtml-binding> filter: words with less than three letter </p> <p [text]="'includes: ' + myArrayState.bar.includes('hello' || 'world')" i-amphtml-binding> includes: "hello" or "world" </p> <p [text]="'indexOf: ' + myArrayState.bar.indexOf('world')" i-amphtml-binding>indexOf: "world"</p> <p [text]="'join: ' + myArrayState.bar.join('-')" i-amphtml-binding> join: all words with a dash </p> <p [text]="'lastIndexOf: ' + myArrayState.baz.lastIndexOf('amp-bind')" i-amphtml-binding> lastIndexOf: "amp-bind" </p> <p [text]="'map: ' + myArrayState.foo.map((x, i) => x + i)" i-amphtml-binding> map: add each number to previous number </p> <p [text]="'reduce: ' + myArrayState.foo.reduce((x, i) => x + i)" i-amphtml-binding> reduce: add all numbers in array together </p> <p [text]="'slice: ' + myArrayState.bar.slice(1,3)" i-amphtml-binding> slice: return words at index 1 and 3 </p> <p [text]="'some: ' + myArrayState.foo.some(x => x < 2)" i-amphtml-binding> some: some numbers are less than 2 </p> <p [text]="'sort: ' + myArrayState.bar.sort()" i-amphtml-binding> sort: place words in alphabetical order </p> <p [text]="'splice: ' + myArrayState.bar.splice(2, 0, 'amp-bind')" i-amphtml-binding> splice: place "amp-bind" at index 2 </p> <button on="tap:AMP.setState({})">Evaluate</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myArrayState"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span> <span class="s2">"foo"</span><span class="o">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="s2">"bar"</span><span class="o">:</span> <span class="p">[</span><span class="s2">"hello"</span><span class="p">,</span> <span class="s2">"world"</span><span class="p">,</span> <span class="s2">"bar"</span><span class="p">,</span> <span class="s2">"baz"</span><span class="p">],</span> <span class="s2">"baz"</span><span class="o">:</span> <span class="s2">"Hello world, welcome to amp-bind"</span> <span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'concat: ' + myArrayState.foo.concat(4)"</span><span class="p">></span>concat: 1, 2, 3<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'filter: ' + myArrayState.bar.filter(word => word.length > 3)"</span><span class="p">></span> filter: words with less than three letter <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'includes: ' + myArrayState.bar.includes('hello' || 'world')"</span><span class="p">></span> includes: "hello" or "world" <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'indexOf: ' + myArrayState.bar.indexOf('world')"</span><span class="p">></span>indexOf: "world"<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'join: ' + myArrayState.bar.join('-')"</span><span class="p">></span> join: all words with a dash <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'lastIndexOf: ' + myArrayState.baz.lastIndexOf('amp-bind')"</span><span class="p">></span> lastIndexOf: "amp-bind" <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'map: ' + myArrayState.foo.map((x, i) => x + i)"</span><span class="p">></span> map: add each number to previous number <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'reduce: ' + myArrayState.foo.reduce((x, i) => x + i)"</span><span class="p">></span> reduce: add all numbers in array together <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'slice: ' + myArrayState.bar.slice(1,3)"</span><span class="p">></span> slice: return words at index 1 and 3 <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'some: ' + myArrayState.foo.some(x => x < 2)"</span><span class="p">></span> some: some numbers are less than 2 <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'sort: ' + myArrayState.bar.sort()"</span><span class="p">></span> sort: place words in alphabetical order <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'splice: ' + myArrayState.bar.splice(2, 0, 'amp-bind')"</span><span class="p">></span> splice: place "amp-bind" at index 2 <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>Evaluate<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.12.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h4 id="number"><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#Methods"><code>Number</code></a></h4> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential">toExponential</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed">toFixed</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision">toPrecision</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString">toString</a></li> </ul><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <p [text]="'toExponential: ' + (100).toExponential(5)" i-amphtml-binding> toExponential: 100 to the exponent of 5 </p> <p [text]="'toFixed: ' + (1.99).toFixed(1)" i-amphtml-binding> toFixed: 1.99 rounded and fixed to first decimal </p> <p [text]="'toPrecision: ' + (1.234567).toPrecision(3)" i-amphtml-binding> toPrecision: 1.234567 returned as a string to the third digit </p> <p [text]="'toString ' + (3.14).toString()" i-amphtml-binding> toString: 3.14 returned as a string </p> <button on="tap:AMP.setState({})">Evaluate</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'toExponential: ' + (100).toExponential(5)"</span><span class="p">></span> toExponential: 100 to the exponent of 5 <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'toFixed: ' + (1.99).toFixed(1)"</span><span class="p">></span> toFixed: 1.99 rounded and fixed to first decimal <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'toPrecision: ' + (1.234567).toPrecision(3)"</span><span class="p">></span> toPrecision: 1.234567 returned as a string to the third digit <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'toString ' + (3.14).toString()"</span><span class="p">></span> toString: 3.14 returned as a string <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>Evaluate<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.13.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h4 id="string"><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Methods"><code>String</code></a></h4> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt">charAt</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt">charCodeAt</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat">concat</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">indexOf</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">lastIndexOf</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice">slice</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">split</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr">substr</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">toLowerCase</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase">toUpperCase</a></li> </ul><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-state id="myStringState" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">{"foo":"Hello world","bar":", welcome to amp-bind"}</script> </amp-state> <p [text]="'charAt: ' + myStringState.foo.charAt(6)" i-amphtml-binding> charAt: The character at index 6 </p> <p [text]="'charCodeAt: ' + myStringState.foo.charCodeAt(6)" i-amphtml-binding> charCodeAt: The UTF-16 code unit of the character at index 6 </p> <p [text]="'concat: ' + myStringState.foo.concat(myState.bar)" i-amphtml-binding> concat: Combine foo and bar </p> <p [text]="'lastIndexOf: ' + myStringState.foo.lastIndexOf('w')" i-amphtml-binding> lastIndexOf: The index of "w" </p> <p [text]="'replace: ' + myStringState.foo.replace('world', 'amp-bind')" i-amphtml-binding> replace: Replace "world" with "amp-bind" </p> <p [text]="'slice: ' + myStringState.foo.slice(5)" i-amphtml-binding> slice: Extract the first 5 characters </p> <p [text]="'split: ' + myStringState.foo.split(' ')" i-amphtml-binding> split: Split words at space and return as array </p> <p [text]="'toLowerCase: ' + myStringState.foo.toLowerCase()" i-amphtml-binding> toLowerCase: Make all letters lower case </p> <p [text]="'toUpperCase: ' + myStringState.foo.toUpperCase()" i-amphtml-binding> toUpperCase: Make all letters upper case </p> <button on="tap:AMP.setState({})">Evaluate</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myStringState"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span> <span class="s2">"foo"</span><span class="o">:</span> <span class="s2">"Hello world"</span><span class="p">,</span> <span class="s2">"bar"</span><span class="o">:</span> <span class="s2">", welcome to amp-bind"</span> <span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'charAt: ' + myStringState.foo.charAt(6)"</span><span class="p">></span> charAt: The character at index 6 <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'charCodeAt: ' + myStringState.foo.charCodeAt(6)"</span><span class="p">></span> charCodeAt: The UTF-16 code unit of the character at index 6 <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'concat: ' + myStringState.foo.concat(myState.bar)"</span><span class="p">></span> concat: Combine foo and bar <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'lastIndexOf: ' + myStringState.foo.lastIndexOf('w')"</span><span class="p">></span> lastIndexOf: The index of "w" <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'replace: ' + myStringState.foo.replace('world', 'amp-bind')"</span><span class="p">></span> replace: Replace "world" with "amp-bind" <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'slice: ' + myStringState.foo.slice(5)"</span><span class="p">></span> slice: Extract the first 5 characters <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'split: ' + myStringState.foo.split(' ')"</span><span class="p">></span> split: Split words at space and return as array <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'toLowerCase: ' + myStringState.foo.toLowerCase()"</span><span class="p">></span> toLowerCase: Make all letters lower case <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'toUpperCase: ' + myStringState.foo.toUpperCase()"</span><span class="p">></span> toUpperCase: Make all letters upper case <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>Evaluate<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.14.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h4 id="math"><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math"><code>Math</code></a></h4> <p>Static functions are not namespaced, e.g. use <code>abs(-1)</code> instead of <code>Math.abs(-1)</code></p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs">abs</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil">ceil</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">floor</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max">max</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min">min</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow">pow</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">random</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round">round</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign">sign</a></li> </ul><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <p [text]="'abs: ' + abs(5 - 9)" i-amphtml-binding>abs: absolute number of 5 - 9</p> <p [text]="'ceil: ' + ceil(1.01)" i-amphtml-binding> abs: round 1.01 up to the next largest whole number </p> <p [text]="'floor: ' + floor(1.99)" i-amphtml-binding>floor: round 1.99 down to a whole number</p> <p [text]="'max: ' + max(100, 4, 98)" i-amphtml-binding>max: return largest number</p> <p [text]="'min: ' + min(100, 4, 98)" i-amphtml-binding>min: return smalled number</p> <p [text]="'pow: ' + pow(5, 3)" i-amphtml-binding>pow: return 5 to the power of 3</p> <p [text]="'random: ' + random()" i-amphtml-binding> random: return a number greater than 0 and less than 1 </p> <p [text]="'round: ' + round(1.51)" i-amphtml-binding>round: round 1.51</p> <p [text]="'sign: ' + sign(-9)" i-amphtml-binding>sign: evaluate if positive or negative</p> <button on="tap:AMP.setState({})">Evaluate</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'abs: ' + abs(5 - 9)"</span><span class="p">></span>abs: absolute number of 5 - 9<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'ceil: ' + ceil(1.01)"</span><span class="p">></span> abs: round 1.01 up to the next largest whole number <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'floor: ' + floor(1.99)"</span><span class="p">></span>floor: round 1.99 down to a whole number<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'max: ' + max(100, 4, 98)"</span><span class="p">></span>max: return largest number<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'min: ' + min(100, 4, 98)"</span><span class="p">></span>min: return smalled number<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'pow: ' + pow(5, 3)"</span><span class="p">></span>pow: return 5 to the power of 3<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'random: ' + random()"</span><span class="p">></span> random: return a number greater than 0 and less than 1 <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'round: ' + round(1.51)"</span><span class="p">></span>round: round 1.51<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'sign: ' + sign(-9)"</span><span class="p">></span>sign: evaluate if positive or negative<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>Evaluate<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.15.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h4 id="object"><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"><code>Object</code></a></h4> <p>Static functions are not namespaced, e.g. use <code>keys(Object)</code> instead of <code>Object.abs(Object)</code></p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">keys</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values">values</a></li> </ul><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-state id="myObjectState" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">{"hello":"world","foo":"bar"}</script> </amp-state> <p [text]="'keys: ' + keys(myObjectState)" i-amphtml-binding> keys: myObjectState JSON object keys </p> <p [text]="'values: ' + values(myObjectState)" i-amphtml-binding> values: myObjectState JSON object values </p> <button on="tap:AMP.setState({})">Evaluate</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myObjectState"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span> <span class="s2">"hello"</span><span class="o">:</span> <span class="s2">"world"</span><span class="p">,</span> <span class="s2">"foo"</span><span class="o">:</span> <span class="s2">"bar"</span> <span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'keys: ' + keys(myObjectState)"</span><span class="p">></span> keys: myObjectState JSON object keys <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'values: ' + values(myObjectState)"</span><span class="p">></span> values: myObjectState JSON object values <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>Evaluate<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.16.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h4 id="global"><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects"><code>Global</code></a></h4> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent</a></li> </ul><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <p [text]="'encodeURI: ' + encodeURI('https://amp.dev/😉')" i-amphtml-binding> encodeURI: Encode a URI and ignore protocol prefix </p> <p [text]="'encodeURIComponent: ' + encodeURIComponent('https://amp.dev/😉')" i-amphtml-binding> encodeURIComponent: Encode a URI </p> <button on="tap:AMP.setState({})">Evaluate</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'encodeURI: ' + encodeURI('https://amp.dev/😉')"</span><span class="p">></span> encodeURI: Encode a URI and ignore protocol prefix <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'encodeURIComponent: ' + encodeURIComponent('https://amp.dev/😉')"</span><span class="p">></span> encodeURIComponent: Encode a URI <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({})"</span><span class="p">></span>Evaluate<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.17.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h3 id="defining-macros-with-amp-bind-macro">Defining macros with <code>amp-bind-macro</code></h3> <p>Reuse <code>amp-bind</code> expression fragments by defining an <code>amp-bind-macro</code>. The <code>amp-bind-macro</code> element allows an expression that takes zero or more arguments and references the current state. Invoke <code>amp-bind-macros</code> like a function, referencing the <code>id</code> attribute value from anywhere in the document.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-bind-macro id="circleArea" arguments="radius" expression="3.14 * radius * radius" class="i-amphtml-layout-container" i-amphtml-layout="container"></amp-bind-macro> <p> Input a radius value </p> <input type="number" min="0" max="100" value="0" on="input-throttled:AMP.setState({myCircle:{radius: event.value}})"> <p> The circle has an area of <span [text]="circleArea(myCircle.radius)" i-amphtml-binding>0</span>. </p> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-bind-macro</span> <span class="na">id</span><span class="o">=</span><span class="s">"circleArea"</span> <span class="na">arguments</span><span class="o">=</span><span class="s">"radius"</span> <span class="na">expression</span><span class="o">=</span><span class="s">"3.14 * radius * radius"</span> <span class="p">></</span><span class="nt">amp-bind-macro</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span><span class="p">></span> Input a radius value <span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">"number"</span> <span class="na">min</span><span class="o">=</span><span class="s">"0"</span> <span class="na">max</span><span class="o">=</span><span class="s">"100"</span> <span class="na">value</span><span class="o">=</span><span class="s">"0"</span> <span class="na">on</span><span class="o">=</span><span class="s">"input-throttled:AMP.setState({myCircle:{radius: event.value}})"</span> <span class="p">/></span> <span class="p"><</span><span class="nt">p</span><span class="p">></span> The circle has an area of <span class="p"><</span><span class="nt">span</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"circleArea(myCircle.radius)"</span><span class="p">></span>0<span class="p"></</span><span class="nt">span</span><span class="p">></span>. <span class="p"></</span><span class="nt">p</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.18.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p>A macro can also call other macros <i>defined before itself</i>. A macro cannot call itself recursively.</p> <h2 id="bindings">Bindings</h2> <p>A <strong>binding</strong> is a special attribute of the form <code>[property]</code> that links an element's property to an <a href="#expressions">expression</a>. Use the alternative,<a href="#react-and-xml-compatibility">XML-compatible</a> syntax if developing in XML.</p> <p>When the <strong>state</strong> changes, expressions tied to that state are evaluated. The element properties <strong>bound</strong> to the <strong>state</strong> are updated with the new expression results.</p> <p>Boolean expression results toggle boolean attributes. For example: <code><amp-video [controls]="expr"...></code>. When <code>expr</code> evaluates to <code>true</code>, the <code><amp-video></code> element has the <code>controls</code> attribute. When <code>expr</code> evaluates to <code>false</code>, the <code>controls</code> attribute is removed.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-video [controls]="controls" width="640" height="360" layout="responsive" poster="/static/inline-examples/images/kitten-playing.png" i-amphtml-binding class="i-amphtml-layout-responsive i-amphtml-layout-size-defined" i-amphtml-layout="responsive"><i-amphtml-sizer slot="i-amphtml-svc" style="display:block;padding-top:56.25%"></i-amphtml-sizer> <source src="/static/inline-examples/videos/kitten-playing.webm" type="video/webm"> <source src="/static/inline-examples/videos/kitten-playing.mp4" type="video/mp4"> <div fallback> <p>This browser does not support the video element.</p> </div> </amp-video> <button on="tap:AMP.setState({ controls: true })"> Controls </button> <button on="tap:AMP.setState({ controls: false })"> No Controls </button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-video</span> <span class="na">[controls]</span><span class="o">=</span><span class="s">"controls"</span> <span class="na">width</span><span class="o">=</span><span class="s">"640"</span> <span class="na">height</span><span class="o">=</span><span class="s">"360"</span> <span class="na">layout</span><span class="o">=</span><span class="s">"responsive"</span> <span class="na">poster</span><span class="o">=</span><span class="s">"/static/inline-examples/images/kitten-playing.png"</span> <span class="p">></span> <span class="p"><</span><span class="nt">source</span> <span class="na">src</span><span class="o">=</span><span class="s">"/static/inline-examples/videos/kitten-playing.webm"</span> <span class="na">type</span><span class="o">=</span><span class="s">"video/webm"</span> <span class="p">/></span> <span class="p"><</span><span class="nt">source</span> <span class="na">src</span><span class="o">=</span><span class="s">"/static/inline-examples/videos/kitten-playing.mp4"</span> <span class="na">type</span><span class="o">=</span><span class="s">"video/mp4"</span> <span class="p">/></span> <span class="p"><</span><span class="nt">div</span> <span class="na">fallback</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span><span class="p">></span>This browser does not support the video element.<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-video</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({ controls: true })"</span><span class="p">></span> Controls <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({ controls: false })"</span><span class="p">></span> No Controls <span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.19.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <h3 id="react-and-xml-compatibility">React and XML compatibility</h3> <p>If developing with React or XML, use the alternative <code>data-amp-bind-property</code> syntax. The <code>[</code> and <code>]</code> characters in attribute names is invalid XML, making the <code>[property]</code> syntax unavailable.</p> <p>Replace the <code>property</code> field with the name of the property you would like to define in <code>data-amp-bind-property</code>.</p> <p>For example, <code>[text]="myState.foo"</code> would become <code>data-amp-bind-text="myState.foo"</code>.</p> <h3 id="binding-types">Binding types</h3> <p><code>amp-bind</code> supports data bindings on five types of element state.</p> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent"><strong>Node.textContent</strong></a></p> <p>Bind <code>Node.textContent</code> using the <code>[text]</code> attribute. The <code>[text]</code> attribute is supported on most text elements.</p> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"'Hello ' + myState.foo"</span><span class="p">></span>Hello World<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">p</span><span class="p">></</span><span class="nt">p</span><span class="p">></span> </pre></div> <p><strong>CSS classes</strong></p> <p>Bind an element's <code>class</code> using the <code>[class]</code> attribute. A <code>[class]</code> expression must result in a space-delimited string. Meaning, if you are binding multiple classes, use a space between names. A comma or dash will be evaluated as the class name.</p><div class="ap-code-preview top-frame"> <amp-state id="orientation20" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">true</script> </amp-state> <amp-state id="dimension20" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">{"width":533,"height":300}</script> </amp-state> <amp-state id="example20" class="i-amphtml-layout-container" i-amphtml-layout="container"> <script type="application/json">"https://preview.amp.dev/documentation/components/amp-bind.example.20.html"</script> </amp-state> <div class="ap-code-preview-top-preview ap-code-preview-top-preview-20"> <div class="ap-code-preview-controls"> <button [hidden]="!orientation20" class="ap-code-preview-controls-button" on="tap: AMP.setState({ orientation20: true, dimension20: { width: dimension20.height, height: dimension20.width, } })" i-amphtml-binding> <div class="ap-a-ico ap-code-preview-controls-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#orientation-toggle"/></svg> </div> </button> <button class="ap-code-preview-controls-button" on="tap:AMP.setState({'example20': 'https://preview.amp.dev/documentation/components/amp-bind.example.20.html?' + random()})"> <div class="ap-a-ico ap-code-preview-controls-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#reload"/></svg> </div> </button> </div> <amp-iframe id="iframeContainer20" class="ap-code-preview-iframe i-amphtml-layout-intrinsic i-amphtml-layout-size-defined" src="https://preview.amp.dev/documentation/components/amp-bind.example.20.html" layout="intrinsic" width="533" [width]="dimension20.width" height="300" [height]="dimension20.height" [src]="example20" sandbox="allow-scripts allow-popups allow-same-origin" frameborder="0" i-amphtml-binding i-amphtml-layout="intrinsic"><i-amphtml-sizer slot="i-amphtml-svc" class="i-amphtml-sizer"><img alt aria-hidden="true" class="i-amphtml-intrinsic-sizer" role="presentation" src="data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgd2lkdGg9IjUzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4="></i-amphtml-sizer> <div placeholder></div> </amp-iframe> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">head</span><span class="p">></span> <span class="p"><</span><span class="nt">style</span> <span class="na">amp-custom</span><span class="p">></span> <span class="p">.</span><span class="nc">background-green</span> <span class="p">{</span> <span class="k">background</span><span class="p">:</span> <span class="kc">green</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">background-red</span> <span class="p">{</span> <span class="k">background</span><span class="p">:</span> <span class="kc">red</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">border-red</span> <span class="p">{</span> <span class="k">border-color</span><span class="p">:</span> <span class="kc">red</span><span class="p">;</span> <span class="k">border-width</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span><span class="p">;</span> <span class="k">border-style</span><span class="p">:</span> <span class="kc">solid</span><span class="p">;</span> <span class="p">}</span> <span class="p"></</span><span class="nt">style</span><span class="p">></span> <span class="p"></</span><span class="nt">head</span><span class="p">></span> <span class="p"><</span><span class="nt">body</span><span class="p">></span> <span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"background-red"</span> <span class="na">[class]</span><span class="o">=</span><span class="s">"myClass"</span><span class="p">></span>Hello World<span class="p"></</span><span class="nt">div</span><span class="p">></span> <span class="c"><!-- This button adds both classes --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({ myClass: 'background-green border-red' })"</span><span class="p">></span> Working: Change Class <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- String arrays also work --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({ myClass: ['background-green', 'border-red'] })"</span> <span class="p">></span> Working string array: Change Class <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="c"><!-- This expression evaluates to class="background-green,border-red" --></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({ myClass: 'background-green,border-red' })"</span><span class="p">></span> Broken: Change Class <span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"></</span><span class="nt">body</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.20.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden"><strong>the <code>hidden</code> attribute</strong></a></p> <p>Hide and reveal and element using the <code>[hidden]</code> attribute. A <code>[hidden]</code> expression should be a boolean expression.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <p [hidden]="hiddenState" i-amphtml-binding>Hello there!</p> <button on="tap:AMP.setState({hiddenState: true})">Hide</button> <button on="tap:AMP.setState({hiddenState: false})">Show</button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">p</span> <span class="na">[hidden]</span><span class="o">=</span><span class="s">"hiddenState"</span><span class="p">></span>Hello there!<span class="p"></</span><span class="nt">p</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({hiddenState: true})"</span><span class="p">></span>Hide<span class="p"></</span><span class="nt">button</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({hiddenState: false})"</span><span class="p">></span>Show<span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.21.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p><strong>Size of <a href="https://www.ampproject.org/docs/reference/components">AMP components</a></strong></p> <p>Change the <code>width</code> and <code>height</code> using the <code>[width]</code> and <code>[height]</code> attributes.</p><div class="ap-code-preview inline"> <div class="ap-code-preview-preview"> <amp-img src="https://unsplash.it/400/200" width="200" [width]="myImageDimension.width" height="100" [height]="myImageDimension.height" i-amphtml-binding class="i-amphtml-layout-fixed i-amphtml-layout-size-defined" style="width:200px;height:100px;" i-amphtml-layout="fixed"> </amp-img> <button on="tap:AMP.setState({ myImageDimension: { width: 400, height: 200 } })"> Change size </button> </div> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-img</span> <span class="na">src</span><span class="o">=</span><span class="s">"https://unsplash.it/400/200"</span> <span class="na">width</span><span class="o">=</span><span class="s">"200"</span> <span class="na">[width]</span><span class="o">=</span><span class="s">"myImageDimension.width"</span> <span class="na">height</span><span class="o">=</span><span class="s">"100"</span> <span class="na">[height]</span><span class="o">=</span><span class="s">"myImageDimension.height"</span> <span class="p">></span> <span class="p"></</span><span class="nt">amp-img</span><span class="p">></span> <span class="p"><</span><span class="nt">button</span> <span class="na">on</span><span class="o">=</span><span class="s">"tap:AMP.setState({</span> <span class="s"> myImageDimension: {</span> <span class="s"> width: 400,</span> <span class="s"> height: 200</span> <span class="s"> }</span> <span class="s"> })"</span> <span class="p">></span> Change size <span class="p"></</span><span class="nt">button</span><span class="p">></span> </pre></div> </div> <a href="https://playground.amp.dev/?url=https%3A//preview.amp.dev/documentation/components/amp-bind.example.22.html%3Fformat%3Dwebsites" class="-n ap--playground-link"> <div class="ap-a-ico -i"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg> </div> <span class="-r">Open this snippet in playground</span> </a> <p><strong>Accessibility states and properties</strong></p> <p>Use to dynamically update information available to assistive technologies, such as screen readers. <a href="https://www.w3.org/WAI/PF/aria-1.1/states_and_properties">All <code>[aria-*]</code> attributes</a> are bindable.</p> <p><strong>AMP Component specific and HTML attributes</strong></p> <p>Some AMP components and HTML elements have specific bindable attributes. They are listed below.</p> <h3 id="amp-component-specific-attributes">AMP component specific attributes</h3> <p> </p> <p><strong><code><amp-brightcove></code></strong></p> <ul> <li><code>[data-account]</code></li> <li><code>[data-embed]</code></li> <li><code>[data-player]</code></li> <li><code>[data-player-id]</code></li> <li><code>[data-playlist-id]</code></li> <li><code>[data-video-id]</code> Changes the displayed Brightcove video.</li> </ul> <p> </p> <p><strong><code><amp-carousel type=slides></code></strong></p> <ul> <li><code>[slide]</code> Changes the currently displayed slide index.</li> </ul> <p><a href="https://amp.dev/documentation/examples/multimedia-animations/image_galleries_with_amp-carousel/#linking-carousels-with-amp-bind">See an example</a>.</p> <p> </p> <p><strong><code><amp-date-picker></code></strong></p> <ul> <li><code>[min]</code> Sets the earliest selectable date</li> <li><code>[max]</code> Sets the latest selectable date</li> </ul> <p><strong><code><amp-google-document-embed></code></strong></p> <ul> <li><code>[src]</code> Displays the document at the updated URL.</li> <li><code>[title]</code> Changes the document's title.</li> </ul> <p><strong><code><amp-iframe></code></strong></p> <ul> <li><code>[src]</code> Changes the iframe's source URL.</li> </ul> <p> </p> <p><strong><code><amp-img></code></strong></p> <ul> <li><code>[alt]</code></li> <li><code>[attribution]</code></li> <li><code>[src]</code></li> <li><code>[srcset]</code></li> </ul> <p>Bind to <code>[srcset]</code> instead of <code>[src]</code> to support responsive images. See corresponding <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-bind/../../src/builtins/amp-img/amp-img.md#attributes"><code>amp-img</code> attributes</a>.</p> <p> </p> <p><strong><code><amp-lightbox></code></strong></p> <ul> <li><code>[open]</code> Toggles display of the lightbox.</li> </ul> <p> </p><div class="ap-m-tip"> <div class="ap-a-ico ap-m-tip-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#speech-bubble"/></svg> </div> <div class="ap-m-tip-content"> Use <code>on="lightboxClose: AMP.setState(...)"</code> to update variables when the lightbox is closed. </div> </div><p></p> <p> </p> <p><strong><code><amp-list></code></strong></p> <ul> <li><code>[src]</code></li> </ul> <p>If the expression is a string, it fetches and renders JSON from the string URL. If the expression is an object or array, it renders the expression data.</p> <p> </p> <p> </p> <p><strong><code><amp-selector></code></strong></p> <ul> <li><code>[selected]</code> Changes the currently selected children element(s) identified by their <code>option</code> attribute values. Supports a comma-separated list of values for multiple selection. <a href="https://amp.dev/documentation/examples/multimedia-animations/image_galleries_with_amp-carousel/?format=email#linking-carousels-with-amp-bind">See an example</a>.</li> <li><code>[disabled]</code></li> </ul> <p> </p><div class="ap-m-tip"> <div class="ap-a-ico ap-m-tip-icon"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#speech-bubble"/></svg> </div> <div class="ap-m-tip-content"> <code>[selected]</code> does not have a non-bindable attribute. The AMP Validator will throw an error if <code>selected</code> is used. </div> </div><p></p> <p> </p> <p> </p> <p><strong><code><amp-state></code></strong></p> <ul> <li><code>[src]</code></li> </ul> <p>Fetches JSON from the new URL and merges it into the existing state. The following update will ignore <code><amp-state></code>elements to prevent cycles.</p> <p> </p> <p> </p> <p><strong><code><amp-twitter></code></strong></p> <ul> <li><code>[data-tweetid]</code> Changes the displayed Tweet.</li> </ul> <p> </p> <p> </p> <p><strong><code><amp-video></code></strong></p> <ul> <li><code>[alt]</code></li> <li><code>[attribution]</code></li> <li><code>[controls]</code></li> <li><code>[loop]</code></li> <li><code>[poster]</code></li> <li><code>[preload]</code></li> <li><code>[src]</code></li> </ul> <p>See corresponding <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-bind/../amp-video/amp-video.md#attributes"><code>amp-video</code> attributes</a>.</p> <p> </p> <p> </p> <p><strong><code><amp-youtube></code></strong></p> <ul> <li><code>[data-videoid]</code> Changes the displayed YouTube video.</li> </ul> <p> </p> <p> </p> <h3 id="html-attributes">HTML attributes</h3> <p><strong><code><a></code></strong></p> <ul> <li><code>[href]</code> Changes the link.</li> </ul> <p><strong><code><button></code></strong></p> <ul> <li><code>[disabled]</code></li> <li><code>[type]</code></li> <li><code>[value]</code></li> </ul> <p> </p> <p> </p> <p><strong><code><details></code></strong></p> <ul> <li><code>[open]</code></li> </ul> <p>See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#Attributes">details attributes</a>.</p> <p><strong><code><fieldset></code></strong></p> <ul> <li><code>[disabled]</code> Enables or disables the fieldset.</li> </ul> <p><strong><code><image></code></strong></p> <ul> <li><code>[xlink:href]</code></li> </ul> <p>See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image">image attributes</a>.</p> <p> </p> <p><strong><code><input></code></strong></p> <ul> <li><code>[accept]</code></li> <li><code>[accessKey]</code></li> <li><code>[autocomplete]</code></li> <li><code>[checked]</code></li> <li><code>[disabled]</code></li> <li><code>[height]</code></li> <li><code>[inputmode]</code></li> <li><code>[max]</code></li> <li><code>[maxlength]</code></li> <li><code>[multiple]</code></li> <li><code>[pattern]</code></li> <li><code>[placeholder]</code></li> <li><code>[readonly]</code></li> <li><code>[required]</code></li> <li><code>[selectiondirection]</code></li> <li><code>[size]</code></li> <li><code>[spellcheck]</code></li> <li><code>[step]</code></li> <li><code>[type]</code></li> <li><code>[value]</code></li> <li><code>[width]</code></li> </ul> <p>See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes">input attributes</a>.</p> <p> </p> <p> </p> <p><strong><code><option></code></strong></p> <ul> <li><code>[disabled]</code></li> <li><code>[label]</code></li> <li><code>[selected]</code></li> <li><code>[value]</code></li> </ul> <p>See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option#Attributes">option attributes</a>.</p> <p><strong><code><optgroup></code></strong></p> <ul> <li><code>[disabled]</code></li> <li><code>[label]</code></li> </ul> <p>See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup#Attributes">optgroup attributes</a>.</p> <p><strong><code><section></code></strong></p> <ul> <li><code>[data-expand]</code> Changes the expansion of a <code>section</code> in an <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-bind/../amp-accordion/amp-accordion.md"><code>amp-accordion</code></a>.</li> </ul> <p> </p> <p><strong><code><select></code></strong></p> <ul> <li><code>[autofocus]</code></li> <li><code>[disabled]</code></li> <li><code>[multiple]</code></li> <li><code>[required]</code></li> <li><code>[size]</code></li> </ul> <p>See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#Attributes">select attributes</a>.</p> <p> </p> <p> </p> <p> </p> <p><strong><code><source></code></strong></p> <ul> <li><code>[src]</code></li> <li><code>[type]</code></li> </ul> <p>See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source#Attributes">source attributes</a>.</p> <p><strong><code><track></code></strong></p> <ul> <li>[label]</li> <li>[src]</li> <li>[srclang]</li> </ul> <p>See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track#Attributes">track attributes</a>.</p> <p> </p> <p> </p> <p><strong><code><textarea></code></strong></p> <ul> <li><code>[autocomplete]</code></li> <li><code>[autofocus]</code></li> <li><code>[cols]</code></li> <li><code>[disabled]</code></li> <li><code>[defaultText]</code></li> <li><code>[maxlength]</code></li> <li><code>[minlength]</code></li> <li><code>[placeholder]</code></li> <li><code>[readonly]</code></li> <li><code>[required]</code></li> <li><code>[rows]</code></li> <li><code>[selectiondirection]</code></li> <li><code>[selectionend]</code></li> <li><code>[selectionstart]</code></li> <li><code>[spellcheck]</code></li> <li><code>[wrap]</code></li> </ul> <p>Use <code>[defaultText]</code> to update initial text, and <code>[text]</code> to update current text. See corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#Attributes">textarea attributes</a>.</p> <p> </p> <p> </p> <h3 id="disallowed-bindings">Disallowed bindings</h3> <p>For security reasons, binding to <code>innerHTML</code> is disallowed.</p> <p>All attribute bindings are sanitized for unsafe values (e.g., <code>javascript:</code>).</p> <h2 id="debugging">Debugging</h2> <p> </p> <p>Test in development mode. Enter development by adding the fragment <code>#development=1</code> to the end of the URL. This highlights warnings and errors in the browser console during development and grants access to special debugging functions.</p> <p> </p> <p> </p> <h3 id="warnings">Warnings</h3> <p>In development mode, <code>amp-bind</code> will issue a warning when the default value of a bound attribute doesn't match its corresponding expression's initial result. This can help prevent unintended mutations caused by changes in other state variables. For example:</p> <div class="-ta"><pre><span></span><span class="c"><!-- The element's default class value ('def') doesn't match the expression result for [class] ('abc'),</span> <span class="c"> so a warning will be issued in development mode. --></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[class]</span><span class="o">=</span><span class="s">"'abc'"</span> <span class="na">class</span><span class="o">=</span><span class="s">"def"</span><span class="p">></</span><span class="nt">p</span><span class="p">></span> </pre></div> <p>In development mode, <code>amp-bind</code> will also issue a warning when dereferencing undefined variables or properties. This can also help prevent unintended mutations due to <code>null</code> expression results. For example:</p> <div class="-ta"><pre><span></span><span class="p"><</span><span class="nt">amp-state</span> <span class="na">id</span><span class="o">=</span><span class="s">"myAmpState"</span><span class="p">></span> <span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"application/json"</span><span class="p">></span> <span class="p">{</span><span class="s2">"foo"</span><span class="o">:</span> <span class="mi">123</span><span class="p">}</span> <span class="p"></</span><span class="nt">script</span><span class="p">></span> <span class="p"></</span><span class="nt">amp-state</span><span class="p">></span> <span class="c"><!-- The amp-state#myAmpState does not have a `bar` variable, so a warning</span> <span class="c"> will be issued in development mode. --></span> <span class="p"><</span><span class="nt">p</span> <span class="na">[text]</span><span class="o">=</span><span class="s">"myAmpState.bar"</span><span class="p">></span>Some placeholder text.<span class="p"></</span><span class="nt">p</span><span class="p">></span> </pre></div> <h3 id="errors">Errors</h3> <p>Below outlines the types of errors that may arise when working with <code>amp-bind</code>.</p> <table> <tbody><tr> <th>Type</th> <th>Message</th> <th>Suggestion</th> </tr> <tr> <td class="col-thirty">Invalid binding</td> <td class="col-fourty"><em>Binding to [foo] on <P> is not allowed</em>.</td> <td class="col-thirty">Use only <a href="#amp-component-specific-attributes">allowlisted bindings</a>.</td> </tr> <tr> <td>Syntax error</td> <td><em>Expression compilation error in...</em></td> <td>Verify the expression for typos.</td> </tr> <tr> <td>Non-allowlisted functions</td> <td><em>alert is not a supported function.</em></td> <td>Use only <a href="#allow-listed-functions">allow-listed functions</a>.</td> </tr> <tr> <td>Sanitized result</td> <td><em>"javascript:alert(1)" is not a valid result for [href].</em></td> <td>Avoid banned URL protocols or expressions that would fail the AMP Validator.</td> </tr> <tr> <td>CSP violation</td> <td><em>Refused to create a worker from 'blob:...' because it violates the following Content Security Policy directive...</em></td> <td>Add <code>default-src blob:</code> to your origin's Content Security Policy. <code>amp-bind</code> delegates expensive work to a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Dedicated_workers">dedicated Web Worker</a> to ensure good performance.</td> </tr> </tbody></table> <h3 id="debugging-state">Debugging State</h3> <p>Use <code>AMP.printState()</code> to print the current state to the console. To make this work, you need to enable the <a href="https://amp.dev/documentation/guides-and-tutorials/learn/validation-workflow/validate_amp/#browser-developer-console">development mode</a>.</p> <h3 id="expression-grammar">Expression grammar</h3> <p>The BNF-like grammar for <code>amp-bind</code> expressions:</p> <div class="-ta"><pre><span></span><code>expr: operation | invocation | member_access | '(' expr ')' | variable | literal ; operation: '!' expr | '-' expr %prec UMINUS | '+' expr %prec UPLUS | expr '+' expr | expr '-' expr | expr '*' expr | expr '/' expr | expr '%' expr | expr '&&' expr | expr '||' expr | expr '<=' expr | expr '<' expr | expr '>=' expr | expr '>' expr | expr '!=' expr | expr '==' expr | expr '?' expr ':' expr ; invocation: NAME args | expr '.' NAME args | expr '.' NAME '(' arrow_function ')' | expr '.' NAME '(' arrow_function ',' expr ')' ; arrow_function: '(' ')' '=>' expr | NAME '=>' expr | '(' params ')' '=>' expr ; params: NAME ',' NAME | params ',' NAME ; args: '(' ')' | '(' array ')' ; member_access: expr member ; member: '.' NAME | '[' expr ']' ; variable: NAME ; literal: primitive | object_literal | array_literal ; primitive: STRING | NUMBER | TRUE | FALSE | NULL ; array_literal: '[' ']' | '[' array ']' | '[' array ',' ']' ; array: expr | array ',' expr ; object_literal: '{' '}' | '{' object '}' | '{' object ',' '}' ; object: key_value | object ',' key_value ; key_value: key ':' expr ; key: NAME | primitive | '[' expr ']' ; </code></pre></div> </section> <section class="ap--help"> <div class="-ff"> <span class="-fl">Need more help?</span> <p class="-fh">You've read this document a dozen times but it doesn't really cover all of your questions? Maybe other people felt the same: reach out to them on Stack Overflow.</p> <a href="https://stackoverflow.com/questions/tagged/amp-html" rel="noopener" class="-n"> <svg class="ap-a-ico -i"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#external"/></svg> <span class="-r">Go to Stack Overflow</span> </a> <div class="-fp"></div> <span class="-fl">Found a bug or missing a feature?</span> <p class="-fh">The AMP project strongly encourages your participation and contributions! We hope you'll become an ongoing participant in our open source community but we also welcome one-off contributions for the issues you're particularly passionate about.</p> <a href="https://github.com/ampproject/amphtml" rel="noopener" class="-n link-preview-1"> <svg class="ap-a-ico -i"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#external"/></svg> <span class="-r">Go to GitHub</span> </a> <div class="-fp"></div> </div> </section> </div> </main> <amp-sidebar id="sidebar-left" class="ap--ampsidebar i-amphtml-layout-nodisplay" layout="nodisplay" side="left" hidden="hidden" i-amphtml-layout="nodisplay"> <nav class="ap--ampsidebar-toolbar" toolbar="(min-width: 768px)" toolbar-target="ap--sidebar-content"> <ul> <div class="ap-m-format-toggle"> <button class="ap-m-format-toggle-selected ap-m-format-toggle-link-websites"> <span class="ap-a-ico"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#amp-websites"/></svg> </span> <span>websites</span> <span class="ap-a-ico ap-m-format-toggle-angle"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#angle-down-solid"/></svg> </span> </button> <div class="ap-m-format-toggle-formats"> <a class="ap-m-format-toggle-link ap-m-format-toggle-link-stories" href="/documentation/components/stories/amp-bind/"> <span class="ap-a-ico"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#amp-stories"/></svg> </span> <span>stories</span> </a> <a class="ap-m-format-toggle-link ap-m-format-toggle-link-ads" href="/documentation/components/ads/amp-bind/"> <span class="ap-a-ico"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#amp-ads"/></svg> </span> <span>ads</span> </a> <a class="ap-m-format-toggle-link ap-m-format-toggle-link-email" href="/documentation/components/email/amp-bind/"> <span class="ap-a-ico"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#amp-email"/></svg> </span> <span>email</span> </a> </div> </div> <div class="ap-o-sidebar-component"> <div class="ap-o-sidebar"> <div class="nav"> <ul class="nav-list level-1"> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">3</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-3d-gltf/">amp-3d-gltf</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-3q-player/">amp-3q-player</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">A</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-access-fewcents/">amp-access-fewcents</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-access-laterpay/">amp-access-laterpay</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-access-poool/">amp-access-poool</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-access-scroll/">amp-access-scroll</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-access/">amp-access</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-accordion/">amp-accordion</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-action-macro/">amp-action-macro</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-ad-exit/">amp-ad-exit</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-ad/">amp-ad</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-addthis/">amp-addthis</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-analytics/">amp-analytics</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-anim/">amp-anim</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-animation/">amp-animation</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-apester-media/">amp-apester-media</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-app-banner/">amp-app-banner</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-audio/">amp-audio</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-auto-ads/">amp-auto-ads</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-autocomplete/">amp-autocomplete</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">B</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-base-carousel/">amp-base-carousel</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-beopinion/">amp-beopinion</a> </li> <li class="nav-item level-2 active" autoscroll> <a class="nav-link" href="/documentation/components/websites/amp-bind/">amp-bind</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-bodymovin-animation/">amp-bodymovin-animation</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-brid-player/">amp-brid-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-brightcove/">amp-brightcove</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-byside-content/">amp-byside-content</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">C</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-call-tracking/">amp-call-tracking</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-carousel/">amp-carousel</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-connatix-player/">amp-connatix-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-consent/">amp-consent</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">D</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-dailymotion/">amp-dailymotion</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-date-countdown/">amp-date-countdown</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-date-display/">amp-date-display</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-date-picker/">amp-date-picker</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-delight-player/">amp-delight-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-dynamic-css-classes/">amp-dynamic-css-classes</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">E</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-embedly-card/">amp-embedly-card</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-experiment/">amp-experiment</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">F</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-facebook-comments/">amp-facebook-comments</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-facebook-like/">amp-facebook-like</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-facebook-page/">amp-facebook-page</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-facebook/">amp-facebook</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-fit-text/">amp-fit-text</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-font/">amp-font</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-form/">amp-form</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-fx-collection/">amp-fx-collection</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-fx-flying-carpet/">amp-fx-flying-carpet</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">G</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-geo/">amp-geo</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-gfycat/">amp-gfycat</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-gist/">amp-gist</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-google-document-embed/">amp-google-document-embed</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-google-read-aloud-player/">amp-google-read-aloud-player</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">H</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-hulu/">amp-hulu</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">I</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-iframe/">amp-iframe</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-iframely/">amp-iframely</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-ima-video/">amp-ima-video</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-image-lightbox/">amp-image-lightbox</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-image-slider/">amp-image-slider</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-img/">amp-img</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-imgur/">amp-imgur</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-inline-gallery/">amp-inline-gallery</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-inputmask/">amp-inputmask</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-instagram/">amp-instagram</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-install-serviceworker/">amp-install-serviceworker</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-izlesene/">amp-izlesene</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">J</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-jwplayer/">amp-jwplayer</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">K</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-kaltura-player/">amp-kaltura-player</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">L</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-layout/">amp-layout</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-lightbox-gallery/">amp-lightbox-gallery</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-lightbox/">amp-lightbox</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-link-rewriter/">amp-link-rewriter</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-list/">amp-list</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-live-list/">amp-live-list</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">M</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-mathml/">amp-mathml</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-mega-menu/">amp-mega-menu</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-megaphone/">amp-megaphone</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-minute-media-player/">amp-minute-media-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-mowplayer/">amp-mowplayer</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-mustache/">amp-mustache</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">N</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-nested-menu/">amp-nested-menu</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-next-page/">amp-next-page</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-nexxtv-player/">amp-nexxtv-player</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">O</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-o2-player/">amp-o2-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-onetap-google/">amp-onetap-google</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-ooyala-player/">amp-ooyala-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-orientation-observer/">amp-orientation-observer</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">P</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-pan-zoom/">amp-pan-zoom</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-pinterest/">amp-pinterest</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-pixel/">amp-pixel</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-playbuzz/">amp-playbuzz</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-position-observer/">amp-position-observer</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-powr-player/">amp-powr-player</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">R</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-reach-player/">amp-reach-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-recaptcha-input/">amp-recaptcha-input</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-reddit/">amp-reddit</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-render/">amp-render</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-riddle-quiz/">amp-riddle-quiz</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">S</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-script/">amp-script</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-selector/">amp-selector</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-sidebar/">amp-sidebar</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-skimlinks/">amp-skimlinks</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-slikeplayer/">amp-slikeplayer</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-smartlinks/">amp-smartlinks</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-social-share/">amp-social-share</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-soundcloud/">amp-soundcloud</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-springboard-player/">amp-springboard-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-sticky-ad/">amp-sticky-ad</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-stream-gallery/">amp-stream-gallery</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-subscriptions-google/">amp-subscriptions-google</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-subscriptions/">amp-subscriptions</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">T</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-tiktok/">amp-tiktok</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-timeago/">amp-timeago</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-truncate-text/">amp-truncate-text</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-twitter/">amp-twitter</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">U</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-user-notification/">amp-user-notification</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">V</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-video-docking/">amp-video-docking</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-video-iframe/">amp-video-iframe</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-video/">amp-video</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-vimeo/">amp-vimeo</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-vine/">amp-vine</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-viqeo-player/">amp-viqeo-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-vk/">amp-vk</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">W</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-web-push/">amp-web-push</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-wistia-player/">amp-wistia-player</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-wordpress-embed/">amp-wordpress-embed</a> </li> </ul> </li> <li class="nav-item level-1"> <ul class="nav-list level-2"> <li class="nav-link">Y</li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-yotpo/">amp-yotpo</a> </li> <li class="nav-item level-2 "> <a class="nav-link" href="/documentation/components/websites/amp-youtube/">amp-youtube</a> </li> </ul> </li> </ul> </div> </div> </div> </ul> </nav> </amp-sidebar> <footer class="ap--footer"> <div class="-a"> <div class="-f"> <div class="ap-o-footer-hint">Of course, this site is made with AMP!</div> <div class="-l"> <h5 class="-c">Follow us</h5> <ul class="-h"> <li class="-p"> <a class="ap-a-ico -d" href="https://twitter.com/AMPhtml" rel="noopener" title="Twitter"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#twitter"/></svg> </a> </li> <li class="-p"> <a class="ap-a-ico -d" href="https://www.youtube.com/channel/UCXPBsjgKKG2HqsKBhWA4uQw" rel="noopener" title="YouTube"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#youtube"/></svg> </a> </li> <li class="-p"> <a class="ap-a-ico -d" href="https://blog.amp.dev/" rel="noopener"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#wordpress" title="WordPress"/></svg> </a> </li> <li class="-p"> <a class="ap-a-ico -d" href="https://github.com/ampproject" title="GitHub"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#github"/></svg> </a></li> <li class="-p"> <a class="ap-a-ico -d" href="https://stackoverflow.com/questions/tagged/amp-html" rel="noopener" title="Stackoverflow"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#stackoverflow"/></svg></a> </li> </ul> </div> </div> <div class="-v"> <div class="-m"> <h5 class="-g">Overview</h5> <ul class="-y"> <li class="-b"><a href="/about/websites/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>AMP Framework</a></li> <li class="-b"><a href="/about/use-cases/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Use Cases</a></li> <li class="-b"><a href="/success-stories/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Success stories</a></li> <li class="-b"><a href="/about/how-amp-works/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Functionality</a></li> </ul> </div> <div class="-m"> <h5 class="-g">Docs</h5> <ul class="-y"> <li class="-b"><a href="/documentation/guides-and-tutorials/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Get Started</a></li> <li class="-b"><a href="/documentation/guides-and-tutorials/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Guides and Tutorials</a></li> <li class="-b"><a href="/documentation/components/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Components</a></li> <li class="-b"><a href="/documentation/examples/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Examples</a></li> <li class="-b"><a href="/documentation/templates/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Design Templates</a></li> <li class="-b"><a href="/documentation/tools/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Tools</a></li> </ul> </div> <div class="-m"> <h5 class="-g">Community</h5> <ul class="-y"> <li class="-b"><a href="/support/faq/platform-and-vendor-partners/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Platform and Vendor Partners</a></li> <li class="-b"><a href="/documentation/guides-and-tutorials/contribute/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Contribute</a></li> <li class="-b"><a href="/community/roadmap/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Roadmap</a></li> </ul> <h5 class="-g">OpenJS Foundation</h5> <ul class="-y"> <li class="-b"><a class="-w" href="https://openjsf.org" rel="noopener"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>The OpenJS Foundation</a></li> <li class="-b"><a class="-w" href="https://bylaws.openjsf.org" rel="noopener"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>OpenJS Foundation Bylaws</a></li> <li class="-b"><a class="-w" href="https://trademark-policy.openjsf.org" rel="noopener"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Trademark Policy</a></li> <li class="-b"><a class="-w" href="https://trademark-list.openjsf.org" rel="noopener"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>Trademark List</a></li> </ul> </div> <div class="-m"> <h5 class="-g">Events</h5> <ul class="-y"> <li class="-b"><a href="https://blog.amp.dev/2020/02/20/amp-conf-2020-return-to-nyc/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>AMP Conf 2020</a></li> <li class="-b"><a href="/events/amp-cs-2019/" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#internal"/></svg></div>AMP Contributor Summit 2019</a></li> </ul> <h5 class="-g">AMP Brand Materials</h5> <ul class="-y"> <li class="-b"><a href="/static/files/brand-material/AMP_Mini_Styleguide.pdf" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#download"/></svg></div>Styleguide</a></li> <li class="-b"><a href="/static/files/brand-material/AMP_Logo_Rebrush.zip" class="-w"><div class="ap-a-ico -x"><svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#download"/></svg></div>Logos</a></li> </ul> </div> </div> <div class="-k"> <div class="-_"> <amp-img src="/static/img/logo-openjsf.svg" alt="Logo of the OpenJS Foundation" width="315" height="100" layout="responsive" class="i-amphtml-layout-responsive i-amphtml-layout-size-defined" i-amphtml-layout="responsive"><i-amphtml-sizer slot="i-amphtml-svc" style="display:block;padding-top:31.746%"></i-amphtml-sizer></amp-img> </div> <ul class="-j"> <li class="-q"><a class="-z" href="https://terms-of-use.openjsf.org" rel="noopener">Terms of Use</a></li> <li class="-q"><a class="-z" href="https://privacy-policy.openjsf.org" rel="noopener">Privacy Policy</a></li> <li class="-q"><a class="-z" href="https://www.linuxfoundation.org/cookies" rel="noopener">Cookie Policy</a></li> </ul> </div> <div class="-te"> © <a href="https://openjsf.org">OpenJS Foundation</a> and AMP Project contributors. All rights reserved. The <a href="https://openjsf.org">OpenJS Foundation</a> has registered trademarks and uses trademarks. For a list of trademarks of the <a href="https://openjsf.org">OpenJS Foundation</a>, please see our <a href="https://trademark-policy.openjsf.org">Trademark Policy</a> and <a href="https://trademark-list.openjsf.org">Trademark List</a>. Trademarks and logos not indicated on the <a href="https://trademark-list.openjsf.org">list of OpenJS Foundation trademarks</a> are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them. <br><br> The services available at <a href="https://cdn.ampproject.org">cdn.ampproject.org</a> are provided by Google and the respective <a href="https://policies.google.com/privacy?hl=en">privacy policy</a> applies. </div> </div> </footer> <amp-analytics type="gtag" data-credentials="include" data-block-on-consent class="i-amphtml-layout-fixed i-amphtml-layout-size-defined" style="width:1px;height:1px;" i-amphtml-layout="fixed"> <script type="application/json">{"extraUrlParams":{"cd2":"${ampdocHost}"},"requests":{"CWV_EVENT":"${base}?v=1\u0026t=event\u0026tid=${gtag_id}\u0026cid=0\u0026ec=cwv","base":"https://google-analytics.com/collect/"},"triggers":{"banner":{"on":"click","selector":"#top-banner","vars":{"event_action":"click","event_category":"components","event_label":"banner","event_name":"banner"}},"breadcrumbLink":{"on":"click","selector":".ap-m-breadcrumbs-crumb","vars":{"event_action":"link","event_category":"components","event_label":"breadcrumbs","event_name":"breadcrumbs"}},"cls":{"extraUrlParams":{"cls":"${cumulativeLayoutShift}"},"on":"visible","request":"CWV_EVENT"},"defaultPageview":{"on":"visible","request":"pageview","vars":{"title":"{{title}}"}},"fid":{"extraUrlParams":{"fid":"${firstInputDelay}"},"on":"visible","request":"CWV_EVENT"},"formatToggle":{"on":"click","selector":".ap-m-format-toggle-link","vars":{"event_action":"link","event_category":"components","event_label":"format-toggle","event_name":"format-toggle"}},"lcp":{"extraUrlParams":{"lcp":"${largestContentfulPaint}"},"on":"visible","request":"CWV_EVENT"},"navigation":{"on":"click","selector":".ap--header a, .ap-o-burger-menu-link","vars":{"event_action":"link","event_category":"components","event_label":"navigation","event_name":"navigation"}},"scrolledEnd":{"on":"scroll","scrollSpec":{"verticalBoundaries":[90]},"vars":{"event_action":"end","event_category":"components","event_label":"scroll","event_name":"scroll"}},"scrolledHalf":{"on":"scroll","scrollSpec":{"verticalBoundaries":[50]},"vars":{"event_action":"half","event_category":"components","event_label":"scroll","event_name":"scroll"}},"searchButton":{"on":"click","selector":"#searchTriggerOpen","vars":{"event_action":"open","event_category":"search","event_label":"search","event_name":"search"}},"sidebarLink":{"on":"click","selector":".ap-o-sidebar a","vars":{"event_action":"link","event_category":"components","event_label":"sidebar","event_name":"sidebar"}},"sidebarToggle":{"on":"click","selector":"label[for=\"sidebar-desktop\"], label[for=\"sidebar\"]","vars":{"event_action":"toggle","event_category":"components","event_label":"sidebar","event_name":"sidebar"}},"tocLink":{"on":"click","selector":".ap-o-toc a","vars":{"event_action":"link","event_category":"components","event_label":"toc","event_name":"toc"}},"tocToggle":{"on":"click","selector":".ap-o-toc label","vars":{"event_action":"toggle","event_category":"components","event_label":"toc","event_name":"toc"}}},"vars":{"config":{"G-TYM9BH1XCX":{"groups":"default"}},"gtag_id":"G-TYM9BH1XCX"}}</script> </amp-analytics><amp-geo layout="nodisplay" class="i-amphtml-layout-nodisplay" hidden="hidden" i-amphtml-layout="nodisplay"> <script type="application/json">{"ISOCountryGroups":{"eu":["preset-eea"],"doubleOptIn":["de","at","no","gr","lu"]}}</script> </amp-geo> <amp-consent id="consent" class="-o i-amphtml-layout-nodisplay" layout="nodisplay" hidden="hidden" i-amphtml-layout="nodisplay"> <script type="application/json">{"consentInstanceId":"consent","promptUI":"consent-popup","consentRequired":false,"geoOverride":{"eu":{"consentRequired":true}}}</script> <div id="consent-popup" class="consent-popup"> <button type="reset" class="-u" on="tap:consent.dismiss" role="button" tabindex="0" aria-label="Dismiss consent"> <svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#close"/></svg> </button> <p class="ap-o-consent-text"> We use cookies to understand how you use our site and to improve your experience. By continuing to use our site, you accept our <a href="https://policies.google.com/technologies/cookies">use of cookies</a> and <a href="https://policies.google.com/privacy">privacy policy</a>. </p> <button on="tap:consent.accept" class="ap-a-btn" role="button" aria-label="Accept use of cookies">Got it!</button> </div> </amp-consent> <amp-install-serviceworker src="/serviceworker.js" data-iframe-src="https://amp.dev/serviceworker.html" layout="nodisplay" class="i-amphtml-layout-nodisplay" hidden="hidden" i-amphtml-layout="nodisplay"></amp-install-serviceworker> <style amp-keyframes>@keyframes duepduep{0%{transform:translate(0)}49%{transform:translate(40px)}50%{transform:translate(-40px)}to{transform:translate(0)}}@keyframes moveSidebarToggleBackwards{0%{transform:translateX(calc(90vw - 50%))}to{transform:translateX(0)}}@keyframes moveSidebarToggleForwards{0%{transform:translateX(0)}to{transform:translateX(calc(90vw - 50%))}}@keyframes collapse{0%{transform:scale(1)}to{transform:scale(0)}}@keyframes expand{0%{transform:scale(0)}to{transform:scale(1)}}</style></body></html>