Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using it's URL and the proper URL extention.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>BoosterTheme 6&period;0&period;0 - Developer documentation &lpar;WIP&rpar;</title>
        <style>
/* From extension vscode.markdown-math */
@font-face{font-family:KaTeX_AMS;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Caligraphic;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Caligraphic;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Fraktur;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Fraktur;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype");font-weight:700;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Math;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype");font-weight:700;font-style:italic}@font-face{font-family:KaTeX_Math;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype");font-weight:700;font-style:normal}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype");font-weight:400;font-style:italic}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Script;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size1;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size2;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size3;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size4;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Typewriter;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype");font-weight:400;font-style:normal}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto;border-color:currentColor}.katex *{-ms-high-contrast-adjust:none!important}.katex .katex-version:after{content:"0.13.0"}.katex .katex-mathml{position:absolute;clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-weight:700;font-style:italic}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{display:inline-table;table-layout:fixed;border-collapse:collapse}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;vertical-align:bottom;position:relative}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;vertical-align:bottom;font-size:1px;width:2px;min-width:2px}.katex .vbox{display:inline-flex;flex-direction:column;align-items:baseline}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{width:0;max-width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{width:0;position:relative}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{display:inline-block;border:0 solid;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline{display:inline-block;width:100%;border-bottom-style:dashed}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{display:block;position:absolute;width:100%;height:inherit;fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex svg path{stroke:none}.katex img{border-style:none;min-width:0;min-height:0;max-width:none;max-height:none}.katex .stretchy{width:100%;display:block;position:relative;overflow:hidden}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{width:100%;position:relative;overflow:hidden}.katex .halfarrow-left{position:absolute;left:0;width:50.2%;overflow:hidden}.katex .halfarrow-right{position:absolute;right:0;width:50.2%;overflow:hidden}.katex .brace-left{position:absolute;left:0;width:25.1%;overflow:hidden}.katex .brace-center{position:absolute;left:25%;width:50%;overflow:hidden}.katex .brace-right{position:absolute;right:0;width:25.1%;overflow:hidden}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{box-sizing:border-box;border:.04em solid}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{box-sizing:border-content;border-top:.049em solid;border-right:.049em solid;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{counter-increment:katexEqnNo;content:"(" counter(katexEqnNo) ")"}.katex .mml-eqn-num:before{counter-increment:mmlEqnNo;content:"(" counter(mmlEqnNo) ")"}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;position:absolute;left:calc(50% + .3em);text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{text-align:left;padding-left:2em}body{counter-reset:katexEqnNo mmlEqnNo}

/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

.katex-error {
	color: var(--vscode-editorError-foreground);
}

</style>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.css" integrity="sha384-yFRtMMDnQtDRO8rLpMIKrtPCD5jdktao2TV19YiZYWMDkUR5GQZR/NOVTdquEx1j" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.css" rel="stylesheet" type="text/css">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/markdown.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/highlight.css">
<style>
            body {
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif;
                font-size: 14px;
                line-height: 1.6;
            }
        </style>
        <style>
.task-list-item { list-style-type: none; } .task-list-item-checkbox { margin-left: -20px; vertical-align: middle; }
</style>
        
        <script src="https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.js"></script>
        
    </head>
    <body class="vscode-body vscode-light">
        <h1 id="boostertheme-600---developer-documentation-wip">BoosterTheme 6.0.0 - Developer documentation (WIP)</h1>
<p>We've listened to your requests, we've talked to developers, and we completely agree - Booster needs more <strong>compatibility and extendability</strong>.<br>
Those 2 things are on of the main focuses of Booster 6.</p>
<p>To learn more about Booster 6.0 check out <a href="">this article</a> (not yet published).</p>
<p>TLDR;</p>
<ul>
<li>Booster's Javascript has been rewritten from the ground up, focusing on plug'n'play for 3rd party devs</li>
<li>Major overhaul of code has been done, with incremental adjustments and improvements, to reduce the amount of clutter and confusion</li>
<li>100% compatibility with Online Store 2.0 (keyword: Sections on ALL pages)</li>
</ul>
<br>
<p><a href="#booster-and-custom-code">&gt; Skip to developer documentation and references</a></p>
<p><a href="#introducing-booster-events-boosterthemeevents">&gt; Skip to event definitions</a></p>
<p><a href="#boostertheme-methods">&gt; Skip to method definitions</a></p>
<br>
<h2 id="shopify-development-done-the-booster-way">Shopify development done the &quot;Booster&quot; way</h2>
<h3 id="brief-history-of-boosterd-liquid">Brief history of Booster'd Liquid</h3>
<p>Our development strategy was not moulded by Shopify, but rather &quot;against&quot; it.<br>
We come from different (web) development backgrounds, whether it's backend development, frontend, old school PHP templating or React and serverless.<br>
We're used to having freedom, offloading heavy tasks to the backend and trying to keep everything as vanilla as possible.<br>
When we began building on Shopify, we realized that's not the norm when it comes to Shopify.</p>
<p>Even though we've worked with dozens of different CMS', we never imagined for a new and fresh CMS with a clear niche, such as Shopify, to be plagued by that many obsolete Javascript and heavy plugins and apps.<br>
Our goal for Booster 5 was clear. We want it to be <strong>lean, fast, responsive and different</strong>.</p>
<br>
<p>Main differences compared to other themes:</p>
<ul>
<li>Relying on native browser functionality, eliminating polyfills, jQuery and other dependencies aimed at (mostly) IE</li>
<li>Offload as much computing to Shopify (we've been creating our own JSON to consume, as well as generating HTML on the backend, just injecting it when needed)</li>
<li>Vanilla Javascript executed only when needed</li>
<li>Modern solutions to (not so modern) problems</li>
<li>Execution time measured in miliseconds, blocking time as close to 0 as possible (~1ms)</li>
<li>Regular updates with user requests, ready to move with the industry, but also be ahead of it at any time</li>
</ul>
<br>
<p>Achieving the above was far from easy and included things like:</p>
<ul>
<li>A custom backend server that minifies and combines assets <strong>on the fly</strong></li>
<li>A custom file template format used internally to achieve <strong>TRUE DRY</strong> methodology when building in Liquid</li>
<li>A custom SCSS parser</li>
<li>Rethinking the way Liquid does things</li>
<li>Rethinking theme and file architecture</li>
</ul>
<br>
<p>Initial release of Booster 5 and its 5.0.x series produced results. It was not perfect, there was (and still is) room for improvement, but comparing it against other &quot;big players&quot; and even Shopify themselves - we knew that we were on the right track.<br>
Booster's 5.1.x series brought more polish and less bugs, we've introduced more &quot;native&quot; approaches to handling product forms, but issues with 3rd party apps and developers were always there.<br>
Even though we've tried reaching out to developers, it was pretty clear, everyone just wants to plug in their script, overwrite whatever Javascript the theme was using and do it their own way.<br>
<strong>Developers were looking to do it the bruteforce way, instead of doing their things alongside the theme.</strong></p>
<p>&quot;No other theme does it this way&quot; - that one sentence was our greatest defeat.<br>
Even though we were producing results, providing support, customizations, speeds and flexibility yet unseen in the Shopify ecosystem, just because it wasn't done the &quot;old&quot; way, it's been decided that it's the wrong way.<br>
That one sentence alone was enough for us to go back to the drawing board and find a way of making it work, for both us and 3rd party developers.</p>
<h3 id="booster-6-and-os20">Booster 6 and OS2.0</h3>
<p>Booster 6.0.0 was in development way before Shopify decided to drop the bombshell that is Online Store 2.0, but seeing the announcement gave us a really unique possibility.<br>
Online Store 2.0 (OS2.0) brought JSON templates, Dawn (Shopify's Open Source theme) and their new goal when it comes to development.<br>
Usually those would be bad news for a well established theme whose codebase thousands of customers rely on, but in this case it gave us a <strong>big advantage</strong>.</p>
<p>Online Store 2.0 was aligned with Booster's <strong>new file architecture</strong>.<br>
JSON templates mean no more code in templates - That's exactly what we've done with Booster 5.x<br>
Our templates were containing sections, nothing more, nothing else.<br>
Online Store 2.0, messages that Shopify provided with its announcement and everything accompanying Unite 2021 proved that we're on the right track.<br>
Converting our entire theme to Online Store 2.0 was done in <strong>a single day</strong>.<br>
We could continue working on Booster 6.0 whilst having the advantage of being fully OS2.0 compatible, without investing additional man-hours in the entire project.</p>
<h3 id="booster-6-and-developers">Booster 6 and developers</h3>
<p>That brings us to our biggest change in Booster 6.0.<br>
Many might think it's all the new features announced, all the bug fixes, cleaned up code, but in reality it's some of the things they can't see.<br>
It's the new architecture put in place to provide quick updates to our code as well as an easy way to <strong>provide access points for 3rd party developers</strong>.</p>
<p><br><br></p>
<h2 id="booster-and-custom-code">Booster and Custom Code</h2>
<p>Our main entry point for custom code used to be &quot;Advanced HTML &amp; CSS&quot; settings part of our theme.<br>
This way, you could write code inside the editor, have it refresh with your new changes, but also make sure all of your changes were brought over to the new versions after update - without conflicts.<br>
As much as we loved this, we quickly realized it's not enough, especially not for heavily customized themes.</p>
<p>Booster 6.0 brings new ways of adding code that <strong>will be preserved after updates</strong>:</p>
<p><strong>layout__ snippets</strong><br>
Booster now comes with 2 new snippets that will <strong>always be moved over to the updated theme</strong>, those are <em>layout__custom-code--body.liquid</em> and <em>layout__custom-code--head.liquid</em>.<br>
Code that's written inside these will be moved over to the updated themes with <em>no question asked</em> policy.<br>
It will always be there.<br>
(<em>We are looking for other places to include this policy and snippets in, do let us know if you have suggestions</em>)</p>
<p><strong>Page, App, HTML &amp; Liquid blocks</strong><br>
Booster 6.0 comes with 4 new block types.<br>
Custom HTML &amp; Custom Liquid blocks - which serve the obvious purpose of inserting custom HTML &amp; Liquid code inside selected sections.<br>
App blocks - which are a part of OS2.0 and allow apps to include their code without worrying about leftover code and injecting Javascript.<br>
Page blocks - you can now insert unescped content of entire pages, if you wish to do so, inside a select number of sections. This allows you to take advantage of Shopify's WYSIWYG combined with the usual way of editing and building our sections.</p>
<p><strong>Section-based code settings</strong><br>
New fields and inputs inside sections and blocks. Mostly targeted at CSS. Read below for more information.</p>
<p><strong>Third party liquids</strong><br>
As was the case before, any <em>unofficial</em> liquid files and assets will get <strong>moved automatically</strong> to the new updated theme.</p>
<p><strong>Settings</strong><br>
Advanced HTML &amp; CSS settings will <strong>not be removed</strong> and will stay as a part of instantly movable code, especially used for things like marketing pixels and different tags.</p>
<p><em>We are looking to expand support and &quot;no questions asked&quot; policy to other parts of our theme, for a more seamless approach to updates for heavily customized sites</em></p>
<p><br><br></p>
<h2 id="booster-and-css">Booster and CSS</h2>
<p>Booster 6.0.x series has polishing and improvement of CX (customer experience) as one of its main goals - coupled with the aforementioned.<br>
This means cleaning up our CSS and adding more polish to transitions and experience.<br>
We've made sure to accommodate for any custom CSS modifications done to sections, and for that reason we've included &quot;<strong>Section Scoped CSS</strong>&quot;.</p>
<p>Section Scoped CSS is a new field found in <em>most</em> (bringing it to <em>all</em> sections soon!) Booster sections which allowes you to write CSS directly inside section's settings.<br>
This means - automatic updates and less back and forth between your IDE, Shopify's editor, and most importantly - live updates.<br>
Section Scoped CSS brings another major perk and that's a custom CSS identifier &quot;##scoped&quot;.<br>
Using &quot;##scoped&quot; as an identified will make sure CSS gets applied to this section and <strong>this section only</strong>.<br>
This keyword dynamically gets replaced with the sections unique identifier.</p>
<p>Example of ##scoped usage</p>
<pre><code>// all h1 tags on the page will turn red (unless they have a more specific rule on them)  
h1 {  
    color: red;  
}  

// only the h1 tags contained in *the section this is written for* will turn red  
##scoped h1 {  
    color: red;  
}  

// you should treat ##scoped like you would any other identified  
##scoped &gt; div, ##scoped::after, ##scoped:hover {  
    ... you get the idea  
}  
</code></pre>
<p><br><br></p>
<h2 id="booster-and-javascript---the-new-structure-and-the-lack-of-it">Booster and Javascript - The new structure (and the lack of it?)</h2>
<p>Your prayers have not gone unnoticed.<br>
We've made sure to go to the <em>other extreme</em> and write our entire Javascript as if they were separate components, finding unique ways to make things work together and talk to each other.</p>
<p>We are not fans of unused code and are HUGE fans of DRY.<br>
This means Booster no longer loads app Javascript that will not be used, but also means that all of our modules are completely separated from the final file.</p>
<p><em>When referring to &quot;internal&quot; methods, that's our way of saying they are Booster specific. They are to be used by everyone</em></p>
<p>The architecture we decided on was <strong>&quot;modules&quot; + Init</strong>.<br>
Every module of ours is versioned independently of another, with the main goal of being able to provide LTS (long-term support) for people who have decided not to update for one reason or another.<br>
<strong>Modules</strong> is just a fancy way for us to address ES6 Classes.<br>
<strong>Init</strong> is the main class which brings them all together.</p>
<br>
<h3 id="3-booster-constants-you-must-not-override">3 Booster constants you MUST NOT override</h3>
<p>We have a total of 3 variables used for our theme and those are.</p>
<ul>
<li><strong>bstr_modules</strong> - an array of modules to be loaded, dynamically adding modules necessary for apps to run if they are enabled</li>
<li><strong>bstore</strong> - a custom LocalStorage wrapper which adds utility (such as auto parsing of JSON and default returns), as well as expiry and &quot;data origin verification&quot;</li>
<li><strong>BoosterTheme</strong> - main Init Class containing all of Booster's modules</li>
</ul>
<br>
<h3 id="booster-plugins-wip">Booster Plugins (WIP)</h3>
<p>We are working on an easier for you to include additional scripts to Booster's Init Class, complete with versioning and dependencies.<br>
This will allow you to await for certain modules to be loaded and executed, as well as make sure everything is ready for your script to run - before it does.<br>
Check back for more information in future updates. No ETA.</p>
<br>
<h3 id="introducing-booster-events-boosterthemeevents">Introducing Booster Events (BoosterTheme.events)</h3>
<p>Booster Events is our way of reaching out to developers and providing a more streamlined way of communicating and modify the results of our Javascript.<br>
Booster Events is a wrapper around the way we've been listening and dispatching events internally (BstrEvents) as well as DOM CustomEvents.<br>
<strong>Booster Events is the main and only way our modules talk to eachother</strong> - We eat our own food around here</p>
<br>
<h4 id="boosterthemeevents">BoosterTheme.events</h4>
<p>This class provides 2 external methods:</p>
<ul>
<li>BoosterTheme.events.on(event, callback) - used to bind to events</li>
<li>BoosterTheme.events.trigger(event, params, log = false) - used to trigger events, if logged, functions binding to this event will get called with the last logged set of params on bind. Feel free to use it for any purposes you deem necessary. Dispatches a CustomEvent on 'document' and calls all of internally bound functions.</li>
</ul>
<br>
<h4 id="binding-to-booster-events">Binding to Booster Events</h4>
<p>All Booster events are dispatched in 2 ways (except for 'booster:initialized' which is DOM only).<br>
You can listen to them on the document using the usual <strong>addEventListener</strong></p>
<pre><code>// params available inside event.detail  
document.addEventListener(event, callback)  
</code></pre>
<p>or by using our <strong>internal event callback</strong></p>
<pre><code>// params are the main prop that's passed to callback  
BoosterTheme.events.on(event, callback)  
</code></pre>
<p>The only advantage of using BoosterTheme.events is our internal logging.<br>
Since not all code is executed at the some moment, some of our events are logged, so if they get executed before your script gets a chance to bind to it, your callback will be executed with the last known set of params logged.<br>
This way you can make sure that your code is up to date with current on-site data without doing additional ready-checks.</p>
<p>All of our events are namespaced.</p>
<pre><code>'booster:[module]:[action]'
</code></pre>
<br>
<h4 id="preventing-events-boostermodulebaction">Preventing events (booster:[module]:b*[action])</h4>
<p>Not all Booster events can be prevented. Only those whose action begins with :b* can. (booster:[module]:b*[action])<br>
Events can be prevented in 2 ways:</p>
<ul>
<li>By returning &quot;false&quot; (Boolean) - if bound to BoosterTheme.events</li>
<li>Calling event.preventDefault() - if bound to DOM events</li>
</ul>
<p><em>We are taking suggestions for events, both preventable and not, we are able to add them without you needing to update the theme.</em></p>
<br>
<br>
<h3 id="main-init--loaded-events">Main (Init &amp; Loaded) events</h3>
<br>
<h4 id="main-event-dom---boosterinitialized"><strong>Main event (DOM) - 'booster:initialized'</strong></h4>
<p>'booster:initialized' is the <strong>only</strong> DOM-specific event that you can't listen to via our internal event callbacks for obvious reasons - it is dispatched right after our events callback is initialized.<br>
If BoosterTheme is not available at the time of your scripts execution - use this event to bind to access our internal methods, if you need them.</p>
<p>Params</p>
<pre><code>BoosterTheme: main Init instance containing the rest of Booster code  
</code></pre>
<p>Called</p>
<pre><code>Right after BoosterEvents is initialized, before the rest of code is executed ('booster:loaded' for the latter)  
</code></pre>
<h4 id="fully-loaded---boosterloaded"><strong>Fully loaded - 'booster:loaded'</strong></h4>
<p>Params</p>
<pre><code>BoosterTheme: main Init instance  
</code></pre>
<p>Called</p>
<pre><code>After all of modules have been loaded and initialized  
</code></pre>
<br>
<br>
<h3 id="cart-events---boostercartaction">Cart events - booster:cart:[action]</h3>
<br>
<h4 id="minicart-update---boostercartupdate"><strong>Minicart update - 'booster:cart:update'</strong></h4>
<p>BoosterTheme binds to LocalStorage events as well as XHR and Fetch requests to keep the cart sync'd and updated no matter who makes the change - <strong>even across windows and tabs</strong>.</p>
<p>Params (logged)</p>
<pre><code>lastUpdate: Date.now() of when the cart was last updated  
data:  
    html: Minicart's HTML  
    item_count: number of items in the cart  
    items: (variant_id:value pairs)   
        variant_id  
            quantity: number of items with this specific variant id  
            info: additional item metadata, JSON'd Liquid ProductDrop (call the event with console.log for more information)  
                ProductDrop | json  
    total: price-formatted total amount in cart  
    total_raw: raw total provided by Shopify, before formatting ($1.00 -&gt; 100)  
initial: (planned parameter, defaults to undefiend) whether it's an initial cart load  
</code></pre>
<p>Called</p>
<pre><code>On cart update - including the initial load of minicart when the page loads.  
</code></pre>
<h4 id="before-adding---boostercartbadd"><strong>Before adding - 'booster:cart:b*add'</strong></h4>
<p>Params</p>
<pre><code>form (or json): form that the AddCartEvent is being called on  
json (or form): JSON that's being used for this AddCartEvent (default Shopify /cart/add.js body)  
target (optional): target (DomElement) that initialized the event  
</code></pre>
<p>Called</p>
<pre><code>Before adding (an) item(s) to cart for the purposes of preventing if needed be.  
</code></pre>
<h4 id="added-to-cart---boostercartadd"><strong>Added to cart - 'booster:cart:add'</strong></h4>
<p>Params</p>
<pre><code>(Same as :b*add)  
</code></pre>
<p>Called</p>
<pre><code>After an items has been successfully processed and added to cart.  
</code></pre>
<h4 id="before-a-modal-is-shown---boostercartbmodal"><strong>Before a modal is shown - 'booster:cart:b*modal'</strong></h4>
<p>Params</p>
<pre><code>item: that a modal is about to be generated for  
cart: current minicart state (check booster:cart:update)  
will_upsell: whether an upsell modal is about to be generated  
</code></pre>
<p>Called</p>
<pre><code>For the purposes of preventing the Booster Success modal to be generated.  
</code></pre>
<h4 id="before-an-upsell-is-shown---boostercartbupsell"><strong>Before an upsell is shown - 'booster:cart:b*upsell'</strong></h4>
<p>Params:</p>
<pre><code>item: (same as above)  
cart: (same as above)  
</code></pre>
<p>Called</p>
<pre><code>For the purposes of preventing native Booster Upsell modal  
</code></pre>
<h4 id="after-an-upsell-is-shown---boostercartupsell"><strong>After an upsell is shown - 'booster:cart:upsell'</strong></h4>
<p>Params:</p>
<pre><code>item: (same as b*upsell)  
cart: (same as b*upsell)  
html: upsell container  
items: (planned parameter, currently defaults to false) a list of items that are being shown  
</code></pre>
<p>Called</p>
<pre><code>After the upsell has been shown.  
</code></pre>
<h4 id="cart-cleared---boostercartclear"><strong>Cart cleared - 'booster:cart:clear'</strong></h4>
<p>Params</p>
<pre><code>none  
</code></pre>
<p>Called</p>
<pre><code>After a cart has been cleared with BoosterTheme.cart.clear()  
In the future it will be called when /cart/clear.js is requested  
</code></pre>
<br>
<br>
<h3 id="swatch-events---boosterswatchaction">Swatch events - booster:swatch:[action]</h3>
<br>
<h4 id="swatch-selected---boosterswatchselect"><strong>Swatch selected - 'booster:swatch:select'</strong></h4>
<p>Params</p>
<pre><code>{
    selectedVariant{},
    currentOptions[],
    product:{id, variants}
}
</code></pre>
<p>Called</p>
<pre><code>After swatches have been selected in such a way that it matches a (valid) product variant
</code></pre>
<h4 id="swatch-updated---boosterswatchupdate"><strong>Swatch updated - 'booster:swatch:update'</strong></h4>
<p>Params</p>
<pre><code>{
    selectedVariant{}||false,
    currentOptions[],
    product:{id, variants}
}
</code></pre>
<p>Called</p>
<pre><code>After swatch selection has been updated, whether or not it results in a matching variant. selectedVariant can be set to false.
</code></pre>
<h4 id="swatch-deselected---boosterswatchdeselect"><strong>Swatch deselected - 'booster:swatch:deselect'</strong></h4>
<p>Params</p>
<pre><code>{
    oldVariant{},
    currentOptions[],
    product:{id, variants}
}
</code></pre>
<p>Called</p>
<pre><code>After swatches have been changed/selected in a way that doesn't match a valid variant, while there was a previous variant selected.
</code></pre>
<h4 id="swatch-rendered---boosterswatchrender"><strong>Swatch rendered - 'booster:swatch:render'</strong></h4>
<p>Params</p>
<pre><code>{
    pid,
    options,
    aOptions
}
</code></pre>
<p>Called</p>
<pre><code>After a swatch change has been done. Filters out and renders swatches based on current options. Including active, deselected and unavailable.
</code></pre>
<br>
<br>
<h3 id="dom-events">DOM events</h3>
<br>
<h4 id="html-content-added-or-reloaded---boostercontentupdate"><strong>HTML content added or reloaded - 'booster:content:update'</strong></h4>
<p>Params</p>
<pre><code>trigger(optional): module that added HTML  
</code></pre>
<p>Called</p>
<pre><code>When HTML is added by Booster modules or reloaded.  
</code></pre>
<br>
<h3 id="geo-visitor">GEO Visitor</h3>
<p>Booster comes with a visitor module which loads basic information to be used inside Booster's location-based modules.</p>
<br>
<h4 id="visitor-loaded---boostergeovisitor"><strong>Visitor loaded - 'booster:geo:visitor'</strong></h4>
<p>Params (logged)</p>
<pre><code>ip: IP of the current visiting customer  
country:  
    code: ISO country code  
    name: country's international name  
    nativeName: country's native name  
    capital: the capital of this country  
region: region's name  
city:  
    name: city's name  
    zip: city's zip code  
    capital: (boolean) whether or not this city is the capital  
language: (only shows the first found language in multilingual countries)  
    code: ISO language code  
    name: language's name  
    nativeName: language's native name  
currency: (only shows the first found currency in multicurrency countries)  
    code: ISO currency code  
    name: currency's name  
    symbol: currency's symbol ($, €, ...)  
flag:  
    svg: IMGElement with the country's flag  
    emoji: emoji of the country's flag  
</code></pre>
<p>Called</p>
<pre><code>When Visitor information is obtained. Data is cached for a day.  
</code></pre>
<br>
<h4 id="visitor-loading-error---boostergeoerror"><strong>Visitor loading error - 'booster:geo:error'</strong></h4>
<p>Params</p>
<pre><code>none  
</code></pre>
<p>Called</p>
<pre><code>In case an error has occured while trying to get the visitor's information.  
</code></pre>
<br>
<h3 id="these-are-already-a-part-of-the-theme---wip">THESE ARE ALREADY A PART OF THE THEME - WIP!</h3>
<h2 id="more-events-to-be-documented-variants-currency-">More events to be documented (variants, currency ...)</h2>
<br>
<h2 id="boostertheme-methods">BoosterTheme methods</h2>
<h3 id="swatches-boosterthemeswatches">Swatches (BoosterTheme.swatches)</h3>
<ul>
<li>initListeners() - swatch element listeners</li>
<li>getVariants(pid) - get a dictionary of variants for the product id (if the product/its swatch is available on the page), will support products not currently on page in the future via AJAX</li>
<li>getVariant(pid, id) - info about a specific variant</li>
<li>findVariant(pid) - find a variant based on currently selected values</li>
<li>setOption(pid, index, option) - change an option at index to option</li>
<li>setOptions(pid, []options) - set options for a pid based on options array</li>
<li>setProductVariant(pid, id) - set options according to the variant (id)</li>
</ul>
<h3 id="cart-boosterthemecart">Cart (BoosterTheme.cart)</h3>
<ul>
<li>open() - opens the first visible cart element</li>
<li>close() - closes all cart elements</li>
<li>clear() - clears the cart/removes all products</li>
<li>addToCart(event?, form) - can be used on a button or as a separate method, will add to cart based on the form (&lt;form&gt;) that contains respected input elements and their values (based on Shopify's standards)</li>
<li>addtoCartJSON(event?, json) - will add to cart based on Shopify-defined JSON format, eg. {items: [id, quantity]}, more info: <a target="_blank" href="https://shopify.dev/api/ajax/reference/cart">Shopify AJAX reference</a></li>
<li>removeFromCart(target?, id) - will remove selected id from cart</li>
<li>minicart - property containing internal minicart data, use cart event instead, but can be used if necessary</li>
<li>cartSuccessConfig - property containing action and the info surrounding it</li>
</ul>
<h3 id="visitor-boosterthemevisitor">Visitor (BoosterTheme.visitor)</h3>
<ul>
<li>get() - returns current visitor JSON</li>
</ul>
<h3 id="async-boosterthemebasync">Async (BoosterTheme.basync)</h3>
<ul>
<li>load({url, section?, selector?, json?}) - returns a DOM parsed element containing extracted JSON (if set) from a section (if defined), otherwise it's just the parsed DOM, return value {html, parser, json?}</li>
</ul>
<p><br><br></p>
<h2 id="this-list-is-incomplete-and-will-contain-more-information">This list is INCOMPLETE and will contain more information</h2>
<p><br><br></p>
<h2 id="notes-and-feedback">Notes and feedback</h2>
<p>Feedback will be greatly appreciated and we are looking forward to working with developers and making Booster as well as Shopify a more streamlined environment for you to build cool stuff in!</p>

    </body>
    </html>
              
            
!

CSS

              
                
              
            
!

JS

              
                
              
            
!
999px

Console