CINXE.COM
<!doctype html><html lang="en"><head><title data-rh="true">Breaking the code: How did we build our Figma plugin? | by Sai Lakshman | Zeta Design</title><meta data-rh="true" charset="utf-8"/><meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,maximum-scale=1"/><meta data-rh="true" name="theme-color" content="#000000"/><meta data-rh="true" name="twitter:app:name:iphone" content="Medium"/><meta data-rh="true" name="twitter:app:id:iphone" content="828256236"/><meta data-rh="true" property="al:ios:app_name" content="Medium"/><meta data-rh="true" property="al:ios:app_store_id" content="828256236"/><meta data-rh="true" property="al:android:package" content="com.medium.reader"/><meta data-rh="true" property="fb:app_id" content="542599432471018"/><meta data-rh="true" property="og:site_name" content="Medium"/><meta data-rh="true" property="og:type" content="article"/><meta data-rh="true" property="article:published_time" content="2021-06-01T17:56:39.760Z"/><meta data-rh="true" name="title" content="Breaking the code: How did we build our Figma plugin? | by Sai Lakshman | Zeta Design"/><meta data-rh="true" property="og:title" content="Breaking the code: How did we build our Figma plugin?"/><meta data-rh="true" property="al:android:url" content="medium://p/402682bb13cb"/><meta data-rh="true" property="al:ios:url" content="medium://p/402682bb13cb"/><meta data-rh="true" property="al:android:app_name" content="Medium"/><meta data-rh="true" name="description" content="Writing UX copies can be a little frustrating and confusing, and sometimes we are unsure about how to get the right word. To crack the code for the UX copies, we at Zeta Design wanted to build a…"/><meta data-rh="true" property="og:description" content="Learn how Zeta Design built its first Figma plugin."/><meta data-rh="true" property="og:url" content="https://design.zeta.in/breaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb"/><meta data-rh="true" property="al:web:url" content="https://design.zeta.in/breaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb"/><meta data-rh="true" property="og:image" content="https://miro.medium.com/v2/resize:fit:1200/1*Buv9AgzhmtMU6dkKrqZznw.png"/><meta data-rh="true" property="article:author" content="https://medium.com/@sai_lakshman"/><meta data-rh="true" name="author" content="Sai Lakshman"/><meta data-rh="true" name="robots" content="index,noarchive,follow,max-image-preview:large"/><meta data-rh="true" name="referrer" content="unsafe-url"/><meta data-rh="true" property="twitter:title" content="Breaking the code: How did we build our Figma plugin?"/><meta data-rh="true" name="twitter:site" content="@zetaindia"/><meta data-rh="true" name="twitter:app:url:iphone" content="medium://p/402682bb13cb"/><meta data-rh="true" property="twitter:description" content="Learn how Zeta Design built its first Figma plugin."/><meta data-rh="true" name="twitter:image:src" content="https://miro.medium.com/v2/resize:fit:1200/1*Buv9AgzhmtMU6dkKrqZznw.png"/><meta data-rh="true" name="twitter:card" content="summary_large_image"/><meta data-rh="true" name="twitter:label1" content="Reading time"/><meta data-rh="true" name="twitter:data1" content="9 min read"/><link data-rh="true" rel="icon" href="https://miro.medium.com/v2/resize:fill:256:256/1*7FG4sDTdzgBNYQL3onKlXQ.png"/><link data-rh="true" rel="search" type="application/opensearchdescription+xml" title="Medium" href="/osd.xml"/><link data-rh="true" rel="apple-touch-icon" sizes="152x152" href="https://miro.medium.com/v2/resize:fill:304:304/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="120x120" href="https://miro.medium.com/v2/resize:fill:240:240/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="76x76" href="https://miro.medium.com/v2/resize:fill:152:152/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="60x60" href="https://miro.medium.com/v2/resize:fill:120:120/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="mask-icon" href="https://miro.medium.com/v2/resize:fill:1000:1000/7*GAOKVe--MXbEJmV9230oOQ.png" color="#171717"/><link data-rh="true" id="glyph_preload_link" rel="preload" as="style" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" id="glyph_link" rel="stylesheet" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" rel="author" href="https://medium.com/@sai_lakshman"/><link data-rh="true" rel="canonical" href="https://design.zeta.in/breaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb"/><link data-rh="true" rel="alternate" href="android-app://com.medium.reader/https/medium.com/p/402682bb13cb"/><script data-rh="true" type="application/ld+json">{"@context":"http:\u002F\u002Fschema.org","@type":"NewsArticle","image":["https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1200\u002F1*Buv9AgzhmtMU6dkKrqZznw.png"],"url":"https:\u002F\u002Fdesign.zeta.in\u002Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb","dateCreated":"2021-06-01T12:59:37.273Z","datePublished":"2021-06-01T12:59:37.273Z","dateModified":"2022-01-06T15:44:13.491Z","headline":"Breaking the code: How did we build our Figma plugin?","name":"Breaking the code: How did we build our Figma plugin?","description":"Writing UX copies can be a little frustrating and confusing, and sometimes we are unsure about how to get the right word. To crack the code for the UX copies, we at Zeta Design wanted to build a…","identifier":"402682bb13cb","author":{"@type":"Person","name":"Sai Lakshman","url":"https:\u002F\u002Fdesign.zeta.in\u002F@sai_lakshman"},"creator":["Sai Lakshman"],"publisher":{"@type":"Organization","name":"Zeta Design","url":"design.zeta.in","logo":{"@type":"ImageObject","width":300,"height":60,"url":"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:600\u002F1*Vjz4OlxhDF68YL7pwRL-Rg.png"}},"mainEntityOfPage":"https:\u002F\u002Fdesign.zeta.in\u002Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb"}</script><style type="text/css" data-fela-rehydration="552" data-fela-type="STATIC">html{box-sizing:border-box;-webkit-text-size-adjust:100%}*, *:before, *:after{box-sizing:inherit}body{margin:0;padding:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:rgba(0,0,0,0.8);position:relative;min-height:100vh}h1, h2, h3, h4, h5, h6, dl, dd, ol, ul, menu, figure, blockquote, p, pre, form{margin:0}menu, ol, ul{padding:0;list-style:none;list-style-image:none}main{display:block}a{color:inherit;text-decoration:none}a, button, input{-webkit-tap-highlight-color:transparent}img, svg{vertical-align:middle}button{background:transparent;overflow:visible}button, input, optgroup, select, textarea{margin:0}:root{--reach-tabs:1;--reach-menu-button:1}#speechify-root{font-family:Sohne, sans-serif}div[data-popper-reference-hidden="true"]{visibility:hidden;pointer-events:none}.grecaptcha-badge{visibility:hidden} /*XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>*/.hljs {background: #fff;color: black; }/* Gray DOCTYPE selectors like WebKit */ .xml .hljs-meta {color: #c0c0c0; }.hljs-comment, .hljs-quote {color: #007400; }.hljs-tag, .hljs-attribute, .hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-name {color: #aa0d91; }.hljs-variable, .hljs-template-variable {color: #3F6E74; }.hljs-code, .hljs-string, .hljs-meta .hljs-string {color: #c41a16; }.hljs-regexp, .hljs-link {color: #0E0EFF; }.hljs-title, .hljs-symbol, .hljs-bullet, .hljs-number {color: #1c00cf; }.hljs-section, .hljs-meta {color: #643820; }.hljs-title.class_, .hljs-class .hljs-title, .hljs-type, .hljs-built_in, .hljs-params {color: #5c2699; }.hljs-attr {color: #836C28; }.hljs-subst {color: #000; }.hljs-formula {background-color: #eee;font-style: italic; }.hljs-addition {background-color: #baeeba; }.hljs-deletion {background-color: #ffc8bd; }.hljs-selector-id, .hljs-selector-class {color: #9b703f; }.hljs-doctag, .hljs-strong {font-weight: bold; }.hljs-emphasis {font-style: italic; } </style><style type="text/css" data-fela-rehydration="552" data-fela-type="KEYFRAME">@-webkit-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@-moz-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE">.a{font-family:medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.b{font-weight:400}.c{background-color:rgba(255, 255, 255, 1)}.l{display:block}.m{position:sticky}.n{top:0}.o{z-index:500}.p{padding:0 24px}.q{align-items:center}.r{border-bottom:solid 1px #F2F2F2}.y{height:41px}.z{line-height:20px}.ab{display:flex}.ac{height:57px}.ae{flex:1 0 auto}.af{color:inherit}.ag{fill:inherit}.ah{font-size:inherit}.ai{border:inherit}.aj{font-family:inherit}.ak{letter-spacing:inherit}.al{font-weight:inherit}.am{padding:0}.an{margin:0}.ao{cursor:pointer}.ap:disabled{cursor:not-allowed}.aq:disabled{color:#6B6B6B}.ar:disabled{fill:#6B6B6B}.au{width:auto}.av path{fill:#242424}.aw{height:25px}.ax{margin-left:16px}.ay{border:none}.az{border-radius:20px}.ba{width:240px}.bb{background:#F9F9F9}.bc path{fill:#6B6B6B}.be{outline:none}.bf{font-family:sohne, "Helvetica Neue", Helvetica, Arial, sans-serif}.bg{font-size:14px}.bh{width:100%}.bi{padding:10px 20px 10px 0}.bj{background-color:transparent}.bk{color:#242424}.bl::placeholder{color:#6B6B6B}.bm{display:inline-block}.bn{margin-left:12px}.bo{margin-right:12px}.bp{border-radius:4px}.bq{margin-left:24px}.br{height:24px}.bx{background-color:#F9F9F9}.by{border-radius:50%}.bz{height:32px}.ca{width:32px}.cb{justify-content:center}.ch{max-width:680px}.ci{min-width:0}.cj{animation:k1 1.2s ease-in-out infinite}.ck{height:100vh}.cl{margin-bottom:16px}.cm{margin-top:48px}.cn{align-items:flex-start}.co{flex-direction:column}.cp{justify-content:space-between}.cq{margin-bottom:24px}.cw{width:80%}.cx{background-color:#F2F2F2}.dd{height:44px}.de{width:44px}.df{margin:auto 0}.dg{margin-bottom:4px}.dh{height:16px}.di{width:120px}.dj{width:80px}.dp{margin-bottom:8px}.dq{width:96%}.dr{width:98%}.ds{width:81%}.dt{margin-left:8px}.du{color:#6B6B6B}.dv{font-size:13px}.dw{height:100%}.ep{color:#FFFFFF}.eq{fill:#FFFFFF}.er{background:rgba(148, 116, 198, 1)}.es{border-color:rgba(148, 116, 198, 1)}.ew:disabled{cursor:inherit !important}.ex:disabled{opacity:0.3}.ey:disabled:hover{background:rgba(148, 116, 198, 1)}.ez:disabled:hover{border-color:rgba(148, 116, 198, 1)}.fa{border-radius:99em}.fb{border-width:1px}.fc{border-style:solid}.fd{box-sizing:border-box}.fe{text-decoration:none}.ff{text-align:center}.fi{margin-right:32px}.fj{position:relative}.fk{fill:#6B6B6B}.fn{background:transparent}.fo svg{margin-left:4px}.fp svg{fill:#6B6B6B}.fr{box-shadow:inset 0 0 0 1px rgba(0, 0, 0, 0.05)}.fs{position:absolute}.fz{margin:0 24px}.gd{background:rgba(255, 255, 255, 1)}.ge{border:1px solid #F2F2F2}.gf{box-shadow:0 1px 4px #F2F2F2}.gg{max-height:100vh}.gh{overflow-y:auto}.gi{left:0}.gj{top:calc(100vh + 100px)}.gk{bottom:calc(100vh + 100px)}.gl{width:10px}.gm{pointer-events:none}.gn{word-break:break-word}.go{word-wrap:break-word}.gp:after{display:block}.gq:after{content:""}.gr:after{clear:both}.gs{line-height:1.23}.gt{letter-spacing:0}.gu{font-style:normal}.gv{font-weight:700}.ia{align-items:baseline}.ib{width:48px}.ic{height:48px}.id{border:2px solid rgba(255, 255, 255, 1)}.ie{z-index:0}.if{box-shadow:none}.ig{border:1px solid rgba(0, 0, 0, 0.05)}.ih{margin-left:-12px}.ii{width:28px}.ij{height:28px}.ik{z-index:1}.il{width:24px}.im{margin-bottom:2px}.in{flex-wrap:nowrap}.io{font-size:16px}.ip{line-height:24px}.ir{margin:0 8px}.is{display:inline}.it{color:rgba(148, 116, 198, 1)}.iu{fill:rgba(148, 116, 198, 1)}.ix{flex:0 0 auto}.ja{flex-wrap:wrap}.jd{white-space:pre-wrap}.je{margin-right:4px}.jf{overflow:hidden}.jg{max-height:20px}.jh{text-overflow:ellipsis}.ji{display:-webkit-box}.jj{-webkit-line-clamp:1}.jk{-webkit-box-orient:vertical}.jl{word-break:break-all}.jn{padding-left:8px}.jo{padding-right:8px}.kp> *{flex-shrink:0}.kq{overflow-x:scroll}.kr::-webkit-scrollbar{display:none}.ks{scrollbar-width:none}.kt{-ms-overflow-style:none}.ku{width:74px}.kv{flex-direction:row}.kw{z-index:2}.kz{-webkit-user-select:none}.la{border:0}.lb{fill:rgba(117, 117, 117, 1)}.le{outline:0}.lf{user-select:none}.lg> svg{pointer-events:none}.lp{cursor:progress}.lq{opacity:1}.lr{padding:4px 0}.lu{margin-top:0px}.lv{width:16px}.lx{display:inline-flex}.md{max-width:100%}.me{padding:8px 2px}.mf svg{color:#6B6B6B}.mw{line-height:1.58}.mx{letter-spacing:-0.004em}.my{font-family:source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif}.nt{margin-bottom:-0.46em}.nu{font-style:italic}.nv{clear:both}.ob{height:auto}.oc{margin-top:10px}.od{max-width:728px}.oe{margin-left:auto}.of{margin-right:auto}.oi{background:none}.oj{text-decoration:underline}.ok{line-height:1.12}.ol{letter-spacing:-0.022em}.om{font-weight:600}.ph{margin-bottom:-0.28em}.pn{max-width:3360px}.pp{cursor:zoom-in}.pq{z-index:auto}.ps{list-style-type:disc}.pt{margin-left:30px}.pu{padding-left:0px}.qa{max-width:2880px}.qb{line-height:1.18}.qp{margin-bottom:-0.31em}.qq{max-width:1440px}.qr{max-width:1145px}.qs{box-shadow:inset 3px 0 0 0 #242424}.qt{padding-left:23px}.qu{margin-left:-20px}.qv{margin-top:32px}.qw{margin-bottom:14px}.qx{padding-top:24px}.qy{padding-bottom:10px}.qz{background-color:#000000}.ra{height:3px}.rb{width:3px}.rc{margin-right:20px}.rd{max-width:337px}.re{margin-bottom:26px}.rf{margin-top:6px}.rg{margin-top:8px}.rh{margin-right:8px}.ri{padding:8px 16px}.rj{border-radius:100px}.rk{transition:background 300ms ease}.rm{white-space:nowrap}.rn{border-top:none}.rt{height:52px}.ru{max-height:52px}.rv{box-sizing:content-box}.rw{position:static}.ry{max-width:155px}.sj{margin-bottom:48px}.sx{border-radius:2px}.sz{height:64px}.ta{width:64px}.tb{align-self:flex-end}.tc{color:rgba(255, 255, 255, 1)}.td{fill:rgba(255, 255, 255, 1)}.te{background:rgba(25, 25, 25, 1)}.tf{border-color:rgba(25, 25, 25, 1)}.ti:disabled{opacity:0.1}.tj:disabled:hover{background:rgba(25, 25, 25, 1)}.tk:disabled:hover{border-color:rgba(25, 25, 25, 1)}.tl{flex:1 1 auto}.tr{padding-right:4px}.ts{font-weight:500}.tz{margin-top:16px}.ua{height:0px}.ub{border-bottom:solid 1px #E5E5E5}.uc{margin-top:56px}.ud{margin-top:72px}.ue{padding:24px 0}.uf{margin-bottom:0px}.ug{margin-right:16px}.as:hover:not(:disabled){color:rgba(25, 25, 25, 1)}.at:hover:not(:disabled){fill:rgba(25, 25, 25, 1)}.et:hover{background:rgba(126, 101, 166, 1)}.eu:hover{border-color:rgba(126, 101, 166, 1)}.ev:hover{cursor:pointer}.fl:hover{color:#242424}.fm:hover{fill:#242424}.fq:hover svg{fill:#242424}.ft:hover{background-color:rgba(0, 0, 0, 0.1)}.iq:hover{text-decoration:underline}.iv:hover:not(:disabled){color:rgba(126, 101, 166, 1)}.iw:hover:not(:disabled){fill:rgba(126, 101, 166, 1)}.ld:hover{fill:rgba(8, 8, 8, 1)}.ls:hover{fill:#000000}.lt:hover p{color:#000000}.lw:hover{color:#000000}.mg:hover svg{color:#000000}.rl:hover{background-color:#F2F2F2}.sy:hover{background-color:none}.tg:hover{background:#000000}.th:hover{border-color:#242424}.bd:focus-within path{fill:#242424}.lc:focus{fill:rgba(8, 8, 8, 1)}.mh:focus svg{color:#000000}.pr:focus{transform:scale(1.01)}.lh:active{border-style:none}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="all and (min-width: 1080px)">.d{display:none}.bw{width:64px}.cg{margin:0 64px}.cv{height:48px}.dc{margin-bottom:52px}.do{margin-bottom:48px}.ef{font-size:14px}.eg{line-height:20px}.em{font-size:13px}.eo{padding:5px 12px}.fh{display:flex}.fy{margin-bottom:68px}.gc{max-width:680px}.hq{font-size:42px}.hr{margin-top:1.19em}.hs{margin-bottom:32px}.ht{line-height:52px}.hu{letter-spacing:-0.011em}.hz{align-items:center}.kb{border-top:solid 1px #F2F2F2}.kc{border-bottom:solid 1px #F2F2F2}.kd{margin:32px 0 0}.ke{padding:3px 8px}.kn> *{margin-right:24px}.ko> :last-child{margin-right:0}.lo{margin-top:0px}.mc{margin:0}.np{font-size:20px}.nq{margin-top:2.14em}.nr{line-height:32px}.ns{letter-spacing:-0.003em}.oa{margin-top:56px}.pd{font-size:24px}.pe{margin-top:1.95em}.pf{line-height:30px}.pg{letter-spacing:-0.016em}.pm{margin-top:0.94em}.pz{margin-top:1.14em}.qm{margin-top:1.72em}.qn{line-height:24px}.qo{letter-spacing:0}.rs{margin-bottom:88px}.sd{display:inline-block}.si{padding-top:72px}.sk{flex-direction:row}.sn{margin-bottom:0}.so{margin-right:20px}.tm{max-width:500px}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="all and (max-width: 1079.98px)">.e{display:none}.ln{margin-top:0px}.og{margin-left:auto}.oh{text-align:center}.sc{display:inline-block}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="all and (max-width: 903.98px)">.f{display:none}.lm{margin-top:0px}.sb{display:inline-block}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="all and (max-width: 727.98px)">.g{display:none}.lk{margin-top:0px}.ll{margin-right:0px}.sa{display:inline-block}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="all and (max-width: 551.98px)">.h{display:none}.s{display:flex}.t{justify-content:space-between}.bs{width:24px}.cc{margin:0 24px}.cr{height:40px}.cy{margin-bottom:44px}.dk{margin-bottom:32px}.dx{font-size:13px}.dy{line-height:20px}.eh{padding:0px 8px 1px}.fu{margin-bottom:4px}.gw{font-size:32px}.gx{margin-top:1.01em}.gy{margin-bottom:24px}.gz{line-height:38px}.ha{letter-spacing:-0.014em}.hv{align-items:flex-start}.iy{flex-direction:column}.jb{margin-bottom:2px}.jp{margin:24px -24px 0}.jq{padding:0}.kf> *{margin-right:8px}.kg> :last-child{margin-right:24px}.kx{margin-left:0px}.li{margin-top:0px}.lj{margin-right:0px}.ly{margin:0}.mi{border:1px solid #F2F2F2}.mj{border-radius:99em}.mk{padding:0px 16px 0px 12px}.ml{height:38px}.mm{align-items:center}.mo svg{margin-right:8px}.mz{font-size:18px}.na{margin-top:1.56em}.nb{line-height:28px}.nc{letter-spacing:-0.003em}.nw{margin-top:40px}.on{font-size:20px}.oo{margin-top:1.2em}.op{line-height:24px}.oq{letter-spacing:0}.pi{margin-top:0.67em}.pv{margin-top:1.34em}.qc{font-size:16px}.qd{margin-top:1.23em}.ro{margin-bottom:80px}.rz{display:inline-block}.se{padding-top:48px}.sv{margin-bottom:20px}.sw{margin-right:0}.tq{max-width:100%}.tt{font-size:24px}.tu{line-height:30px}.tv{letter-spacing:-0.016em}.mn:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="all and (min-width: 904px) and (max-width: 1079.98px)">.i{display:none}.bv{width:64px}.cf{margin:0 64px}.cu{height:48px}.db{margin-bottom:52px}.dn{margin-bottom:48px}.ed{font-size:14px}.ee{line-height:20px}.ek{font-size:13px}.el{padding:5px 12px}.fg{display:flex}.fx{margin-bottom:68px}.gb{max-width:680px}.hl{font-size:42px}.hm{margin-top:1.19em}.hn{margin-bottom:32px}.ho{line-height:52px}.hp{letter-spacing:-0.011em}.hy{align-items:center}.jx{border-top:solid 1px #F2F2F2}.jy{border-bottom:solid 1px #F2F2F2}.jz{margin:32px 0 0}.ka{padding:3px 8px}.kl> *{margin-right:24px}.km> :last-child{margin-right:0}.mb{margin:0}.nl{font-size:20px}.nm{margin-top:2.14em}.nn{line-height:32px}.no{letter-spacing:-0.003em}.nz{margin-top:56px}.oz{font-size:24px}.pa{margin-top:1.95em}.pb{line-height:30px}.pc{letter-spacing:-0.016em}.pl{margin-top:0.94em}.py{margin-top:1.14em}.qj{margin-top:1.72em}.qk{line-height:24px}.ql{letter-spacing:0}.rr{margin-bottom:88px}.sh{padding-top:72px}.sl{flex-direction:row}.sp{margin-bottom:0}.sq{margin-right:20px}.tn{max-width:500px}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="all and (min-width: 728px) and (max-width: 903.98px)">.j{display:none}.w{display:flex}.x{justify-content:space-between}.bu{width:64px}.ce{margin:0 48px}.ct{height:48px}.da{margin-bottom:52px}.dm{margin-bottom:48px}.eb{font-size:13px}.ec{line-height:20px}.ej{padding:0px 8px 1px}.fw{margin-bottom:68px}.ga{max-width:680px}.hg{font-size:42px}.hh{margin-top:1.19em}.hi{margin-bottom:32px}.hj{line-height:52px}.hk{letter-spacing:-0.011em}.hx{align-items:center}.jt{border-top:solid 1px #F2F2F2}.ju{border-bottom:solid 1px #F2F2F2}.jv{margin:32px 0 0}.jw{padding:3px 8px}.kj> *{margin-right:24px}.kk> :last-child{margin-right:0}.ma{margin:0}.nh{font-size:20px}.ni{margin-top:2.14em}.nj{line-height:32px}.nk{letter-spacing:-0.003em}.ny{margin-top:56px}.ov{font-size:24px}.ow{margin-top:1.95em}.ox{line-height:30px}.oy{letter-spacing:-0.016em}.pk{margin-top:0.94em}.px{margin-top:1.14em}.qg{margin-top:1.72em}.qh{line-height:24px}.qi{letter-spacing:0}.rq{margin-bottom:88px}.sg{padding-top:72px}.sm{flex-direction:row}.sr{margin-bottom:0}.ss{margin-right:20px}.to{max-width:500px}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="all and (min-width: 552px) and (max-width: 727.98px)">.k{display:none}.u{display:flex}.v{justify-content:space-between}.bt{width:24px}.cd{margin:0 24px}.cs{height:40px}.cz{margin-bottom:44px}.dl{margin-bottom:32px}.dz{font-size:13px}.ea{line-height:20px}.ei{padding:0px 8px 1px}.fv{margin-bottom:4px}.hb{font-size:32px}.hc{margin-top:1.01em}.hd{margin-bottom:24px}.he{line-height:38px}.hf{letter-spacing:-0.014em}.hw{align-items:flex-start}.iz{flex-direction:column}.jc{margin-bottom:2px}.jr{margin:24px 0 0}.js{padding:0}.kh> *{margin-right:8px}.ki> :last-child{margin-right:8px}.ky{margin-left:0px}.lz{margin:0}.mp{border:1px solid #F2F2F2}.mq{border-radius:99em}.mr{padding:0px 16px 0px 12px}.ms{height:38px}.mt{align-items:center}.mv svg{margin-right:8px}.nd{font-size:18px}.ne{margin-top:1.56em}.nf{line-height:28px}.ng{letter-spacing:-0.003em}.nx{margin-top:40px}.or{font-size:20px}.os{margin-top:1.2em}.ot{line-height:24px}.ou{letter-spacing:0}.pj{margin-top:0.67em}.pw{margin-top:1.34em}.qe{font-size:16px}.qf{margin-top:1.23em}.rp{margin-bottom:80px}.sf{padding-top:48px}.st{margin-bottom:20px}.su{margin-right:0}.tp{max-width:100%}.tw{font-size:24px}.tx{line-height:30px}.ty{letter-spacing:-0.016em}.mu:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="print">.rx{display:none}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="(orientation: landscape) and (max-width: 903.98px)">.jm{max-height:none}</style><style type="text/css" data-fela-rehydration="552" data-fela-type="RULE" media="(prefers-reduced-motion: no-preference)">.po{transition:transform 300ms cubic-bezier(0.2, 0, 0.2, 1)}</style></head><body><div id="root"><div class="a b c"><div class="d e f g h i j k"></div><script>document.domain = document.domain;</script><div class="l c"><div class="l m n o c"><div class="p q r s t u v w x i d y z"><a class="du ag dv bf ak b am an ao ap aq ar as at s u w i d q dw z" href="https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2F402682bb13cb&%7Efeature=LoOpenInAppButton&%7Echannel=ShowPostUnderCollection&source=---top_nav_layout_nav----------------------------------" rel="noopener follow">Open in app<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="none" viewBox="0 0 10 10" class="dt"><path fill="currentColor" d="M.985 8.485a.375.375 0 1 0 .53.53zM8.75 1.25h.375A.375.375 0 0 0 8.75.875zM8.375 6.5a.375.375 0 1 0 .75 0zM3.5.875a.375.375 0 1 0 0 .75zm-1.985 8.14 7.5-7.5-.53-.53-7.5 7.5zm6.86-7.765V6.5h.75V1.25zM3.5 1.625h5.25v-.75H3.5z"></path></svg></a><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton" href="https://medium.com/m/signin?operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&source=post_page---top_nav_layout_nav-----------------------global_nav-----------" rel="noopener follow">Sign up</a></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" href="https://medium.com/m/signin?operation=login&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&source=post_page---top_nav_layout_nav-----------------------global_nav-----------" rel="noopener follow">Sign in</a></span></p></div></div></div><div class="p q r ab ac"><div class="ab q ae"><a class="af ag ah ai aj ak al am an ao ap aq ar as at ab" aria-label="Homepage" data-testid="headerMediumLogo" href="https://medium.com/?source=---top_nav_layout_nav----------------------------------" rel="noopener follow"><svg xmlns="http://www.w3.org/2000/svg" width="719" height="160" fill="none" viewBox="0 0 719 160" class="au av aw"><path fill="#242424" d="m174.104 9.734.215-.047V8.02H130.39L89.6 103.89 48.81 8.021H1.472v1.666l.212.047c8.018 1.81 12.09 4.509 12.09 14.242V137.93c0 9.734-4.087 12.433-12.106 14.243l-.212.047v1.671h32.118v-1.665l-.213-.048c-8.018-1.809-12.089-4.509-12.089-14.242V30.586l52.399 123.305h2.972l53.925-126.743V140.75c-.687 7.688-4.721 10.062-11.982 11.701l-.215.05v1.652h55.948v-1.652l-.215-.05c-7.269-1.639-11.4-4.013-12.087-11.701l-.037-116.774h.037c0-9.733 4.071-12.432 12.087-14.242m25.555 75.488c.915-20.474 8.268-35.252 20.606-35.507 3.806.063 6.998 1.312 9.479 3.714 5.272 5.118 7.751 15.812 7.368 31.793zm-.553 5.77h65.573v-.275c-.186-15.656-4.721-27.834-13.466-36.196-7.559-7.227-18.751-11.203-30.507-11.203h-.263c-6.101 0-13.584 1.48-18.909 4.16-6.061 2.807-11.407 7.003-15.855 12.511-7.161 8.874-11.499 20.866-12.554 34.343q-.05.606-.092 1.212a50 50 0 0 0-.065 1.151 85.807 85.807 0 0 0-.094 5.689c.71 30.524 17.198 54.917 46.483 54.917 25.705 0 40.675-18.791 44.407-44.013l-1.886-.664c-6.557 13.556-18.334 21.771-31.738 20.769-18.297-1.369-32.314-19.922-31.042-42.395m139.722 41.359c-2.151 5.101-6.639 7.908-12.653 7.908s-11.513-4.129-15.418-11.63c-4.197-8.053-6.405-19.436-6.405-32.92 0-28.067 8.729-46.22 22.24-46.22 5.657 0 10.111 2.807 12.236 7.704zm43.499 20.008c-8.019-1.897-12.089-4.722-12.089-14.951V1.309l-48.716 14.353v1.757l.299-.024c6.72-.543 11.278.386 13.925 2.83 2.072 1.915 3.082 4.853 3.082 8.987v18.66c-4.803-3.067-10.516-4.56-17.448-4.56-14.059 0-26.909 5.92-36.176 16.672-9.66 11.205-14.767 26.518-14.767 44.278-.003 31.72 15.612 53.039 38.851 53.039 13.595 0 24.533-7.449 29.54-20.013v16.865h43.711v-1.746zM424.1 19.819c0-9.904-7.468-17.374-17.375-17.374-9.859 0-17.573 7.632-17.573 17.374s7.721 17.374 17.573 17.374c9.907 0 17.375-7.47 17.375-17.374m11.499 132.546c-8.019-1.897-12.089-4.722-12.089-14.951h-.035V43.635l-43.714 12.551v1.705l.263.024c9.458.842 12.047 4.1 12.047 15.152v81.086h43.751v-1.746zm112.013 0c-8.018-1.897-12.089-4.722-12.089-14.951V43.635l-41.621 12.137v1.71l.246.026c7.733.813 9.967 4.257 9.967 15.36v59.279c-2.578 5.102-7.415 8.131-13.274 8.336-9.503 0-14.736-6.419-14.736-18.073V43.638l-43.714 12.55v1.703l.262.024c9.459.84 12.05 4.097 12.05 15.152v50.17a56.3 56.3 0 0 0 .91 10.444l.787 3.423c3.701 13.262 13.398 20.197 28.59 20.197 12.868 0 24.147-7.966 29.115-20.43v17.311h43.714v-1.747zm169.818 1.788v-1.749l-.213-.05c-8.7-2.006-12.089-5.789-12.089-13.49v-63.79c0-19.89-11.171-31.761-29.883-31.761-13.64 0-25.141 7.882-29.569 20.16-3.517-13.01-13.639-20.16-28.606-20.16-13.146 0-23.449 6.938-27.869 18.657V43.643L545.487 55.68v1.715l.263.024c9.345.829 12.047 4.181 12.047 14.95v81.784h40.787v-1.746l-.215-.053c-6.941-1.631-9.181-4.606-9.181-12.239V66.998c1.836-4.289 5.537-9.37 12.853-9.37 9.086 0 13.692 6.296 13.692 18.697v77.828h40.797v-1.746l-.215-.053c-6.94-1.631-9.18-4.606-9.18-12.239V75.066a42 42 0 0 0-.578-7.26c1.947-4.661 5.86-10.177 13.475-10.177 9.214 0 13.691 6.114 13.691 18.696v77.828z"></path></svg></a><div class="ax h"><div class="ab ay az ba bb q bc bd"><div class="bm" aria-hidden="false" aria-describedby="searchResults" aria-labelledby="searchResults"></div><div class="bn bo ab"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div><input role="combobox" aria-controls="searchResults" aria-expanded="false" aria-label="search" data-testid="headerSearchInput" tabindex="0" class="ay be bf bg z bh bi bj bk bl" placeholder="Search" value=""/></div></div></div><div class="h k w fg fh"><div class="fi ab"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerWriteButton" href="https://medium.com/m/signin?operation=register&redirect=https%3A%2F%2Fmedium.com%2Fnew-story&source=---top_nav_layout_nav-----------------------new_post_topnav-----------" rel="noopener follow"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Write"><path fill="currentColor" d="M14 4a.5.5 0 0 0 0-1zm7 6a.5.5 0 0 0-1 0zm-7-7H4v1h10zM3 4v16h1V4zm1 17h16v-1H4zm17-1V10h-1v10zm-1 1a1 1 0 0 0 1-1h-1zM3 20a1 1 0 0 0 1 1v-1zM4 3a1 1 0 0 0-1 1h1z"></path><path stroke="currentColor" d="m17.5 4.5-8.458 8.458a.25.25 0 0 0-.06.098l-.824 2.47a.25.25 0 0 0 .316.316l2.47-.823a.25.25 0 0 0 .098-.06L19.5 6.5m-2-2 2.323-2.323a.25.25 0 0 1 .354 0l1.646 1.646a.25.25 0 0 1 0 .354L19.5 6.5m-2-2 2 2"></path></svg><div class="dt l">Write</div></div></a></span></div></div><div class="k j i d"><div class="fi ab"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSearchButton" href="https://medium.com/search?source=---top_nav_layout_nav----------------------------------" rel="noopener follow"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Search"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div></a></div></div><div class="fi h k j"><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton" href="https://medium.com/m/signin?operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&source=post_page---top_nav_layout_nav-----------------------global_nav-----------" rel="noopener follow">Sign up</a></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" href="https://medium.com/m/signin?operation=login&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&source=post_page---top_nav_layout_nav-----------------------global_nav-----------" rel="noopener follow">Sign in</a></span></p></div></div></div><div class="l" aria-hidden="false"><button class="ay fn am ab q ao fo fp fq" aria-label="user options menu" data-testid="headerUserIcon"><div class="l fj"><img alt="" class="l fd by bz ca cx" src="https://miro.medium.com/v2/resize:fill:64:64/1*dmbNkD5D-u45r44go_cf0g.png" width="32" height="32" loading="lazy" role="presentation"/><div class="fr by l bz ca fs n ay ft"></div></div></button></div></div></div><div class="l"><div class="fu fv fw fx fy l"><div class="ab cb"><div class="ci bh fz ga gb gc"></div></div><article><div class="l"><div class="l"><span class="l"></span><section><div><div class="fs gi gj gk gl gm"></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><div><h1 id="4410" class="pw-post-title gs gt gu bf gv gw gx gy gz ha hb hc hd he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu bk" data-testid="storyTitle">Breaking the code: How did we build our Figma plugin?</h1><div><div class="speechify-ignore ab cp"><div class="speechify-ignore bh l"><div class="hv hw hx hy hz ab"><div><div class="ab ia"><div><div class="bm" aria-hidden="false"><a href="https://medium.com/@sai_lakshman?source=post_page---byline--402682bb13cb--------------------------------" rel="noopener follow"><div class="l ib ic by id ie"><div class="l fj"><img alt="Sai Lakshman" class="l fd by dd de cx" src="https://miro.medium.com/v2/resize:fill:88:88/1*0ECTVtKvhAKBcMqtkE-q1Q.png" width="44" height="44" loading="lazy" data-testid="authorPhoto"/><div class="if by l dd de fs n ig ft"></div></div></div></a></div></div><div class="ih ab fj"><div><div class="bm" aria-hidden="false"><a href="https://design.zeta.in/?source=post_page---byline--402682bb13cb--------------------------------" rel="noopener ugc nofollow"><div class="l ii ij by id ik"><div class="l fj"><img alt="Zeta Design" class="l fd by br il cx" src="https://miro.medium.com/v2/resize:fill:48:48/1*7FG4sDTdzgBNYQL3onKlXQ.png" width="24" height="24" loading="lazy" data-testid="publicationPhoto"/><div class="if by l br il fs n ig ft"></div></div></div></a></div></div></div></div></div><div class="bn bh l"><div class="ab"><div style="flex:1"><span class="bf b bg z bk"><div class="im ab q"><div class="ab q in"><div class="ab q"><div><div class="bm" aria-hidden="false"><p class="bf b io ip bk"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" data-testid="authorName" href="https://medium.com/@sai_lakshman?source=post_page---byline--402682bb13cb--------------------------------" rel="noopener follow">Sai Lakshman</a></p></div></div></div><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span><p class="bf b io ip du"><span><a class="it iu ah ai aj ak al am an ao ap aq ar ex iv iw" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F809d3d0ce467&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&user=Sai+Lakshman&userId=809d3d0ce467&source=post_page-809d3d0ce467--byline--402682bb13cb---------------------post_header-----------" rel="noopener follow">Follow</a></span></p></div></div></span></div></div><div class="l ix"><span class="bf b bg z du"><div class="ab cn iy iz ja"><div class="jb jc ab"><div class="bf b bg z du ab jd"><span class="je l ix">Published in</span><div><div class="l" aria-hidden="false"><a class="af ag ah ai aj ak al am an ao ap aq ar iq ab q" data-testid="publicationName" href="https://design.zeta.in/?source=post_page---byline--402682bb13cb--------------------------------" rel="noopener ugc nofollow"><p class="bf b bg z jf jg jh ji jj jk jl jm bk">Zeta Design</p></a></div></div></div><div class="h k"><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span></div></div><span class="bf b bg z du"><div class="ab ae"><span data-testid="storyReadTime">9 min read</span><div class="jn jo l" aria-hidden="true"><span class="l" aria-hidden="true"><span class="bf b bg z du">·</span></span></div><span data-testid="storyPublishDate">Jun 1, 2021</span></div></span></div></span></div></div></div><div class="ab cp jp jq jr js jt ju jv jw jx jy jz ka kb kc kd ke"><div class="h k w fg fh q"><div class="ku l"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerClapButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fzeta-design%2F402682bb13cb&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&user=Sai+Lakshman&userId=809d3d0ce467&source=---header_actions--402682bb13cb---------------------clap_footer-----------" rel="noopener follow"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></div><div><div class="bm" aria-hidden="false"><button class="ao la lq lr ab q fk ls lt" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lu"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg></button></div></div></div><div class="ab q kf kg kh ki kj kk kl km kn ko kp kq kr ks kt"><div class="lv k j i d"></div><div class="h k"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerBookmarkButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2F402682bb13cb&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&source=---header_actions--402682bb13cb---------------------bookmark_footer-----------" rel="noopener follow"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lw" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="fd lx cn"><div class="l ae"><div class="ab cb"><div class="ly lz ma mb mc md ci bh"><div class="ab"><div class="bm bh" aria-hidden="false"><div><div class="bm" aria-hidden="false"><button aria-label="Listen" data-testid="audioPlayButton" class="af fk ah ai aj ak al me an ao ap ex mf mg lt mh mi mj mk ml s mm mn mo mp mq mr ms u mt mu mv"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M3 12a9 9 0 1 1 18 0 9 9 0 0 1-18 0m9-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2m3.376 10.416-4.599 3.066a.5.5 0 0 1-.777-.416V8.934a.5.5 0 0 1 .777-.416l4.599 3.066a.5.5 0 0 1 0 .832" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Listen</p></div></button></div></div></div></div></div></div></div></div><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="headerSocialShareButton" class="af fk ah ai aj ak al me an ao ap ex mf mg lt mh mi mj mk ml s mm mn mo mp mq mr ms u mt mu mv"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Share</p></div></button></div></div></div></div></div></div></div></div></div><p id="a046" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Learn how Zeta Design built its first Figma plugin.</em></p></div></div><div class="nv bh"><figure class="nw nx ny nz oa nv bh paragraph-image"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*Buv9AgzhmtMU6dkKrqZznw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*Buv9AgzhmtMU6dkKrqZznw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*Buv9AgzhmtMU6dkKrqZznw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*Buv9AgzhmtMU6dkKrqZznw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*Buv9AgzhmtMU6dkKrqZznw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Buv9AgzhmtMU6dkKrqZznw.png 1100w, https://miro.medium.com/v2/resize:fit:4800/format:webp/1*Buv9AgzhmtMU6dkKrqZznw.png 4800w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 100vw" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*Buv9AgzhmtMU6dkKrqZznw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*Buv9AgzhmtMU6dkKrqZznw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*Buv9AgzhmtMU6dkKrqZznw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*Buv9AgzhmtMU6dkKrqZznw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*Buv9AgzhmtMU6dkKrqZznw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*Buv9AgzhmtMU6dkKrqZznw.png 1100w, https://miro.medium.com/v2/resize:fit:4800/1*Buv9AgzhmtMU6dkKrqZznw.png 4800w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 100vw"/><img alt="" class="bh md ob c" width="2400" height="1240" loading="eager" role="presentation"/></picture><figcaption class="oc ff od oe of og oh bf b bg z du">Illustrations by <span class="is"><span class="is" aria-hidden="false"><a class="oi it fe" href="https://medium.com/u/a94240008425?source=post_page---user_mention--402682bb13cb--------------------------------" rel="noopener" target="_blank">Aakansha Menon</a></span></span>.</figcaption></figure></div><div class="ab cb"><div class="ci bh fz ga gb gc"><p id="2896" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><strong class="my gv">Co-authored by </strong><span class="is"><span class="is" aria-hidden="false"><a class="oi it fe" href="https://medium.com/u/924d6ac61d43?source=post_page---user_mention--402682bb13cb--------------------------------" rel="noopener" target="_blank"><strong class="my gv">Manik Chugh</strong></a></span></span><strong class="my gv"> and </strong><span class="is"><span class="is" aria-hidden="false"><a class="oi it fe" href="https://medium.com/u/289f1789610e?source=post_page---user_mention--402682bb13cb--------------------------------" rel="noopener" target="_blank"><strong class="my gv">Sneh Singh</strong></a></span></span><strong class="my gv">. Illustrations by </strong><span class="is"><span class="is" aria-hidden="false"><a class="oi it fe" href="https://medium.com/u/a94240008425?source=post_page---user_mention--402682bb13cb--------------------------------" rel="noopener" target="_blank"><strong class="my gv">Aakansha Menon</strong></a></span></span><strong class="my gv">.</strong></p><p id="9241" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Writing UX copies can be a little frustrating and confusing, and sometimes we are unsure about how to get the right word. To crack the code for the UX copies, we at Zeta Design wanted to build a Figma plugin for the larger design community. The plugin is called the <a class="af oj" href="https://www.figma.com/community/plugin/960778033371641874/Ghost-UXWriter" rel="noopener ugc nofollow" target="_blank">Ghost UXWriter</a> and has a set of UX copies cataloged and categorized with a voice and tone variation ranging from plain, casual to playful. The intention to build this Figma plugin originated from our Medium blog post, ‘<a class="af oj" rel="noopener ugc nofollow" target="_blank" href="/designing-voice-and-tone-for-error-messages-185676c10627#:~:text=The%20significance%20of%20voice%20and,are%20not%20given%20enough%20importance.&text=The%20voice%20of%20the%20error,bringing%20out%20the%20brand%20personality.">Designing voice and tone for error messages</a>.’</p><p id="7bf2" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">This plugin can be used by designers, writers, and developers, making it a go-to plugin every time someone wants a hand with UX copywriting.</p><p id="32c6" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">The journey of building our Figma plugin can be divided into three-phases — writing UX copies, designing the interface, and developing the plugin.This blog will focus on the third phase, the development phase, to unravel the pitfalls and the havens while developing a Figma plugin.</p><h1 id="7d2e" class="ok ol gu bf om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph bk">How does the plugin work?</h1><p id="0a7a" class="pw-post-body-paragraph mw mx gu my b mz pi nb nc nd pj nf ng nh pk nj nk nl pl nn no np pm nr ns nt gn bk"><em class="nu">Step 1: Download the plugin from Figma community, search </em><strong class="my gv"><em class="nu">Ghost UXWriter</em></strong></p><p id="2ebf" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 2: Open the plugin on your artboard</em></p><p id="7059" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 3: Search for your copy or look through the different categories of the copies</em></p><p id="6dac" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 4: Select the type of error you are looking for. You will get three different copies for each error</em></p><p id="bf3e" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 5: Tap on the cards to insert text in your frames</em></p><p id="8c99" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">And you are all geared up to make your UX copies more <em class="nu">fun and exciting </em>😎</p><figure class="nw nx ny nz oa nv oe of paragraph-image"><div role="button" tabindex="0" class="po pp fj pq bh pr"><div class="oe of pn"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*rMobpdLQcd84Sp-9mza8Sw.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*rMobpdLQcd84Sp-9mza8Sw.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*rMobpdLQcd84Sp-9mza8Sw.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*rMobpdLQcd84Sp-9mza8Sw.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*rMobpdLQcd84Sp-9mza8Sw.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rMobpdLQcd84Sp-9mza8Sw.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*rMobpdLQcd84Sp-9mza8Sw.gif 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*rMobpdLQcd84Sp-9mza8Sw.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*rMobpdLQcd84Sp-9mza8Sw.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*rMobpdLQcd84Sp-9mza8Sw.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*rMobpdLQcd84Sp-9mza8Sw.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*rMobpdLQcd84Sp-9mza8Sw.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*rMobpdLQcd84Sp-9mza8Sw.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/1*rMobpdLQcd84Sp-9mza8Sw.gif 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh md ob c" width="700" height="392" loading="lazy" role="presentation"/></picture></div></div><figcaption class="oc ff od oe of og oh bf b bg z du"><a class="af oj" href="https://www.figma.com/community/plugin/960778033371641874/Ghost-UXWriter" rel="noopener ugc nofollow" target="_blank">Ghost UXWriter</a> in action</figcaption></figure><p id="f51b" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Currently, in the Ghost UXWriter, we support the following features:</p><ul class=""><li id="69a7" class="mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt ps pt pu bk">Plugin tutorial, onboarding screens</li><li id="1d3b" class="mw mx gu my b mz pv nb nc nd pw nf ng nh px nj nk nl py nn no np pz nr ns nt ps pt pu bk">User login</li><li id="b762" class="mw mx gu my b mz pv nb nc nd pw nf ng nh px nj nk nl py nn no np pz nr ns nt ps pt pu bk">Seamless Search Engine</li><li id="eb1e" class="mw mx gu my b mz pv nb nc nd pw nf ng nh px nj nk nl py nn no np pz nr ns nt ps pt pu bk">Different UX categories with the variation of voice and tone ranging from plain, casual to playful</li><li id="3013" class="mw mx gu my b mz pv nb nc nd pw nf ng nh px nj nk nl py nn no np pz nr ns nt ps pt pu bk">Easily Insert selected UX copy in artboard</li><li id="1e3a" class="mw mx gu my b mz pv nb nc nd pw nf ng nh px nj nk nl py nn no np pz nr ns nt ps pt pu bk">Copy text to clipboard</li><li id="0691" class="mw mx gu my b mz pv nb nc nd pw nf ng nh px nj nk nl py nn no np pz nr ns nt ps pt pu bk">User Profile</li><li id="8a24" class="mw mx gu my b mz pv nb nc nd pw nf ng nh px nj nk nl py nn no np pz nr ns nt ps pt pu bk">Bookmark favourite copies</li><li id="d89c" class="mw mx gu my b mz pv nb nc nd pw nf ng nh px nj nk nl py nn no np pz nr ns nt ps pt pu bk">Add custom copies as MyCopies</li></ul><h1 id="8000" class="ok ol gu bf om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph bk">Discovering design</h1><p id="1b31" class="pw-post-body-paragraph mw mx gu my b mz pi nb nc nd pj nf ng nh pk nj nk nl pl nn no np pm nr ns nt gn bk">In the initial phase of design, we began with a low-fidelity wireframe to brainstorm the ideas from onboarding users to get them to use the plugin’s main features. Next, we converted them to high-fidelity screen-based designs, covering end-to-end plugin flows with monochromatic colors.</p><p id="efe2" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">While designing for the Figma plugin frame, we had to solve for the scale of things. We had to create a small screen window that would fit into a large screen device. Our objective was to consume the minimum space of the designer’s artboard and give the majority of the area to their canvas. Hence, we settled onto a 360px width plugin window size and constrained our flows to that.</p><figure class="nw nx ny nz oa nv oe of paragraph-image"><div role="button" tabindex="0" class="po pp fj pq bh pr"><div class="oe of qa"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*Udi9NtgHYs0iYxEcyuaN_w.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*Udi9NtgHYs0iYxEcyuaN_w.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*Udi9NtgHYs0iYxEcyuaN_w.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*Udi9NtgHYs0iYxEcyuaN_w.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*Udi9NtgHYs0iYxEcyuaN_w.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Udi9NtgHYs0iYxEcyuaN_w.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*Udi9NtgHYs0iYxEcyuaN_w.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*Udi9NtgHYs0iYxEcyuaN_w.png 640w, https://miro.medium.com/v2/resize:fit:720/1*Udi9NtgHYs0iYxEcyuaN_w.png 720w, https://miro.medium.com/v2/resize:fit:750/1*Udi9NtgHYs0iYxEcyuaN_w.png 750w, https://miro.medium.com/v2/resize:fit:786/1*Udi9NtgHYs0iYxEcyuaN_w.png 786w, https://miro.medium.com/v2/resize:fit:828/1*Udi9NtgHYs0iYxEcyuaN_w.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*Udi9NtgHYs0iYxEcyuaN_w.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*Udi9NtgHYs0iYxEcyuaN_w.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh md ob c" width="700" height="350" loading="lazy" role="presentation"/></picture></div></div><figcaption class="oc ff od oe of og oh bf b bg z du"><a class="af oj" href="https://www.figma.com/community/plugin/960778033371641874/Ghost-UXWriter" rel="noopener ugc nofollow" target="_blank">Ghost UXWriter’s</a> design evolution</figcaption></figure><h2 id="dee3" class="qb ol gu bf om qc qd dy oq qe qf ea ou nh qg qh qi nl qj qk ql np qm qn qo qp bk">Picking the right color</h2><p id="64d6" class="pw-post-body-paragraph mw mx gu my b mz pi nb nc nd pj nf ng nh pk nj nk nl pl nn no np pm nr ns nt gn bk">Our initial plugin was designed in monochromatic color, and it was ready to ship. But, we felt the colors reflected an uptight formal-looking product, but that is not what Ghost UXWriter stood for.</p><p id="4973" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">The core of Ghost UXWriter lies in being a hospitable, lighthearted, and warm plugin. We restarted with rounds of iterating the color variations, starting from pastel, vibrant to even rich premium colors, we still couldn’t find the perfect color for our product personality. After trying different color sets, we started exploring the gradient’s territory, and then we had our hands on mesh gradients.</p><p id="d391" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">We found a perfect match to our product’s personality with that exploration, and without a doubt, we closed on that final iteration with Mesh gradients. The Mesh gradient impacted every product element, starting from updating the logo colors to the Figma community banners and all the promotional content.</p><p id="6ef5" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">And that’s how we closed our plugin designs with all our iterations and explorations. You can find some of the flows <a class="af oj" href="https://www.figma.com/file/KC61Vsg7XRVYIFRB6PoP6h/Plugin-design-journey?node-id=0%3A1" rel="noopener ugc nofollow" target="_blank">here</a>.</p><h1 id="f8e3" class="ok ol gu bf om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph bk">Dismantling the code</h1><figure class="nw nx ny nz oa nv oe of paragraph-image"><div role="button" tabindex="0" class="po pp fj pq bh pr"><div class="oe of qq"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*Mzg-gzJoyRZAWgnUlBsU2A.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*Mzg-gzJoyRZAWgnUlBsU2A.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*Mzg-gzJoyRZAWgnUlBsU2A.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*Mzg-gzJoyRZAWgnUlBsU2A.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*Mzg-gzJoyRZAWgnUlBsU2A.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Mzg-gzJoyRZAWgnUlBsU2A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*Mzg-gzJoyRZAWgnUlBsU2A.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*Mzg-gzJoyRZAWgnUlBsU2A.png 640w, https://miro.medium.com/v2/resize:fit:720/1*Mzg-gzJoyRZAWgnUlBsU2A.png 720w, https://miro.medium.com/v2/resize:fit:750/1*Mzg-gzJoyRZAWgnUlBsU2A.png 750w, https://miro.medium.com/v2/resize:fit:786/1*Mzg-gzJoyRZAWgnUlBsU2A.png 786w, https://miro.medium.com/v2/resize:fit:828/1*Mzg-gzJoyRZAWgnUlBsU2A.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*Mzg-gzJoyRZAWgnUlBsU2A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*Mzg-gzJoyRZAWgnUlBsU2A.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh md ob c" width="700" height="350" loading="lazy" role="presentation"/></picture></div></div><figcaption class="oc ff od oe of og oh bf b bg z du">Our development process</figcaption></figure><p id="0bfd" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">The Figma plugin development ecosystem was uncharted territory for us. On that account, we prepped ourselves with research on all <a class="af oj" href="https://www.figma.com/plugin-docs/intro/" rel="noopener ugc nofollow" target="_blank">documentation</a> regarding the Figma plugin. It helped us explore the possibilities and limitations with Figma plugins, which would eventually help us build a full-fledged one.</p><h2 id="ec61" class="qb ol gu bf om qc qd dy oq qe qf ea ou nh qg qh qi nl qj qk ql np qm qn qo qp bk">The basic setup</h2><p id="d014" class="pw-post-body-paragraph mw mx gu my b mz pi nb nc nd pj nf ng nh pk nj nk nl pl nn no np pm nr ns nt gn bk">After the deep-dive research, we started building the plugin with the help of Figma’s<a class="af oj" href="https://www.figma.com/plugin-docs/setup/" rel="noopener ugc nofollow" target="_blank"> Setup guide</a>. Following are the initial steps we took to set up the plugin:</p><p id="0f18" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 1: Install VSCode editor as suggested by Figma for writing code</em></p><p id="d0d4" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 2: Install NodeJs, NPM package manager, TypeScript to set up a local javascript development environment necessary to build the plugin</em></p><p id="5c11" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 3: Install Figma desktop app as development and testing the plugin only happens in the desktop app</em></p><figure class="nw nx ny nz oa nv oe of paragraph-image"><div role="button" tabindex="0" class="po pp fj pq bh pr"><div class="oe of pn"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*9fi--50WfUWJKzS1CsP1IQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*9fi--50WfUWJKzS1CsP1IQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*9fi--50WfUWJKzS1CsP1IQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*9fi--50WfUWJKzS1CsP1IQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*9fi--50WfUWJKzS1CsP1IQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*9fi--50WfUWJKzS1CsP1IQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*9fi--50WfUWJKzS1CsP1IQ.gif 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*9fi--50WfUWJKzS1CsP1IQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*9fi--50WfUWJKzS1CsP1IQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*9fi--50WfUWJKzS1CsP1IQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*9fi--50WfUWJKzS1CsP1IQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*9fi--50WfUWJKzS1CsP1IQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*9fi--50WfUWJKzS1CsP1IQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/1*9fi--50WfUWJKzS1CsP1IQ.gif 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh md ob c" width="700" height="438" loading="lazy" role="presentation"/></picture></div></div></figure><p id="1d7a" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 4: Navigate to Profile Menu > Plugins > Development > … to browse the plugins</em></p><p id="58ce" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 5: Create a new plugin using one of the default templates, select “With UI & browser APIs” for full configuration or load an existing manifest.json file</em></p><p id="8bc8" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 6: If the plugin is created for the first time, a prompt screen will appear to ‘Save’ the project</em></p><p id="bc5b" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 7: Open the project folder with VSCode editor or in the terminal navigate to the project folder using “cd folder-path ” and type “code .” to open the project</em></p><p id="df81" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Step 8: UI.html, Code.ts, and manifest.json are the files responsible for User interface, plugin logic & communication with Figma APIs, and configuration</em></p><p id="80af" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">If you’re using vanilla javascript to build the project, you’ll only have to work on these files. Alternatively, you can use <a class="af oj" href="https://www.figma.com/plugin-docs/bundling-webpack/" rel="noopener ugc nofollow" target="_blank">Webpack module bundler</a>, <a class="af oj" href="https://www.figma.com/plugin-docs/bundling-react/" rel="noopener ugc nofollow" target="_blank">ReactJs</a>, VueJs, or any other javascript UI framework/library to develop the plugin. These are advanced steps and require further configuration.</p><p id="63f3" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">We relied on only two files, ui.html and code.ts for the complete project. This can get clumsy when you work on a complex plugin, if you want to break your project into multiple files or components, use a bundler/framework to write your code.</p><h2 id="1064" class="qb ol gu bf om qc qd dy oq qe qf ea ou nh qg qh qi nl qj qk ql np qm qn qo qp bk">Bridging Google Sheet with code</h2><p id="598a" class="pw-post-body-paragraph mw mx gu my b mz pi nb nc nd pj nf ng nh pk nj nk nl pl nn no np pm nr ns nt gn bk">After setting up the plugin, we went on to work on the Ghost UXWriter. Ghost UXWriter is a content-heavy plugin; therefore,<strong class="my gv"> </strong>to solve our technical and content-related bottlenecks, we followed a straightforward approach using Firebase for back-end and Google Sheets to host our content. We used vanilla Javascript to build most of our plugin, some TypeScript for working with Figma APIs, plain CSS & HTML for the markup, and inline SVG for media.</p><figure class="nw nx ny nz oa nv oe of paragraph-image"><div role="button" tabindex="0" class="po pp fj pq bh pr"><div class="oe of qq"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 640w, https://miro.medium.com/v2/resize:fit:720/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 720w, https://miro.medium.com/v2/resize:fit:750/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 750w, https://miro.medium.com/v2/resize:fit:786/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 786w, https://miro.medium.com/v2/resize:fit:828/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 828w, https://miro.medium.com/v2/resize:fit:1100/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 1100w, https://miro.medium.com/v2/resize:fit:1400/1*RyhSJWmaTRpduiqKOdxxAA.jpeg 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh md ob c" width="700" height="350" loading="lazy" role="presentation"/></picture></div></div><figcaption class="oc ff od oe of og oh bf b bg z du">Connecting Google Sheets to Firebase</figcaption></figure><p id="2549" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Our development journey started from the Google Sheet, where we first curated our content and later used<a class="af oj" href="https://developers.google.com/apps-script/guides/sheets" rel="noopener ugc nofollow" target="_blank"> Apps Script for Google Sheet</a> to store this data in the Firebase’s <a class="af oj" href="https://firebase.google.com/docs/firestore" rel="noopener ugc nofollow" target="_blank">Firestore</a> NoSQL database. With Google Sheet now synced with the database, content updates happen more seamlessly.</p><p id="8090" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">In the initial plugin launch, we avoided overcomplicating the back-end dashboards, therefore Google Sheets became our primary content source and helped the team to actively collaborate on the content.</p><h2 id="f227" class="qb ol gu bf om qc qd dy oq qe qf ea ou nh qg qh qi nl qj qk ql np qm qn qo qp bk">Jumping through the hoops of authentication</h2><figure class="nw nx ny nz oa nv oe of paragraph-image"><div role="button" tabindex="0" class="po pp fj pq bh pr"><div class="oe of qr"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*xIGpaz1oRGAvns699XI9pA.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*xIGpaz1oRGAvns699XI9pA.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*xIGpaz1oRGAvns699XI9pA.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*xIGpaz1oRGAvns699XI9pA.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*xIGpaz1oRGAvns699XI9pA.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*xIGpaz1oRGAvns699XI9pA.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*xIGpaz1oRGAvns699XI9pA.gif 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*xIGpaz1oRGAvns699XI9pA.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*xIGpaz1oRGAvns699XI9pA.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*xIGpaz1oRGAvns699XI9pA.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*xIGpaz1oRGAvns699XI9pA.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*xIGpaz1oRGAvns699XI9pA.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*xIGpaz1oRGAvns699XI9pA.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/1*xIGpaz1oRGAvns699XI9pA.gif 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh md ob c" width="700" height="377" loading="lazy" role="presentation"/></picture></div></div><figcaption class="oc ff od oe of og oh bf b bg z du">Google authentication in <a class="af oj" href="https://www.figma.com/community/plugin/960778033371641874/Ghost-UXWriter" rel="noopener ugc nofollow" target="_blank">Ghost UXWriter</a></figcaption></figure><p id="0555" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">We wanted to implement a social sign-in for the plugin. There was a hurdle as the Figma plugin doesn’t allow developers to set browser cookies.</p><p id="1a44" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Plugins in Figma are loaded in iframe, giving away certain technical limitations. These limitations include the unavailability of browser APIs (majorly cookies and localStorage) to support authentication and analytics services. Therefore, for implementing a social sign-in, additional steps were required. Even though Figma provides <a class="af oj" href="https://www.figma.com/plugin-docs/api/figma-clientStorage/" rel="noopener ugc nofollow" target="_blank">figma.clientStorage</a> API, as an alternative to native locaStorage API, it doesn’t suit well for our use case.</p><p id="ed9d" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><strong class="my gv">TLDR; </strong>Most of the authentication and analytics services that rely on browser cookies don’t work because of the Figma plugin development limitations.</p><p id="8949" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">To resolve this issue, we performed our authentication by opening a browser tab and sent the user data back to the plugin after a successful login.</p><blockquote class="qs qt qu"><p id="f2da" class="mw mx nu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Whenever a user clicks on the signup button in the plugin, we register a new <a class="af oj" href="https://firebase.google.com/docs/reference/js/firebase.firestore.DocumentReference" rel="noopener ugc nofollow" target="_blank">reference</a> in the Firestore database to listen for login status actively. A new screen opens up in the browser where authentication is carried out using <a class="af oj" href="https://firebase.google.com/products/auth" rel="noopener ugc nofollow" target="_blank">Firebase auth</a>, and once the authentication is successful, we send back user details to plugin UI. We use unique reference IDs to authenticate these requests between the plugin and browser interface.</p></blockquote><p id="42cb" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">These login URLs are also configured with additional restrictions, such as the link is for single use only, reloading the login page will fail the request, and URL with an unregistered reference ID will fail the login attempt. We used strict access rules for our Firestore database and suggested configuring them carefully when you are working with firebase. Below are a few valuable links for working with Firestore rules on your production website.</p><p id="5226" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">1. <a class="af oj" href="https://fireship.io/snippets/firestore-rules-recipes/" rel="noopener ugc nofollow" target="_blank">https://fireship.io/snippets/firestore-rules-recipes/</a></p><p id="c849" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">2. <a class="af oj" href="https://firebase.google.com/docs/reference/rules/rules.firestore" rel="noopener ugc nofollow" target="_blank">https://firebase.google.com/docs/reference/rules/rules.firestore</a></p><p id="11d3" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">If you don’t want to depend on Firebase for any of your flows, you can refer to <a class="af oj" href="https://paper.dropbox.com/doc/OAuth-with-Figma-Plugins-yErww0GkGBaYjgUmBeA4Z" rel="noopener ugc nofollow" target="_blank">this article </a>on implementing a custom authentication through your server.</p><h2 id="0af1" class="qb ol gu bf om qc qd dy oq qe qf ea ou nh qg qh qi nl qj qk ql np qm qn qo qp bk">The common constraints</h2><p id="8596" class="pw-post-body-paragraph mw mx gu my b mz pi nb nc nd pj nf ng nh pk nj nk nl pl nn no np pm nr ns nt gn bk">Even though there are so many possibilities with <a class="af oj" href="https://www.figma.com/plugin-docs/api/api-overview/" rel="noopener ugc nofollow" target="_blank">Figma APIs</a> for developing plugins, we also encountered few API limitations in our journey. In the Ghost UXWriter plugin, we weren’t able to replace text fields with <a class="af oj" href="https://www.figma.com/plugin-docs/api/properties/figma-mixed/" rel="noopener ugc nofollow" target="_blank">mixed fonts</a>. This is a Figma API limitation to replace text nodes with mixed types, and we had to notify users about this explicitly. So if you are planning on building a Figma Plugin DYOR (Do own your research) or join the Figma community Slack channel for any queries related to limitations of APIs.</p><figure class="nw nx ny nz oa nv oe of paragraph-image"><div role="button" tabindex="0" class="po pp fj pq bh pr"><div class="oe of qa"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*OJNhIwx0aGgq-Q_swSaAUg.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*OJNhIwx0aGgq-Q_swSaAUg.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*OJNhIwx0aGgq-Q_swSaAUg.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*OJNhIwx0aGgq-Q_swSaAUg.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*OJNhIwx0aGgq-Q_swSaAUg.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*OJNhIwx0aGgq-Q_swSaAUg.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*OJNhIwx0aGgq-Q_swSaAUg.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*OJNhIwx0aGgq-Q_swSaAUg.png 640w, https://miro.medium.com/v2/resize:fit:720/1*OJNhIwx0aGgq-Q_swSaAUg.png 720w, https://miro.medium.com/v2/resize:fit:750/1*OJNhIwx0aGgq-Q_swSaAUg.png 750w, https://miro.medium.com/v2/resize:fit:786/1*OJNhIwx0aGgq-Q_swSaAUg.png 786w, https://miro.medium.com/v2/resize:fit:828/1*OJNhIwx0aGgq-Q_swSaAUg.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*OJNhIwx0aGgq-Q_swSaAUg.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*OJNhIwx0aGgq-Q_swSaAUg.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh md ob c" width="700" height="350" loading="lazy" role="presentation"/></picture></div></div><figcaption class="oc ff od oe of og oh bf b bg z du">Developmental hurdles and Figma platform limitations</figcaption></figure><p id="af16" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Another major constraint we faced while developing the plugin was that we were unable to see code changes live in real-time. It made the experience quite time-consuming as we had to restart the plugin every time in order to check the output when there was a code change. Since the Figma plugins use web technologies, we built the initial screens and UI that doesn’t rely on Figma APIs using the browser by running a localhost server that watches the code for live changes. This saved us a ton of time in perfecting the plugin UI.</p><p id="f379" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Furthermore, we were also finding it very difficult to debug the plugin for styling and code errors, but now that we have a browser interface, we could quickly check our CSS and rely on the browser’s dev tools for most of the debugging. Despite Figma providing a console and Developer VM option for <a class="af oj" href="https://www.figma.com/plugin-docs/debugging/" rel="noopener ugc nofollow" target="_blank">debugging with Figma</a>, it might look cluttered in the initial phases and is not easy to check styling and live reloads. There’s no other option but to use Developer VM when working with Figma APIs for your plugin. For more information on how plugins run inside Figma, refer <a class="af oj" href="https://www.figma.com/plugin-docs/how-plugins-run/" rel="noopener ugc nofollow" target="_blank">here</a>.</p><h1 id="57ab" class="ok ol gu bf om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph bk">🎯 The road ahead</h1><p id="eb6b" class="pw-post-body-paragraph mw mx gu my b mz pi nb nc nd pj nf ng nh pk nj nk nl pl nn no np pm nr ns nt gn bk">Ghost UXWriter is our first Figma plugin, and the journey to build something new was exhilarating and enthralling.<strong class="my gv"> </strong>Throughout the plugin development process, we preferred to use plain technologies. It made things more straightforward and easier to learn and understand how to build our first plugin. Currently, we are on the lookout for adding more new features and making UX copies more accessible and humane.</p><p id="16c8" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Do check out <a class="af oj" href="https://www.figma.com/community/plugin/960778033371641874/Ghost-UXWriter" rel="noopener ugc nofollow" target="_blank">Ghost UXWriter</a> and tell us how you feel about the plugin in the comments.</p></div></div></div><div class="ab cb qv qw qx qy" role="separator"><span class="qz by bm ra rb rc"></span><span class="qz by bm ra rb rc"></span><span class="qz by bm ra rb"></span></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><figure class="nw nx ny nz oa nv oe of paragraph-image"><div class="oe of rd"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*cUHv14XidnLpIq-Qs8A1Lw.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*cUHv14XidnLpIq-Qs8A1Lw.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*cUHv14XidnLpIq-Qs8A1Lw.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*cUHv14XidnLpIq-Qs8A1Lw.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*cUHv14XidnLpIq-Qs8A1Lw.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*cUHv14XidnLpIq-Qs8A1Lw.gif 1100w, https://miro.medium.com/v2/resize:fit:674/format:webp/1*cUHv14XidnLpIq-Qs8A1Lw.gif 674w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 337px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*cUHv14XidnLpIq-Qs8A1Lw.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*cUHv14XidnLpIq-Qs8A1Lw.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*cUHv14XidnLpIq-Qs8A1Lw.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*cUHv14XidnLpIq-Qs8A1Lw.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*cUHv14XidnLpIq-Qs8A1Lw.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*cUHv14XidnLpIq-Qs8A1Lw.gif 1100w, https://miro.medium.com/v2/resize:fit:674/1*cUHv14XidnLpIq-Qs8A1Lw.gif 674w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 337px"/><img alt="" class="bh md ob c" width="337" height="220" loading="eager" role="presentation"/></picture></div></figure><p id="4d6a" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">And if you are stuck anywhere or have any queries, reach out to the <a class="af oj" href="https://figmaplugins.slack.com/join/shared_invite/zt-8sv6h6hy-vJ0t3G8uT7l~g2KuY_6WvQ#/shared-invite/email" rel="noopener ugc nofollow" target="_blank">Figma Plugins Slack channel</a> to get in touch with fellow plugin developers, discuss development & launch issues, get quick updates on the latest API releases. The whole community is very engaging and resourceful.</p></div></div></div><div class="ab cb qv qw qx qy" role="separator"><span class="qz by bm ra rb rc"></span><span class="qz by bm ra rb rc"></span><span class="qz by bm ra rb"></span></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><h2 id="3272" class="qb ol gu bf om qc qd dy oq qe qf ea ou nh qg qh qi nl qj qk ql np qm qn qo qp bk">📚 <strong class="al">Useful Resources :</strong></h2><p id="9aa6" class="pw-post-body-paragraph mw mx gu my b mz pi nb nc nd pj nf ng nh pk nj nk nl pl nn no np pm nr ns nt gn bk">List of open-source Figma plugins to take inspiration from -<a class="af oj" href="https://github.com/thomas-lowry/figma-plugins-on-github" rel="noopener ugc nofollow" target="_blank">https://github.com/thomas-lowry/figma-plugins-on-github</a></p><p id="2f97" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Localhost server extension for VSCode - <a class="af oj" href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer" rel="noopener ugc nofollow" target="_blank">https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer</a></p></div></div></div><div class="ab cb qv qw qx qy" role="separator"><span class="qz by bm ra rb rc"></span><span class="qz by bm ra rb rc"></span><span class="qz by bm ra rb"></span></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><p id="23c9" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><strong class="my gv">Feel free to reach out to </strong><a class="af oj" href="https://instagram.com/lakshm_n" rel="noopener ugc nofollow" target="_blank"><strong class="my gv">@sai</strong></a><strong class="my gv"> </strong><a class="af oj" href="https://www.instagram.com/manikchugh/" rel="noopener ugc nofollow" target="_blank"><strong class="my gv">@manik</strong></a><strong class="my gv"> </strong><a class="af oj" href="https://www.instagram.com/sneh_s_/" rel="noopener ugc nofollow" target="_blank"><strong class="my gv">@sneh</strong></a><strong class="my gv"> if you face any issues with your plugin or message us at </strong><a class="af oj" href="https://www.instagram.com/zetaux/" rel="noopener ugc nofollow" target="_blank"><strong class="my gv">@zeta</strong></a><strong class="my gv"> for community collaborations.</strong></p></div></div></div></div></section></div></div></article></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="re rf ab ja"><div class="rg ab"><a class="rh ay am ao" href="https://medium.com/tag/figma?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><div class="ri fj cx rj ge rk rl bf b bg z bk rm">Figma</div></a></div><div class="rg ab"><a class="rh ay am ao" href="https://medium.com/tag/figma-plugin?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><div class="ri fj cx rj ge rk rl bf b bg z bk rm">Figma Plugin</div></a></div><div class="rg ab"><a class="rh ay am ao" href="https://medium.com/tag/ui?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><div class="ri fj cx rj ge rk rl bf b bg z bk rm">UI</div></a></div><div class="rg ab"><a class="rh ay am ao" href="https://medium.com/tag/ux?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><div class="ri fj cx rj ge rk rl bf b bg z bk rm">UX</div></a></div><div class="rg ab"><a class="rh ay am ao" href="https://medium.com/tag/development?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><div class="ri fj cx rj ge rk rl bf b bg z bk rm">Development</div></a></div></div></div></div><div class="l"></div><footer class="rn ro rp rq rr rs rt ru rv ab q rw ik c"><div class="l ae"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ab cp rx"><div class="ab q kv"><div class="ry l"><span class="l rz sa sb e d"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fzeta-design%2F402682bb13cb&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&user=Sai+Lakshman&userId=809d3d0ce467&source=---footer_actions--402682bb13cb---------------------clap_footer-----------" rel="noopener follow"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></span><span class="l h g f sc sd"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fzeta-design%2F402682bb13cb&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&user=Sai+Lakshman&userId=809d3d0ce467&source=---footer_actions--402682bb13cb---------------------clap_footer-----------" rel="noopener follow"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></span></div><div class="bq ab"><div><div class="bm" aria-hidden="false"><button class="ao la lq lr ab q fk ls lt" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lu"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg></button></div></div></div></div><div class="ab q"><div class="rc l ix"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerBookmarkButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2F402682bb13cb&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&source=---footer_actions--402682bb13cb---------------------bookmark_footer-----------" rel="noopener follow"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lw" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="rc l ix"><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="footerSocialShareButton" class="af fk ah ai aj ak al me an ao ap ex mf mg lt mh"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg></button></div></div></div></div></div></div></div></div></div></footer><div class="se sf sg sh si l bx"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="sj l"><div class="ab sk sl sm iz iy"><div class="sn so sp sq sr ss st su sv sw ab cp"><div class="h k"><a href="https://design.zeta.in/?source=post_page---post_publication_info--402682bb13cb--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Zeta Design" class="sx ib ic cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*7FG4sDTdzgBNYQL3onKlXQ.png" width="48" height="48" loading="lazy"/><div class="sx l ic ib fs n fr sy"></div></div></a></div><div class="j i d"><a href="https://design.zeta.in/?source=post_page---post_publication_info--402682bb13cb--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Zeta Design" class="sx ta sz cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*7FG4sDTdzgBNYQL3onKlXQ.png" width="64" height="64" loading="lazy"/><div class="sx l sz ta fs n fr sy"></div></div></a></div><div class="j i d tb ix"><div class="ab"><span><a class="bf b bg z tc ri td te tf tg th ev ew ti tj tk fa fb fc fd bm fe ff" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fcollection%2Fzeta-design&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&collection=Zeta+Design&collectionId=b1d9ef1bb1cd&source=post_page---post_publication_info--402682bb13cb---------------------follow_profile-----------" rel="noopener follow">Follow</a></span></div></div></div><div class="ab co tl"><div class="tm tn to tp tq l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" href="https://design.zeta.in/?source=post_page---post_publication_info--402682bb13cb--------------------------------" rel="noopener follow"><h2 class="pw-author-name bf ts tt tu tv tw tx ty nh qh qi nl qk ql np qn qo bk"><span class="gn tr">Published in <!-- -->Zeta Design</span></h2></a><div class="rg ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/followers?source=post_page---post_publication_info--402682bb13cb--------------------------------">2K Followers</a></span></div><div class="bf b bg z du ab jd"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/rocket-rides-and-roadmap-navigating-beyond-mvp-b107f857e142?source=post_page---post_publication_info--402682bb13cb--------------------------------">Last published <span>Sep 6, 2024</span></a></div></div><div class="tz l"><p class="bf b bg z bk"><span class="gn">Perspectives on designing & building digital products for India</span></p></div></div></div><div class="h k"><div class="ab"><span><a class="bf b bg z tc ri td te tf tg th ev ew ti tj tk fa fb fc fd bm fe ff" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fcollection%2Fzeta-design&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&collection=Zeta+Design&collectionId=b1d9ef1bb1cd&source=post_page---post_publication_info--402682bb13cb---------------------follow_profile-----------" rel="noopener follow">Follow</a></span></div></div></div></div><div class="ab sk sl sm iz iy"><div class="sn so sp sq sr ss st su sv sw ab cp"><div class="h k"><a tabindex="0" href="https://medium.com/@sai_lakshman?source=post_page---post_author_info--402682bb13cb--------------------------------" rel="noopener follow"><div class="l fj"><img alt="Sai Lakshman" class="l fd by ic ib cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*0ECTVtKvhAKBcMqtkE-q1Q.png" width="48" height="48" loading="lazy"/><div class="fr by l ic ib fs n ay sy"></div></div></a></div><div class="j i d"><a tabindex="0" href="https://medium.com/@sai_lakshman?source=post_page---post_author_info--402682bb13cb--------------------------------" rel="noopener follow"><div class="l fj"><img alt="Sai Lakshman" class="l fd by sz ta cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*0ECTVtKvhAKBcMqtkE-q1Q.png" width="64" height="64" loading="lazy"/><div class="fr by l sz ta fs n ay sy"></div></div></a></div><div class="j i d tb ix"><div class="ab"><span><a class="bf b bg z tc ri td te tf tg th ev ew ti tj tk fa fb fc fd bm fe ff" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F809d3d0ce467&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&user=Sai+Lakshman&userId=809d3d0ce467&source=post_page-809d3d0ce467--post_author_info--402682bb13cb---------------------follow_profile-----------" rel="noopener follow">Follow</a></span></div></div></div><div class="ab co tl"><div class="tm tn to tp tq l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" href="https://medium.com/@sai_lakshman?source=post_page---post_author_info--402682bb13cb--------------------------------" rel="noopener follow"><h2 class="pw-author-name bf ts tt tu tv tw tx ty nh qh qi nl qk ql np qn qo bk"><span class="gn tr">Written by <!-- -->Sai Lakshman</span></h2></a><div class="rg ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" href="https://medium.com/@sai_lakshman/followers?source=post_page---post_author_info--402682bb13cb--------------------------------" rel="noopener follow">14 Followers</a></span></div><div class="bf b bg z du ab jd"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" href="https://medium.com/@sai_lakshman/following?source=post_page---post_author_info--402682bb13cb--------------------------------" rel="noopener follow">27 Following</a></div></div><div class="tz l"></div></div></div><div class="h k"><div class="ab"><span><a class="bf b bg z tc ri td te tf tg th ev ew ti tj tk fa fb fc fd bm fe ff" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F809d3d0ce467&operation=register&redirect=https%3A%2F%2Fdesign.zeta.in%2Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb&user=Sai+Lakshman&userId=809d3d0ce467&source=post_page-809d3d0ce467--post_author_info--402682bb13cb---------------------follow_profile-----------" rel="noopener follow">Follow</a></span></div></div></div><div class="ua bh ub uc"></div></div></div><div class="h k j"><div class="ua bh ub ud"></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ue ab kv ja"><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://help.medium.com/hc/en-us?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Help</p></a></div><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.statuspage.io/?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Status</p></a></div><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.com/about?autoplay=1&source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">About</p></a></div><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.com/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Careers</p></a></div><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="pressinquiries@medium.com?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Press</p></a></div><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://blog.medium.com/?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Blog</p></a></div><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Privacy</p></a></div><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Terms</p></a></div><div class="uf ug l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://speechify.com/medium?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Text to speech</p></a></div><div class="uf l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.com/business?source=post_page-----402682bb13cb--------------------------------" rel="noopener follow"><p class="bf b dv z du">Teams</p></a></div></div></div></div></div></div></div></div></div></div><script>window.__BUILD_ID__="main-20241122-185319-7bcdc08639"</script><script>window.__GRAPHQL_URI__ = "https://design.zeta.in/_/graphql"</script><script>window.__PRELOADED_STATE__ = {"algolia":{"queries":{}},"cache":{"experimentGroupSet":true,"reason":"This request is not using the cache middleware worker","group":"disabled","tags":["group-edgeCachePosts","post-402682bb13cb","user-809d3d0ce467","collection-b1d9ef1bb1cd"],"serverVariantState":"","middlewareEnabled":false,"cacheStatus":"DYNAMIC","shouldUseCache":false,"vary":[],"lohpSummerUpsellEnabled":false,"publicationHierarchyEnabledWeb":false,"postBottomResponsesEnabled":false},"client":{"hydrated":false,"isUs":false,"isNativeMedium":false,"isSafariMobile":false,"isSafari":false,"isFirefox":false,"routingEntity":{"type":"COLLECTION","id":"b1d9ef1bb1cd","explicit":true},"viewerIsBot":false},"debug":{"requestId":"cd1da106-7d29-4609-bda4-7c6deaf6fbd2","hybridDevServices":[],"originalSpanCarrier":{"traceparent":"00-e693d8633c6d828cd64e2323e54d24ac-fca5ec5268e0f235-01"}},"multiVote":{"clapsPerPost":{}},"navigation":{"branch":{"show":null,"hasRendered":null,"blockedByCTA":false},"hideGoogleOneTap":false,"hasRenderedAlternateUserBanner":null,"currentLocation":"https:\u002F\u002Fdesign.zeta.in\u002Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb","host":"design.zeta.in","hostname":"design.zeta.in","referrer":"","hasSetReferrer":false,"susiModal":{"step":null,"operation":"register"},"postRead":false,"partnerProgram":{"selectedCountryCode":null},"queryString":"?source=collection_home---4------17-----------------------"},"config":{"nodeEnv":"production","version":"main-20241122-185319-7bcdc08639","target":"production","productName":"Medium","publicUrl":"https:\u002F\u002Fcdn-client.medium.com\u002Flite","authDomain":"medium.com","authGoogleClientId":"216296035834-k1k6qe060s2tp2a2jam4ljdcms00sttg.apps.googleusercontent.com","favicon":"production","glyphUrl":"https:\u002F\u002Fglyph.medium.com","branchKey":"key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm","algolia":{"appId":"MQ57UUUQZ2","apiKeySearch":"394474ced050e3911ae2249ecc774921","indexPrefix":"medium_","host":"-dsn.algolia.net"},"recaptchaKey":"6Lfc37IUAAAAAKGGtC6rLS13R1Hrw_BqADfS1LRk","recaptcha3Key":"6Lf8R9wUAAAAABMI_85Wb8melS7Zj6ziuf99Yot5","recaptchaEnterpriseKeyId":"6Le-uGgpAAAAAPprRaokM8AKthQ9KNGdoxaGUvVp","datadog":{"applicationId":"6702d87d-a7e0-42fe-bbcb-95b469547ea0","clientToken":"pub853ea8d17ad6821d9f8f11861d23dfed","rumToken":"pubf9cc52896502b9413b68ba36fc0c7162","context":{"deployment":{"target":"production","tag":"main-20241122-185319-7bcdc08639","commit":"7bcdc08639c179dc5172558201a3fd3abc1b5db6"}},"datacenter":"us"},"googleAnalyticsCode":"G-7JY7T788PK","googlePay":{"apiVersion":"2","apiVersionMinor":"0","merchantId":"BCR2DN6TV7EMTGBM","merchantName":"Medium","instanceMerchantId":"13685562959212738550"},"applePay":{"version":3},"signInWallCustomDomainCollectionIds":["3a8144eabfe3","336d898217ee","61061eb0c96b","138adf9c44c","819cc2aaeee0"],"mediumMastodonDomainName":"me.dm","mediumOwnedAndOperatedCollectionIds":["8a9336e5bb4","b7e45b22fec3","193b68bd4fba","8d6b8a439e32","54c98c43354d","3f6ecf56618","d944778ce714","92d2092dc598","ae2a65f35510","1285ba81cada","544c7006046e","fc8964313712","40187e704f1c","88d9857e584e","7b6769f2748b","bcc38c8f6edf","cef6983b292","cb8577c9149e","444d13b52878","713d7dbc99b0","ef8e90590e66","191186aaafa0","55760f21cdc5","9dc80918cc93","bdc4052bbdba","8ccfed20cbb2"],"tierOneDomains":["medium.com","thebolditalic.com","arcdigital.media","towardsdatascience.com","uxdesign.cc","codeburst.io","psiloveyou.xyz","writingcooperative.com","entrepreneurshandbook.co","prototypr.io","betterhumans.coach.me","theascent.pub"],"topicsToFollow":["d61cf867d93f","8a146bc21b28","1eca0103fff3","4d562ee63426","aef1078a3ef5","e15e46793f8d","6158eb913466","55f1c20aba7a","3d18b94f6858","4861fee224fd","63c6f1f93ee","1d98b3a9a871","decb52b64abf","ae5d4995e225","830cded25262"],"topicToTagMappings":{"accessibility":"accessibility","addiction":"addiction","android-development":"android-development","art":"art","artificial-intelligence":"artificial-intelligence","astrology":"astrology","basic-income":"basic-income","beauty":"beauty","biotech":"biotech","blockchain":"blockchain","books":"books","business":"business","cannabis":"cannabis","cities":"cities","climate-change":"climate-change","comics":"comics","coronavirus":"coronavirus","creativity":"creativity","cryptocurrency":"cryptocurrency","culture":"culture","cybersecurity":"cybersecurity","data-science":"data-science","design":"design","digital-life":"digital-life","disability":"disability","economy":"economy","education":"education","equality":"equality","family":"family","feminism":"feminism","fiction":"fiction","film":"film","fitness":"fitness","food":"food","freelancing":"freelancing","future":"future","gadgets":"gadgets","gaming":"gaming","gun-control":"gun-control","health":"health","history":"history","humor":"humor","immigration":"immigration","ios-development":"ios-development","javascript":"javascript","justice":"justice","language":"language","leadership":"leadership","lgbtqia":"lgbtqia","lifestyle":"lifestyle","machine-learning":"machine-learning","makers":"makers","marketing":"marketing","math":"math","media":"media","mental-health":"mental-health","mindfulness":"mindfulness","money":"money","music":"music","neuroscience":"neuroscience","nonfiction":"nonfiction","outdoors":"outdoors","parenting":"parenting","pets":"pets","philosophy":"philosophy","photography":"photography","podcasts":"podcast","poetry":"poetry","politics":"politics","privacy":"privacy","product-management":"product-management","productivity":"productivity","programming":"programming","psychedelics":"psychedelics","psychology":"psychology","race":"race","relationships":"relationships","religion":"religion","remote-work":"remote-work","san-francisco":"san-francisco","science":"science","self":"self","self-driving-cars":"self-driving-cars","sexuality":"sexuality","social-media":"social-media","society":"society","software-engineering":"software-engineering","space":"space","spirituality":"spirituality","sports":"sports","startups":"startup","style":"style","technology":"technology","transportation":"transportation","travel":"travel","true-crime":"true-crime","tv":"tv","ux":"ux","venture-capital":"venture-capital","visual-design":"visual-design","work":"work","world":"world","writing":"writing"},"defaultImages":{"avatar":{"imageId":"1*dmbNkD5D-u45r44go_cf0g.png","height":150,"width":150},"orgLogo":{"imageId":"7*V1_7XP4snlmqrc_0Njontw.png","height":110,"width":500},"postLogo":{"imageId":"bd978bb536350a710e8efb012513429cabdc4c28700604261aeda246d0f980b7","height":810,"width":1440},"postPreviewImage":{"imageId":"1*hn4v1tCaJy7cWMyb0bpNpQ.png","height":386,"width":579}},"collectionStructuredData":{"8d6b8a439e32":{"name":"Elemental","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F980\u002F1*9ygdqoKprhwuTVKUM0DLPA@2x.png","width":980,"height":159}}},"3f6ecf56618":{"name":"Forge","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F596\u002F1*uULpIlImcO5TDuBZ6lm7Lg@2x.png","width":596,"height":183}}},"ae2a65f35510":{"name":"GEN","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F264\u002F1*RdVZMdvfV3YiZTw6mX7yWA.png","width":264,"height":140}}},"88d9857e584e":{"name":"LEVEL","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*JqYMhNX6KNNb2UlqGqO2WQ.png","width":540,"height":108}}},"7b6769f2748b":{"name":"Marker","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F383\u002F1*haCUs0wF6TgOOvfoY-jEoQ@2x.png","width":383,"height":92}}},"444d13b52878":{"name":"OneZero","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*cw32fIqCbRWzwJaoQw6BUg.png","width":540,"height":123}}},"8ccfed20cbb2":{"name":"Zora","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*tZUQqRcCCZDXjjiZ4bDvgQ.png","width":540,"height":106}}}},"embeddedPostIds":{"coronavirus":"cd3010f9d81f"},"sharedCdcMessaging":{"COVID_APPLICABLE_TAG_SLUGS":[],"COVID_APPLICABLE_TOPIC_NAMES":[],"COVID_APPLICABLE_TOPIC_NAMES_FOR_TOPIC_PAGE":[],"COVID_MESSAGES":{"tierA":{"text":"For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":66,"end":73,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"tierB":{"text":"Anyone can publish on Medium per our Policies, but we don’t fact-check every story. For more info about the coronavirus, see cdc.gov.","markups":[{"start":37,"end":45,"href":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Fcategories\u002F201931128-Policies-Safety"},{"start":125,"end":132,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"paywall":{"text":"This article has been made free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":56,"end":70,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":138,"end":145,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"unbound":{"text":"This article is free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":45,"end":59,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":127,"end":134,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]}},"COVID_BANNER_POST_ID_OVERRIDE_WHITELIST":["3b31a67bff4a"]},"sharedVoteMessaging":{"TAGS":["politics","election-2020","government","us-politics","election","2020-presidential-race","trump","donald-trump","democrats","republicans","congress","republican-party","democratic-party","biden","joe-biden","maga"],"TOPICS":["politics","election"],"MESSAGE":{"text":"Find out more about the U.S. election results here.","markups":[{"start":46,"end":50,"href":"https:\u002F\u002Fcookpolitical.com\u002F2020-national-popular-vote-tracker"}]},"EXCLUDE_POSTS":["397ef29e3ca5"]},"embedPostRules":[],"recircOptions":{"v1":{"limit":3},"v2":{"limit":8}},"braintreeClientKey":"production_zjkj96jm_m56f8fqpf7ngnrd4","braintree":{"enabled":true,"merchantId":"m56f8fqpf7ngnrd4","merchantAccountId":{"usd":"AMediumCorporation_instant","eur":"amediumcorporation_EUR","cad":"amediumcorporation_CAD"},"publicKey":"ds2nn34bg2z7j5gd","braintreeEnvironment":"production","dashboardUrl":"https:\u002F\u002Fwww.braintreegateway.com\u002Fmerchants","gracePeriodDurationInDays":14,"mediumMembershipPlanId":{"monthly":"ce105f8c57a3","monthlyV2":"e8a5e126-792b-4ee6-8fba-d574c1b02fc5","monthlyWithTrial":"d5ee3dbe3db8","monthlyPremium":"fa741a9b47a2","yearly":"a40ad4a43185","yearlyV2":"3815d7d6-b8ca-4224-9b8c-182f9047866e","yearlyStaff":"d74fb811198a","yearlyWithTrial":"b3bc7350e5c7","yearlyPremium":"e21bd2c12166","monthlyOneYearFree":"e6c0637a-2bad-4171-ab4f-3c268633d83c","monthly25PercentOffFirstYear":"235ecc62-0cdb-49ae-9378-726cd21c504b","monthly20PercentOffFirstYear":"ba518864-9c13-4a99-91ca-411bf0cac756","monthly15PercentOffFirstYear":"594c029b-9f89-43d5-88f8-8173af4e070e","monthly10PercentOffFirstYear":"c6c7bc9a-40f2-4b51-8126-e28511d5bdb0","monthlyForStudents":"629ebe51-da7d-41fd-8293-34cd2f2030a8","yearlyOneYearFree":"78ba7be9-0d9f-4ece-aa3e-b54b826f2bf1","yearly25PercentOffFirstYear":"2dbb010d-bb8f-4eeb-ad5c-a08509f42d34","yearly20PercentOffFirstYear":"47565488-435b-47f8-bf93-40d5fbe0ebc8","yearly15PercentOffFirstYear":"8259809b-0881-47d9-acf7-6c001c7f720f","yearly10PercentOffFirstYear":"9dd694fb-96e1-472c-8d9e-3c868d5c1506","yearlyForStudents":"e29345ef-ab1c-4234-95c5-70e50fe6bc23","monthlyCad":"p52orjkaceei","yearlyCad":"h4q9g2up9ktt"},"braintreeDiscountId":{"oneMonthFree":"MONTHS_FREE_01","threeMonthsFree":"MONTHS_FREE_03","sixMonthsFree":"MONTHS_FREE_06","fiftyPercentOffOneYear":"FIFTY_PERCENT_OFF_ONE_YEAR"},"3DSecureVersion":"2","defaultCurrency":"usd","providerPlanIdCurrency":{"4ycw":"usd","rz3b":"usd","3kqm":"usd","jzw6":"usd","c2q2":"usd","nnsw":"usd","q8qw":"usd","d9y6":"usd","fx7w":"cad","nwf2":"cad"}},"paypalClientId":"AXj1G4fotC2GE8KzWX9mSxCH1wmPE3nJglf4Z2ig_amnhvlMVX87otaq58niAg9iuLktVNF_1WCMnN7v","paypal":{"host":"https:\u002F\u002Fapi.paypal.com:443","clientMode":"production","serverMode":"live","webhookId":"4G466076A0294510S","monthlyPlan":{"planId":"P-9WR0658853113943TMU5FDQA","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlan":{"planId":"P-7N8963881P8875835MU5JOPQ","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oneYearGift":{"name":"Medium Membership (1 Year, Digital Gift Code)","description":"Unlimited access to the best and brightest stories on Medium. Gift codes can be redeemed at medium.com\u002Fredeem.","price":"50.00","currency":"USD","sku":"membership-gift-1-yr"},"oldMonthlyPlan":{"planId":"P-96U02458LM656772MJZUVH2Y","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlan":{"planId":"P-59P80963JF186412JJZU3SMI","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"monthlyPlanWithTrial":{"planId":"P-66C21969LR178604GJPVKUKY","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlanWithTrial":{"planId":"P-6XW32684EX226940VKCT2MFA","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oldMonthlyPlanNoSetupFee":{"planId":"P-4N046520HR188054PCJC7LJI","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlanNoSetupFee":{"planId":"P-7A4913502Y5181304CJEJMXQ","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"sdkUrl":"https:\u002F\u002Fwww.paypal.com\u002Fsdk\u002Fjs"},"stripePublishableKey":"pk_live_7FReX44VnNIInZwrIIx6ghjl","log":{"json":true,"level":"info"},"imageUploadMaxSizeMb":25,"staffPicks":{"title":"Staff Picks","catalogId":"c7bc6e1ee00f"}},"session":{"xsrf":""}}</script><script>window.__APOLLO_STATE__ = {"ROOT_QUERY":{"__typename":"Query","variantFlags":[{"__typename":"VariantFlag","name":"enable_lite_homepage","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_sprig","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_conversion_ranker_v2","valueType":{"__typename":"VariantFlagString","value":"control"}},{"__typename":"VariantFlag","name":"enable_lite_archive_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_iceland_nux","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_social_share_sheet","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ml_rank_rex_anno","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"onboarding_tags_from_top_views","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_rating_prompt_stories_read_threshold","valueType":{"__typename":"VariantFlagNumber","value":2}},{"__typename":"VariantFlag","name":"enable_cache_less_following_feed","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_legacy_feed_in_iceland","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_bayesian_average_pub_search","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lite_response_markup","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_pill_based_home_feed","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_topic_portals","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"disable_partner_program_enrollment","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_pp_v4","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_seamless_social_sharing","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"glyph_font_set","valueType":{"__typename":"VariantFlagString","value":"m2-unbound-source-serif-pro"}},{"__typename":"VariantFlag","name":"android_enable_lists_v2","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_mastodon_for_members","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"coronavirus_topic_recirc","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ios_easy_resubscribe","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"allow_access","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"signup_services","valueType":{"__typename":"VariantFlagString","value":"twitter,facebook,google,email,google-fastidv,google-one-tap,apple"}},{"__typename":"VariantFlag","name":"enable_explicit_signals","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_remove_twitter_onboarding_step","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_offline_reading","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_auto_follow_on_subscribe","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lo_homepage","valueType":{"__typename":"VariantFlagString","value":"control"}},{"__typename":"VariantFlag","name":"enable_medium2_kbfd","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_susi_redesign_ios","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_enable_verified_book_author","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_group_gifting","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_publication_hierarchy_web","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_updated_pub_recs_ui","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_pre_pp_v4","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_enable_friend_links_creation","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_google_webhook","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_verifications_service","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_rex_new_push_notification_endpoint","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_simplified_digest_v2_b","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_update_explore_wtf","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"reader_fair_distribution_non_qp","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_annual_premium_plan","valueType":{"__typename":"VariantFlagString","value":"4a442ace1476"}},{"__typename":"VariantFlag","name":"enable_braintree_paypal","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_members_only_audio","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_apple_webhook","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_new_stripe_customers","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_in_app_free_trial","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_bg_post_post","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_eventstats_event_processing","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_susi_redesign_android","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_friend_links_creation","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"browsable_stream_config_bucket","valueType":{"__typename":"VariantFlagString","value":"curated-topics"}},{"__typename":"VariantFlag","name":"enable_newsletter_lo_flow_custom_domains","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_update_topic_portals_wtf","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"limit_user_follows","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_verified_author","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_aurora_pub_follower_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_explicit_signals_updated_post_previews","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_marketing_emails","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"redefined_top_posts","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"price_smoke_test_monthly","valueType":{"__typename":"VariantFlagString","value":""}},{"__typename":"VariantFlag","name":"rex_generator_max_candidates","valueType":{"__typename":"VariantFlagNumber","value":1000}},{"__typename":"VariantFlag","name":"num_post_bottom_responses_to_show","valueType":{"__typename":"VariantFlagNumber","value":1}},{"__typename":"VariantFlag","name":"enable_ios_autorefresh","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_mastodon_for_members_username_selection","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tribute_landing_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_author_cards_byline","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"signin_services","valueType":{"__typename":"VariantFlagString","value":"twitter,facebook,google,email,google-fastidv,google-one-tap,apple"}},{"__typename":"VariantFlag","name":"textshots_userid","valueType":{"__typename":"VariantFlagString","value":""}},{"__typename":"VariantFlag","name":"enable_starspace","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"price_smoke_test_yearly","valueType":{"__typename":"VariantFlagString","value":""}},{"__typename":"VariantFlag","name":"android_enable_image_sharer","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_maim_the_meter","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_new_manage_membership_flow","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"goliath_externalsearch_enable_comment_deindexation","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_monthly_premium_plan","valueType":{"__typename":"VariantFlagString","value":"12a660186432"}},{"__typename":"VariantFlag","name":"skip_fs_cache_user_vals","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_moc_load_processor_all_recs_surfaces","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_enable_friend_links_postpage_banners","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_two_hour_refresh","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_client","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_diversification_rex","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lite_server_upstream_deadlines","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ranker_v10","valueType":{"__typename":"VariantFlagString","value":"control"}},{"__typename":"VariantFlag","name":"android_enable_editor_new_publishing_flow","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_mastodon_avatar_upload","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_intrinsic_automatic_actions","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tag_recs","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_recommended_publishers_query","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"allow_signup","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"can_receive_tips_v0","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_branch_io","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"can_send_tips_v0","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ios_offline_reading","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tipping_v0_android","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_sharer_create_post_share_key","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_premium_tier","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_abandoned_cart_promotion_email","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_see_pronouns","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"limit_post_referrers","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_footer_app_buttons","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_google_one_tap","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tick_landing_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"mobile_custom_app_icon","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_import","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_premium_tier_badge","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_rito_upstream_deadlines","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_enable_lock_responses","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_miro_v2","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_apple_pay","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_moc_load_processor_c","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_dynamic_aspirational_paywall","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_boost_nia_v01","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_webhook","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_creator_welcome_email","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_iceland_forced_android","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_moc_load_processor_first_story","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_recirc_model","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_dynamic_programming_paywall","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_google_pay","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lite_continue_this_thread","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_app_flirty_thirty","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_configure_pronouns","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_sharer_validate_post_share_key","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_speechify_widget","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_rex_aggregator_v2","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_monthly_plan","valueType":{"__typename":"VariantFlagString","value":"60e220181034"}},{"__typename":"VariantFlag","name":"enable_braintree_trial_membership","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_deprecate_legacy_providers_v3","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_rex_reading_history","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_billing_frequency_on_step2","valueType":{"__typename":"VariantFlagString","value":"group_1"}},{"__typename":"VariantFlag","name":"enable_switch_plan_premium_tier","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_integration","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tipping_v0_ios","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_friend_links_postpage_banners","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_syntax_highlight","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"reengagement_notification_duration","valueType":{"__typename":"VariantFlagNumber","value":3}},{"__typename":"VariantFlag","name":"enable_recaptcha_enterprise","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_author_cards","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_enable_home_post_menu","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_automod","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_pp_country_expansion","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_display_paywall_after_onboarding","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_apple_sign_in","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_entities_to_follow_v2","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ios_dynamic_paywall_programming","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_speechify_ios","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_annual_plan","valueType":{"__typename":"VariantFlagString","value":"2c754bcc2995"}},{"__typename":"VariantFlag","name":"enable_conversion_model_v2","valueType":{"__typename":"VariantFlagString","value":"group_2"}},{"__typename":"VariantFlag","name":"enable_ios_dynamic_paywall_aspiriational","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"allow_test_auth","valueType":{"__typename":"VariantFlagString","value":"disallow"}}],"viewer":null,"collectionByDomainOrSlug({\"domainOrSlug\":\"design.zeta.in\"})":{"__ref":"Collection:b1d9ef1bb1cd"},"postResult({\"id\":\"402682bb13cb\"})":{"__ref":"Post:402682bb13cb"}},"Collection:b1d9ef1bb1cd":{"__typename":"Collection","id":"b1d9ef1bb1cd","customStyleSheet":null,"colorPalette":{"__typename":"ColorPalette","highlightSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FFF8EEFF","point":0},{"__typename":"ColorPoint","color":"#FFF7ECFF","point":0.1},{"__typename":"ColorPoint","color":"#FFF6E9FF","point":0.2},{"__typename":"ColorPoint","color":"#FFF5E6FF","point":0.3},{"__typename":"ColorPoint","color":"#FFF4E4FF","point":0.4},{"__typename":"ColorPoint","color":"#FFF3E1FF","point":0.5},{"__typename":"ColorPoint","color":"#FFF1DEFF","point":0.6},{"__typename":"ColorPoint","color":"#FFF0DBFF","point":0.7},{"__typename":"ColorPoint","color":"#FFEFD9FF","point":0.8},{"__typename":"ColorPoint","color":"#FFEED6FF","point":0.9},{"__typename":"ColorPoint","color":"#FFEDD3FF","point":1}]},"defaultBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FF9474C6","point":0},{"__typename":"ColorPoint","color":"#FF896CB6","point":0.1},{"__typename":"ColorPoint","color":"#FF7E65A6","point":0.2},{"__typename":"ColorPoint","color":"#FF735D96","point":0.3},{"__typename":"ColorPoint","color":"#FF685586","point":0.4},{"__typename":"ColorPoint","color":"#FF5C4C76","point":0.5},{"__typename":"ColorPoint","color":"#FF504366","point":0.6},{"__typename":"ColorPoint","color":"#FF443956","point":0.7},{"__typename":"ColorPoint","color":"#FF382F46","point":0.8},{"__typename":"ColorPoint","color":"#FF2A2435","point":0.9},{"__typename":"ColorPoint","color":"#FF1C1824","point":1}]},"tintBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FF4B2878","colorPoints":[{"__typename":"ColorPoint","color":"#FF4B2878","point":0},{"__typename":"ColorPoint","color":"#FF61448C","point":0.1},{"__typename":"ColorPoint","color":"#FF765D9E","point":0.2},{"__typename":"ColorPoint","color":"#FF8A73AF","point":0.3},{"__typename":"ColorPoint","color":"#FF9D89BE","point":0.4},{"__typename":"ColorPoint","color":"#FFB09DCD","point":0.5},{"__typename":"ColorPoint","color":"#FFC1B1DB","point":0.6},{"__typename":"ColorPoint","color":"#FFD3C4E8","point":0.7},{"__typename":"ColorPoint","color":"#FFE4D7F5","point":0.8},{"__typename":"ColorPoint","color":"#FFF4E9FF","point":0.9},{"__typename":"ColorPoint","color":"#FFFFFBFF","point":1}]}},"favicon":{"__ref":"ImageMetadata:1*7FG4sDTdzgBNYQL3onKlXQ.png"},"domain":"design.zeta.in","slug":"zeta-design","googleAnalyticsId":null,"editors":[{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:c89f0f029bca"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:4acc1a4e4abb"}}],"name":"Zeta Design","avatar":{"__ref":"ImageMetadata:1*7FG4sDTdzgBNYQL3onKlXQ.png"},"description":"Perspectives on designing & building digital products for India","subscriberCount":2026,"latestPostsConnection({\"paging\":{\"limit\":1}})":{"__typename":"PostConnection","posts":[{"__ref":"Post:b107f857e142"}]},"viewerEdge":{"__ref":"CollectionViewerEdge:collectionId:b1d9ef1bb1cd-viewerId:lo_01198530914e"},"twitterUsername":"zetaindia","facebookPageId":null,"logo":{"__ref":"ImageMetadata:1*Vjz4OlxhDF68YL7pwRL-Rg.png"}},"ImageMetadata:1*7FG4sDTdzgBNYQL3onKlXQ.png":{"__typename":"ImageMetadata","id":"1*7FG4sDTdzgBNYQL3onKlXQ.png"},"User:c89f0f029bca":{"__typename":"User","id":"c89f0f029bca"},"User:4acc1a4e4abb":{"__typename":"User","id":"4acc1a4e4abb"},"User:f4782ea9c444":{"__typename":"User","id":"f4782ea9c444","customDomainState":{"__typename":"CustomDomainState","live":{"__typename":"CustomDomain","domain":"creativetechie.medium.com"}},"hasSubdomain":true,"username":"creativetechie"},"Post:b107f857e142":{"__typename":"Post","id":"b107f857e142","firstPublishedAt":1725604078487,"creator":{"__ref":"User:f4782ea9c444"},"collection":{"__ref":"Collection:b1d9ef1bb1cd"},"isSeries":false,"mediumUrl":"https:\u002F\u002Fdesign.zeta.in\u002Frocket-rides-and-roadmap-navigating-beyond-mvp-b107f857e142","sequence":null,"uniqueSlug":"rocket-rides-and-roadmap-navigating-beyond-mvp-b107f857e142"},"LinkedAccounts:809d3d0ce467":{"__typename":"LinkedAccounts","mastodon":null,"id":"809d3d0ce467"},"UserViewerEdge:userId:809d3d0ce467-viewerId:lo_01198530914e":{"__typename":"UserViewerEdge","id":"userId:809d3d0ce467-viewerId:lo_01198530914e","isFollowing":false,"isUser":false,"isMuting":false},"NewsletterV3:7b858537659e":{"__typename":"NewsletterV3","id":"7b858537659e","type":"NEWSLETTER_TYPE_AUTHOR","slug":"809d3d0ce467","name":"809d3d0ce467","collection":null,"user":{"__ref":"User:809d3d0ce467"}},"User:809d3d0ce467":{"__typename":"User","id":"809d3d0ce467","name":"Sai Lakshman","username":"sai_lakshman","newsletterV3":{"__ref":"NewsletterV3:7b858537659e"},"linkedAccounts":{"__ref":"LinkedAccounts:809d3d0ce467"},"isSuspended":false,"imageId":"1*0ECTVtKvhAKBcMqtkE-q1Q.png","mediumMemberAt":0,"verifications":{"__typename":"VerifiedInfo","isBookAuthor":false},"socialStats":{"__typename":"SocialStats","followerCount":14,"followingCount":23,"collectionFollowingCount":4},"customDomainState":null,"hasSubdomain":false,"bio":"","isPartnerProgramEnrolled":false,"viewerEdge":{"__ref":"UserViewerEdge:userId:809d3d0ce467-viewerId:lo_01198530914e"},"viewerIsUser":false,"postSubscribeMembershipUpsellShownAt":0,"membership":null,"allowNotes":true,"twitterScreenName":""},"Paragraph:b2f90715cfb1_0":{"__typename":"Paragraph","id":"b2f90715cfb1_0","name":"4410","type":"H3","href":null,"layout":null,"metadata":null,"text":"Breaking the code: How did we build our Figma plugin?","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_1":{"__typename":"Paragraph","id":"b2f90715cfb1_1","name":"a046","type":"P","href":null,"layout":null,"metadata":null,"text":"Learn how Zeta Design built its first Figma plugin.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":51,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*Buv9AgzhmtMU6dkKrqZznw.png":{"__typename":"ImageMetadata","id":"1*Buv9AgzhmtMU6dkKrqZznw.png","originalHeight":1240,"originalWidth":2880,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_2":{"__typename":"Paragraph","id":"b2f90715cfb1_2","name":"69af","type":"IMG","href":null,"layout":"FULL_WIDTH","metadata":{"__ref":"ImageMetadata:1*Buv9AgzhmtMU6dkKrqZznw.png"},"text":"Illustrations by Aakansha Menon.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":17,"end":31,"href":null,"anchorType":"USER","userId":"a94240008425","linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_3":{"__typename":"Paragraph","id":"b2f90715cfb1_3","name":"2896","type":"P","href":null,"layout":null,"metadata":null,"text":"Co-authored by Manik Chugh and Sneh Singh. Illustrations by Aakansha Menon.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":15,"end":26,"href":null,"anchorType":"USER","userId":"924d6ac61d43","linkMetadata":null},{"__typename":"Markup","type":"A","start":31,"end":41,"href":null,"anchorType":"USER","userId":"289f1789610e","linkMetadata":null},{"__typename":"Markup","type":"A","start":60,"end":74,"href":null,"anchorType":"USER","userId":"a94240008425","linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":0,"end":75,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_4":{"__typename":"Paragraph","id":"b2f90715cfb1_4","name":"9241","type":"P","href":null,"layout":null,"metadata":null,"text":"Writing UX copies can be a little frustrating and confusing, and sometimes we are unsure about how to get the right word. To crack the code for the UX copies, we at Zeta Design wanted to build a Figma plugin for the larger design community. The plugin is called the Ghost UXWriter and has a set of UX copies cataloged and categorized with a voice and tone variation ranging from plain, casual to playful. The intention to build this Figma plugin originated from our Medium blog post, ‘Designing voice and tone for error messages.’","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":266,"end":280,"href":"https:\u002F\u002Fwww.figma.com\u002Fcommunity\u002Fplugin\u002F960778033371641874\u002FGhost-UXWriter","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":485,"end":528,"href":"https:\u002F\u002Fdesign.zeta.in\u002Fdesigning-voice-and-tone-for-error-messages-185676c10627#:~:text=The%20significance%20of%20voice%20and,are%20not%20given%20enough%20importance.&text=The%20voice%20of%20the%20error,bringing%20out%20the%20brand%20personality.","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_5":{"__typename":"Paragraph","id":"b2f90715cfb1_5","name":"7bf2","type":"P","href":null,"layout":null,"metadata":null,"text":"This plugin can be used by designers, writers, and developers, making it a go-to plugin every time someone wants a hand with UX copywriting.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_6":{"__typename":"Paragraph","id":"b2f90715cfb1_6","name":"32c6","type":"P","href":null,"layout":null,"metadata":null,"text":"The journey of building our Figma plugin can be divided into three-phases — writing UX copies, designing the interface, and developing the plugin.This blog will focus on the third phase, the development phase, to unravel the pitfalls and the havens while developing a Figma plugin.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_7":{"__typename":"Paragraph","id":"b2f90715cfb1_7","name":"7d2e","type":"H3","href":null,"layout":null,"metadata":null,"text":"How does the plugin work?","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_8":{"__typename":"Paragraph","id":"b2f90715cfb1_8","name":"0a7a","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 1: Download the plugin from Figma community, search Ghost UXWriter","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":57,"end":71,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":0,"end":71,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_9":{"__typename":"Paragraph","id":"b2f90715cfb1_9","name":"2ebf","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 2: Open the plugin on your artboard","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":40,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_10":{"__typename":"Paragraph","id":"b2f90715cfb1_10","name":"7059","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 3: Search for your copy or look through the different categories of the copies","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":83,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_11":{"__typename":"Paragraph","id":"b2f90715cfb1_11","name":"6dac","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 4: Select the type of error you are looking for. You will get three different copies for each error","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":104,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_12":{"__typename":"Paragraph","id":"b2f90715cfb1_12","name":"bf3e","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 5: Tap on the cards to insert text in your frames","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":54,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_13":{"__typename":"Paragraph","id":"b2f90715cfb1_13","name":"8c99","type":"P","href":null,"layout":null,"metadata":null,"text":"And you are all geared up to make your UX copies more fun and exciting 😎","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":54,"end":71,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*rMobpdLQcd84Sp-9mza8Sw.gif":{"__typename":"ImageMetadata","id":"1*rMobpdLQcd84Sp-9mza8Sw.gif","originalHeight":1880,"originalWidth":3360,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_14":{"__typename":"Paragraph","id":"b2f90715cfb1_14","name":"d5a1","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*rMobpdLQcd84Sp-9mza8Sw.gif"},"text":"Ghost UXWriter in action","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":14,"href":"https:\u002F\u002Fwww.figma.com\u002Fcommunity\u002Fplugin\u002F960778033371641874\u002FGhost-UXWriter","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_15":{"__typename":"Paragraph","id":"b2f90715cfb1_15","name":"f51b","type":"P","href":null,"layout":null,"metadata":null,"text":"Currently, in the Ghost UXWriter, we support the following features:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_16":{"__typename":"Paragraph","id":"b2f90715cfb1_16","name":"69a7","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Plugin tutorial, onboarding screens","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_17":{"__typename":"Paragraph","id":"b2f90715cfb1_17","name":"1d3b","type":"ULI","href":null,"layout":null,"metadata":null,"text":"User login","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_18":{"__typename":"Paragraph","id":"b2f90715cfb1_18","name":"b762","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Seamless Search Engine","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_19":{"__typename":"Paragraph","id":"b2f90715cfb1_19","name":"eb1e","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Different UX categories with the variation of voice and tone ranging from plain, casual to playful","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_20":{"__typename":"Paragraph","id":"b2f90715cfb1_20","name":"3013","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Easily Insert selected UX copy in artboard","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_21":{"__typename":"Paragraph","id":"b2f90715cfb1_21","name":"1e3a","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Copy text to clipboard","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_22":{"__typename":"Paragraph","id":"b2f90715cfb1_22","name":"0691","type":"ULI","href":null,"layout":null,"metadata":null,"text":"User Profile","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_23":{"__typename":"Paragraph","id":"b2f90715cfb1_23","name":"8a24","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Bookmark favourite copies","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_24":{"__typename":"Paragraph","id":"b2f90715cfb1_24","name":"d89c","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Add custom copies as MyCopies","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_25":{"__typename":"Paragraph","id":"b2f90715cfb1_25","name":"8000","type":"H3","href":null,"layout":null,"metadata":null,"text":"Discovering design","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_26":{"__typename":"Paragraph","id":"b2f90715cfb1_26","name":"1b31","type":"P","href":null,"layout":null,"metadata":null,"text":"In the initial phase of design, we began with a low-fidelity wireframe to brainstorm the ideas from onboarding users to get them to use the plugin’s main features. Next, we converted them to high-fidelity screen-based designs, covering end-to-end plugin flows with monochromatic colors.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_27":{"__typename":"Paragraph","id":"b2f90715cfb1_27","name":"efe2","type":"P","href":null,"layout":null,"metadata":null,"text":"While designing for the Figma plugin frame, we had to solve for the scale of things. We had to create a small screen window that would fit into a large screen device. Our objective was to consume the minimum space of the designer’s artboard and give the majority of the area to their canvas. Hence, we settled onto a 360px width plugin window size and constrained our flows to that.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*Udi9NtgHYs0iYxEcyuaN_w.png":{"__typename":"ImageMetadata","id":"1*Udi9NtgHYs0iYxEcyuaN_w.png","originalHeight":1440,"originalWidth":2880,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_28":{"__typename":"Paragraph","id":"b2f90715cfb1_28","name":"b912","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*Udi9NtgHYs0iYxEcyuaN_w.png"},"text":"Ghost UXWriter’s design evolution","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":16,"href":"https:\u002F\u002Fwww.figma.com\u002Fcommunity\u002Fplugin\u002F960778033371641874\u002FGhost-UXWriter","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_29":{"__typename":"Paragraph","id":"b2f90715cfb1_29","name":"dee3","type":"H4","href":null,"layout":null,"metadata":null,"text":"Picking the right color","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_30":{"__typename":"Paragraph","id":"b2f90715cfb1_30","name":"64d6","type":"P","href":null,"layout":null,"metadata":null,"text":"Our initial plugin was designed in monochromatic color, and it was ready to ship. But, we felt the colors reflected an uptight formal-looking product, but that is not what Ghost UXWriter stood for.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_31":{"__typename":"Paragraph","id":"b2f90715cfb1_31","name":"4973","type":"P","href":null,"layout":null,"metadata":null,"text":"The core of Ghost UXWriter lies in being a hospitable, lighthearted, and warm plugin. We restarted with rounds of iterating the color variations, starting from pastel, vibrant to even rich premium colors, we still couldn’t find the perfect color for our product personality. After trying different color sets, we started exploring the gradient’s territory, and then we had our hands on mesh gradients.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_32":{"__typename":"Paragraph","id":"b2f90715cfb1_32","name":"d391","type":"P","href":null,"layout":null,"metadata":null,"text":"We found a perfect match to our product’s personality with that exploration, and without a doubt, we closed on that final iteration with Mesh gradients. The Mesh gradient impacted every product element, starting from updating the logo colors to the Figma community banners and all the promotional content.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_33":{"__typename":"Paragraph","id":"b2f90715cfb1_33","name":"6ef5","type":"P","href":null,"layout":null,"metadata":null,"text":"And that’s how we closed our plugin designs with all our iterations and explorations. You can find some of the flows here.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":117,"end":121,"href":"https:\u002F\u002Fwww.figma.com\u002Ffile\u002FKC61Vsg7XRVYIFRB6PoP6h\u002FPlugin-design-journey?node-id=0%3A1","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_34":{"__typename":"Paragraph","id":"b2f90715cfb1_34","name":"f8e3","type":"H3","href":null,"layout":null,"metadata":null,"text":"Dismantling the code","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*Mzg-gzJoyRZAWgnUlBsU2A.png":{"__typename":"ImageMetadata","id":"1*Mzg-gzJoyRZAWgnUlBsU2A.png","originalHeight":720,"originalWidth":1440,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_35":{"__typename":"Paragraph","id":"b2f90715cfb1_35","name":"d19c","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*Mzg-gzJoyRZAWgnUlBsU2A.png"},"text":"Our development process","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_36":{"__typename":"Paragraph","id":"b2f90715cfb1_36","name":"0bfd","type":"P","href":null,"layout":null,"metadata":null,"text":"The Figma plugin development ecosystem was uncharted territory for us. On that account, we prepped ourselves with research on all documentation regarding the Figma plugin. It helped us explore the possibilities and limitations with Figma plugins, which would eventually help us build a full-fledged one.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":130,"end":143,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fintro\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_37":{"__typename":"Paragraph","id":"b2f90715cfb1_37","name":"ec61","type":"H4","href":null,"layout":null,"metadata":null,"text":"The basic setup","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_38":{"__typename":"Paragraph","id":"b2f90715cfb1_38","name":"d014","type":"P","href":null,"layout":null,"metadata":null,"text":"After the deep-dive research, we started building the plugin with the help of Figma’s Setup guide. Following are the initial steps we took to set up the plugin:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":85,"end":97,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fsetup\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_39":{"__typename":"Paragraph","id":"b2f90715cfb1_39","name":"0f18","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 1: Install VSCode editor as suggested by Figma for writing code","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":68,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_40":{"__typename":"Paragraph","id":"b2f90715cfb1_40","name":"d0d4","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 2: Install NodeJs, NPM package manager, TypeScript to set up a local javascript development environment necessary to build the plugin","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":138,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_41":{"__typename":"Paragraph","id":"b2f90715cfb1_41","name":"5c11","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 3: Install Figma desktop app as development and testing the plugin only happens in the desktop app","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":103,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*9fi--50WfUWJKzS1CsP1IQ.gif":{"__typename":"ImageMetadata","id":"1*9fi--50WfUWJKzS1CsP1IQ.gif","originalHeight":2100,"originalWidth":3360,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_42":{"__typename":"Paragraph","id":"b2f90715cfb1_42","name":"e340","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*9fi--50WfUWJKzS1CsP1IQ.gif"},"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_43":{"__typename":"Paragraph","id":"b2f90715cfb1_43","name":"1d7a","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 4: Navigate to Profile Menu \u003E Plugins \u003E Development \u003E … to browse the plugins","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":82,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_44":{"__typename":"Paragraph","id":"b2f90715cfb1_44","name":"58ce","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 5: Create a new plugin using one of the default templates, select “With UI & browser APIs” for full configuration or load an existing manifest.json file","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":157,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_45":{"__typename":"Paragraph","id":"b2f90715cfb1_45","name":"8bc8","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 6: If the plugin is created for the first time, a prompt screen will appear to ‘Save’ the project","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":102,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_46":{"__typename":"Paragraph","id":"b2f90715cfb1_46","name":"bc5b","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 7: Open the project folder with VSCode editor or in the terminal navigate to the project folder using “cd folder-path ” and type “code .” to open the project","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":162,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_47":{"__typename":"Paragraph","id":"b2f90715cfb1_47","name":"df81","type":"P","href":null,"layout":null,"metadata":null,"text":"Step 8: UI.html, Code.ts, and manifest.json are the files responsible for User interface, plugin logic & communication with Figma APIs, and configuration","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":153,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_48":{"__typename":"Paragraph","id":"b2f90715cfb1_48","name":"80af","type":"P","href":null,"layout":null,"metadata":null,"text":"If you’re using vanilla javascript to build the project, you’ll only have to work on these files. Alternatively, you can use Webpack module bundler, ReactJs, VueJs, or any other javascript UI framework\u002Flibrary to develop the plugin. These are advanced steps and require further configuration.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":125,"end":147,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fbundling-webpack\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":149,"end":156,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fbundling-react\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_49":{"__typename":"Paragraph","id":"b2f90715cfb1_49","name":"63f3","type":"P","href":null,"layout":null,"metadata":null,"text":"We relied on only two files, ui.html and code.ts for the complete project. This can get clumsy when you work on a complex plugin, if you want to break your project into multiple files or components, use a bundler\u002Fframework to write your code.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_50":{"__typename":"Paragraph","id":"b2f90715cfb1_50","name":"1064","type":"H4","href":null,"layout":null,"metadata":null,"text":"Bridging Google Sheet with code","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_51":{"__typename":"Paragraph","id":"b2f90715cfb1_51","name":"598a","type":"P","href":null,"layout":null,"metadata":null,"text":"After setting up the plugin, we went on to work on the Ghost UXWriter. Ghost UXWriter is a content-heavy plugin; therefore, to solve our technical and content-related bottlenecks, we followed a straightforward approach using Firebase for back-end and Google Sheets to host our content. We used vanilla Javascript to build most of our plugin, some TypeScript for working with Figma APIs, plain CSS & HTML for the markup, and inline SVG for media.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":123,"end":124,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*RyhSJWmaTRpduiqKOdxxAA.jpeg":{"__typename":"ImageMetadata","id":"1*RyhSJWmaTRpduiqKOdxxAA.jpeg","originalHeight":720,"originalWidth":1440,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_52":{"__typename":"Paragraph","id":"b2f90715cfb1_52","name":"fa8f","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*RyhSJWmaTRpduiqKOdxxAA.jpeg"},"text":"Connecting Google Sheets to Firebase","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_53":{"__typename":"Paragraph","id":"b2f90715cfb1_53","name":"2549","type":"P","href":null,"layout":null,"metadata":null,"text":"Our development journey started from the Google Sheet, where we first curated our content and later used Apps Script for Google Sheet to store this data in the Firebase’s Firestore NoSQL database. With Google Sheet now synced with the database, content updates happen more seamlessly.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":104,"end":133,"href":"https:\u002F\u002Fdevelopers.google.com\u002Fapps-script\u002Fguides\u002Fsheets","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":171,"end":180,"href":"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Ffirestore","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_54":{"__typename":"Paragraph","id":"b2f90715cfb1_54","name":"8090","type":"P","href":null,"layout":null,"metadata":null,"text":"In the initial plugin launch, we avoided overcomplicating the back-end dashboards, therefore Google Sheets became our primary content source and helped the team to actively collaborate on the content.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_55":{"__typename":"Paragraph","id":"b2f90715cfb1_55","name":"f227","type":"H4","href":null,"layout":null,"metadata":null,"text":"Jumping through the hoops of authentication","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*xIGpaz1oRGAvns699XI9pA.gif":{"__typename":"ImageMetadata","id":"1*xIGpaz1oRGAvns699XI9pA.gif","originalHeight":616,"originalWidth":1145,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_56":{"__typename":"Paragraph","id":"b2f90715cfb1_56","name":"6e65","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*xIGpaz1oRGAvns699XI9pA.gif"},"text":"Google authentication in Ghost UXWriter","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":25,"end":39,"href":"https:\u002F\u002Fwww.figma.com\u002Fcommunity\u002Fplugin\u002F960778033371641874\u002FGhost-UXWriter","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_57":{"__typename":"Paragraph","id":"b2f90715cfb1_57","name":"0555","type":"P","href":null,"layout":null,"metadata":null,"text":"We wanted to implement a social sign-in for the plugin. There was a hurdle as the Figma plugin doesn’t allow developers to set browser cookies.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_58":{"__typename":"Paragraph","id":"b2f90715cfb1_58","name":"1a44","type":"P","href":null,"layout":null,"metadata":null,"text":"Plugins in Figma are loaded in iframe, giving away certain technical limitations. These limitations include the unavailability of browser APIs (majorly cookies and localStorage) to support authentication and analytics services. Therefore, for implementing a social sign-in, additional steps were required. Even though Figma provides figma.clientStorage API, as an alternative to native locaStorage API, it doesn’t suit well for our use case.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":333,"end":352,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fapi\u002Ffigma-clientStorage\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_59":{"__typename":"Paragraph","id":"b2f90715cfb1_59","name":"ed9d","type":"P","href":null,"layout":null,"metadata":null,"text":"TLDR; Most of the authentication and analytics services that rely on browser cookies don’t work because of the Figma plugin development limitations.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":6,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_60":{"__typename":"Paragraph","id":"b2f90715cfb1_60","name":"8949","type":"P","href":null,"layout":null,"metadata":null,"text":"To resolve this issue, we performed our authentication by opening a browser tab and sent the user data back to the plugin after a successful login.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_61":{"__typename":"Paragraph","id":"b2f90715cfb1_61","name":"f2da","type":"BQ","href":null,"layout":null,"metadata":null,"text":"Whenever a user clicks on the signup button in the plugin, we register a new reference in the Firestore database to listen for login status actively. A new screen opens up in the browser where authentication is carried out using Firebase auth, and once the authentication is successful, we send back user details to plugin UI. We use unique reference IDs to authenticate these requests between the plugin and browser interface.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":77,"end":86,"href":"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Freference\u002Fjs\u002Ffirebase.firestore.DocumentReference","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":229,"end":242,"href":"https:\u002F\u002Ffirebase.google.com\u002Fproducts\u002Fauth","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_62":{"__typename":"Paragraph","id":"b2f90715cfb1_62","name":"42cb","type":"P","href":null,"layout":null,"metadata":null,"text":"These login URLs are also configured with additional restrictions, such as the link is for single use only, reloading the login page will fail the request, and URL with an unregistered reference ID will fail the login attempt. We used strict access rules for our Firestore database and suggested configuring them carefully when you are working with firebase. Below are a few valuable links for working with Firestore rules on your production website.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_63":{"__typename":"Paragraph","id":"b2f90715cfb1_63","name":"5226","type":"P","href":null,"layout":null,"metadata":null,"text":"1. https:\u002F\u002Ffireship.io\u002Fsnippets\u002Ffirestore-rules-recipes\u002F","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":3,"end":56,"href":"https:\u002F\u002Ffireship.io\u002Fsnippets\u002Ffirestore-rules-recipes\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_64":{"__typename":"Paragraph","id":"b2f90715cfb1_64","name":"c849","type":"P","href":null,"layout":null,"metadata":null,"text":"2. https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Freference\u002Frules\u002Frules.firestore","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":3,"end":67,"href":"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Freference\u002Frules\u002Frules.firestore","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_65":{"__typename":"Paragraph","id":"b2f90715cfb1_65","name":"11d3","type":"P","href":null,"layout":null,"metadata":null,"text":"If you don’t want to depend on Firebase for any of your flows, you can refer to this article on implementing a custom authentication through your server.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":80,"end":93,"href":"https:\u002F\u002Fpaper.dropbox.com\u002Fdoc\u002FOAuth-with-Figma-Plugins-yErww0GkGBaYjgUmBeA4Z","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_66":{"__typename":"Paragraph","id":"b2f90715cfb1_66","name":"0af1","type":"H4","href":null,"layout":null,"metadata":null,"text":"The common constraints","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_67":{"__typename":"Paragraph","id":"b2f90715cfb1_67","name":"8596","type":"P","href":null,"layout":null,"metadata":null,"text":"Even though there are so many possibilities with Figma APIs for developing plugins, we also encountered few API limitations in our journey. In the Ghost UXWriter plugin, we weren’t able to replace text fields with mixed fonts. This is a Figma API limitation to replace text nodes with mixed types, and we had to notify users about this explicitly. So if you are planning on building a Figma Plugin DYOR (Do own your research) or join the Figma community Slack channel for any queries related to limitations of APIs.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":49,"end":59,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fapi\u002Fapi-overview\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":214,"end":225,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fapi\u002Fproperties\u002Ffigma-mixed\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*OJNhIwx0aGgq-Q_swSaAUg.png":{"__typename":"ImageMetadata","id":"1*OJNhIwx0aGgq-Q_swSaAUg.png","originalHeight":1440,"originalWidth":2880,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_68":{"__typename":"Paragraph","id":"b2f90715cfb1_68","name":"08b7","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*OJNhIwx0aGgq-Q_swSaAUg.png"},"text":"Developmental hurdles and Figma platform limitations","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_69":{"__typename":"Paragraph","id":"b2f90715cfb1_69","name":"af16","type":"P","href":null,"layout":null,"metadata":null,"text":"Another major constraint we faced while developing the plugin was that we were unable to see code changes live in real-time. It made the experience quite time-consuming as we had to restart the plugin every time in order to check the output when there was a code change. Since the Figma plugins use web technologies, we built the initial screens and UI that doesn’t rely on Figma APIs using the browser by running a localhost server that watches the code for live changes. This saved us a ton of time in perfecting the plugin UI.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_70":{"__typename":"Paragraph","id":"b2f90715cfb1_70","name":"f379","type":"P","href":null,"layout":null,"metadata":null,"text":"Furthermore, we were also finding it very difficult to debug the plugin for styling and code errors, but now that we have a browser interface, we could quickly check our CSS and rely on the browser’s dev tools for most of the debugging. Despite Figma providing a console and Developer VM option for debugging with Figma, it might look cluttered in the initial phases and is not easy to check styling and live reloads. There’s no other option but to use Developer VM when working with Figma APIs for your plugin. For more information on how plugins run inside Figma, refer here.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":299,"end":319,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fdebugging\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":572,"end":576,"href":"https:\u002F\u002Fwww.figma.com\u002Fplugin-docs\u002Fhow-plugins-run\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_71":{"__typename":"Paragraph","id":"b2f90715cfb1_71","name":"57ab","type":"H3","href":null,"layout":null,"metadata":null,"text":"🎯 The road ahead","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_72":{"__typename":"Paragraph","id":"b2f90715cfb1_72","name":"eb6b","type":"P","href":null,"layout":null,"metadata":null,"text":"Ghost UXWriter is our first Figma plugin, and the journey to build something new was exhilarating and enthralling. Throughout the plugin development process, we preferred to use plain technologies. It made things more straightforward and easier to learn and understand how to build our first plugin. Currently, we are on the lookout for adding more new features and making UX copies more accessible and humane.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":114,"end":115,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_73":{"__typename":"Paragraph","id":"b2f90715cfb1_73","name":"16c8","type":"P","href":null,"layout":null,"metadata":null,"text":"Do check out Ghost UXWriter and tell us how you feel about the plugin in the comments.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":13,"end":27,"href":"https:\u002F\u002Fwww.figma.com\u002Fcommunity\u002Fplugin\u002F960778033371641874\u002FGhost-UXWriter","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*cUHv14XidnLpIq-Qs8A1Lw.gif":{"__typename":"ImageMetadata","id":"1*cUHv14XidnLpIq-Qs8A1Lw.gif","originalHeight":220,"originalWidth":337,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b2f90715cfb1_74":{"__typename":"Paragraph","id":"b2f90715cfb1_74","name":"069a","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*cUHv14XidnLpIq-Qs8A1Lw.gif"},"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_75":{"__typename":"Paragraph","id":"b2f90715cfb1_75","name":"4d6a","type":"P","href":null,"layout":null,"metadata":null,"text":"And if you are stuck anywhere or have any queries, reach out to the Figma Plugins Slack channel to get in touch with fellow plugin developers, discuss development & launch issues, get quick updates on the latest API releases. The whole community is very engaging and resourceful.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":68,"end":95,"href":"https:\u002F\u002Ffigmaplugins.slack.com\u002Fjoin\u002Fshared_invite\u002Fzt-8sv6h6hy-vJ0t3G8uT7l~g2KuY_6WvQ#\u002Fshared-invite\u002Femail","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_76":{"__typename":"Paragraph","id":"b2f90715cfb1_76","name":"3272","type":"H4","href":null,"layout":null,"metadata":null,"text":"📚 Useful Resources :","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":3,"end":21,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_77":{"__typename":"Paragraph","id":"b2f90715cfb1_77","name":"9aa6","type":"P","href":null,"layout":null,"metadata":null,"text":"List of open-source Figma plugins to take inspiration from -https:\u002F\u002Fgithub.com\u002Fthomas-lowry\u002Ffigma-plugins-on-github","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":60,"end":115,"href":"https:\u002F\u002Fgithub.com\u002Fthomas-lowry\u002Ffigma-plugins-on-github","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_78":{"__typename":"Paragraph","id":"b2f90715cfb1_78","name":"2f97","type":"P","href":null,"layout":null,"metadata":null,"text":"Localhost server extension for VSCode - https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=ritwickdey.LiveServer","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":40,"end":113,"href":"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=ritwickdey.LiveServer","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b2f90715cfb1_79":{"__typename":"Paragraph","id":"b2f90715cfb1_79","name":"23c9","type":"P","href":null,"layout":null,"metadata":null,"text":"Feel free to reach out to @sai @manik @sneh if you face any issues with your plugin or message us at @zeta for community collaborations.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":26,"end":30,"href":"https:\u002F\u002Finstagram.com\u002Flakshm_n","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":31,"end":37,"href":"https:\u002F\u002Fwww.instagram.com\u002Fmanikchugh\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":38,"end":43,"href":"https:\u002F\u002Fwww.instagram.com\u002Fsneh_s_\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":101,"end":106,"href":"https:\u002F\u002Fwww.instagram.com\u002Fzetaux\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":0,"end":136,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"CollectionViewerEdge:collectionId:b1d9ef1bb1cd-viewerId:lo_01198530914e":{"__typename":"CollectionViewerEdge","id":"collectionId:b1d9ef1bb1cd-viewerId:lo_01198530914e","isEditor":false,"isMuting":false},"ImageMetadata:1*Vjz4OlxhDF68YL7pwRL-Rg.png":{"__typename":"ImageMetadata","id":"1*Vjz4OlxhDF68YL7pwRL-Rg.png","originalWidth":600,"originalHeight":120},"PostViewerEdge:postId:402682bb13cb-viewerId:lo_01198530914e":{"__typename":"PostViewerEdge","shouldIndexPostForExternalSearch":true,"id":"postId:402682bb13cb-viewerId:lo_01198530914e"},"Tag:figma":{"__typename":"Tag","id":"figma","displayTitle":"Figma","normalizedTagSlug":"figma"},"Tag:figma-plugin":{"__typename":"Tag","id":"figma-plugin","displayTitle":"Figma Plugin","normalizedTagSlug":"figma-plugin"},"Tag:ui":{"__typename":"Tag","id":"ui","displayTitle":"UI","normalizedTagSlug":"ui"},"Tag:ux":{"__typename":"Tag","id":"ux","displayTitle":"UX","normalizedTagSlug":"ux"},"Tag:development":{"__typename":"Tag","id":"development","displayTitle":"Development","normalizedTagSlug":"development"},"Post:402682bb13cb":{"__typename":"Post","id":"402682bb13cb","collection":{"__ref":"Collection:b1d9ef1bb1cd"},"content({\"postMeteringOptions\":{}})":{"__typename":"PostContent","isLockedPreviewOnly":false,"bodyModel":{"__typename":"RichText","sections":[{"__typename":"Section","name":"aa56","startIndex":0,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null},{"__typename":"Section","name":"ecf1","startIndex":74,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null},{"__typename":"Section","name":"54c3","startIndex":76,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null},{"__typename":"Section","name":"b1be","startIndex":79,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null}],"paragraphs":[{"__ref":"Paragraph:b2f90715cfb1_0"},{"__ref":"Paragraph:b2f90715cfb1_1"},{"__ref":"Paragraph:b2f90715cfb1_2"},{"__ref":"Paragraph:b2f90715cfb1_3"},{"__ref":"Paragraph:b2f90715cfb1_4"},{"__ref":"Paragraph:b2f90715cfb1_5"},{"__ref":"Paragraph:b2f90715cfb1_6"},{"__ref":"Paragraph:b2f90715cfb1_7"},{"__ref":"Paragraph:b2f90715cfb1_8"},{"__ref":"Paragraph:b2f90715cfb1_9"},{"__ref":"Paragraph:b2f90715cfb1_10"},{"__ref":"Paragraph:b2f90715cfb1_11"},{"__ref":"Paragraph:b2f90715cfb1_12"},{"__ref":"Paragraph:b2f90715cfb1_13"},{"__ref":"Paragraph:b2f90715cfb1_14"},{"__ref":"Paragraph:b2f90715cfb1_15"},{"__ref":"Paragraph:b2f90715cfb1_16"},{"__ref":"Paragraph:b2f90715cfb1_17"},{"__ref":"Paragraph:b2f90715cfb1_18"},{"__ref":"Paragraph:b2f90715cfb1_19"},{"__ref":"Paragraph:b2f90715cfb1_20"},{"__ref":"Paragraph:b2f90715cfb1_21"},{"__ref":"Paragraph:b2f90715cfb1_22"},{"__ref":"Paragraph:b2f90715cfb1_23"},{"__ref":"Paragraph:b2f90715cfb1_24"},{"__ref":"Paragraph:b2f90715cfb1_25"},{"__ref":"Paragraph:b2f90715cfb1_26"},{"__ref":"Paragraph:b2f90715cfb1_27"},{"__ref":"Paragraph:b2f90715cfb1_28"},{"__ref":"Paragraph:b2f90715cfb1_29"},{"__ref":"Paragraph:b2f90715cfb1_30"},{"__ref":"Paragraph:b2f90715cfb1_31"},{"__ref":"Paragraph:b2f90715cfb1_32"},{"__ref":"Paragraph:b2f90715cfb1_33"},{"__ref":"Paragraph:b2f90715cfb1_34"},{"__ref":"Paragraph:b2f90715cfb1_35"},{"__ref":"Paragraph:b2f90715cfb1_36"},{"__ref":"Paragraph:b2f90715cfb1_37"},{"__ref":"Paragraph:b2f90715cfb1_38"},{"__ref":"Paragraph:b2f90715cfb1_39"},{"__ref":"Paragraph:b2f90715cfb1_40"},{"__ref":"Paragraph:b2f90715cfb1_41"},{"__ref":"Paragraph:b2f90715cfb1_42"},{"__ref":"Paragraph:b2f90715cfb1_43"},{"__ref":"Paragraph:b2f90715cfb1_44"},{"__ref":"Paragraph:b2f90715cfb1_45"},{"__ref":"Paragraph:b2f90715cfb1_46"},{"__ref":"Paragraph:b2f90715cfb1_47"},{"__ref":"Paragraph:b2f90715cfb1_48"},{"__ref":"Paragraph:b2f90715cfb1_49"},{"__ref":"Paragraph:b2f90715cfb1_50"},{"__ref":"Paragraph:b2f90715cfb1_51"},{"__ref":"Paragraph:b2f90715cfb1_52"},{"__ref":"Paragraph:b2f90715cfb1_53"},{"__ref":"Paragraph:b2f90715cfb1_54"},{"__ref":"Paragraph:b2f90715cfb1_55"},{"__ref":"Paragraph:b2f90715cfb1_56"},{"__ref":"Paragraph:b2f90715cfb1_57"},{"__ref":"Paragraph:b2f90715cfb1_58"},{"__ref":"Paragraph:b2f90715cfb1_59"},{"__ref":"Paragraph:b2f90715cfb1_60"},{"__ref":"Paragraph:b2f90715cfb1_61"},{"__ref":"Paragraph:b2f90715cfb1_62"},{"__ref":"Paragraph:b2f90715cfb1_63"},{"__ref":"Paragraph:b2f90715cfb1_64"},{"__ref":"Paragraph:b2f90715cfb1_65"},{"__ref":"Paragraph:b2f90715cfb1_66"},{"__ref":"Paragraph:b2f90715cfb1_67"},{"__ref":"Paragraph:b2f90715cfb1_68"},{"__ref":"Paragraph:b2f90715cfb1_69"},{"__ref":"Paragraph:b2f90715cfb1_70"},{"__ref":"Paragraph:b2f90715cfb1_71"},{"__ref":"Paragraph:b2f90715cfb1_72"},{"__ref":"Paragraph:b2f90715cfb1_73"},{"__ref":"Paragraph:b2f90715cfb1_74"},{"__ref":"Paragraph:b2f90715cfb1_75"},{"__ref":"Paragraph:b2f90715cfb1_76"},{"__ref":"Paragraph:b2f90715cfb1_77"},{"__ref":"Paragraph:b2f90715cfb1_78"},{"__ref":"Paragraph:b2f90715cfb1_79"}]},"validatedShareKey":"","shareKeyCreator":null},"creator":{"__ref":"User:809d3d0ce467"},"inResponseToEntityType":null,"isLocked":false,"isMarkedPaywallOnly":false,"lockedSource":"LOCKED_POST_SOURCE_NONE","mediumUrl":"https:\u002F\u002Fdesign.zeta.in\u002Fbreaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb","primaryTopic":null,"topics":[{"__typename":"Topic","slug":"design"}],"isPublished":true,"latestPublishedVersion":"b2f90715cfb1","visibility":"PUBLIC","postResponses":{"__typename":"PostResponses","count":0},"clapCount":495,"allowResponses":true,"isLimitedState":false,"title":"Breaking the code: How did we build our Figma plugin?","isSeries":false,"sequence":null,"uniqueSlug":"breaking-the-code-how-did-we-build-our-figma-plugin-402682bb13cb","socialTitle":"","socialDek":"","canonicalUrl":"","metaDescription":"","latestPublishedAt":1622570199760,"readingTime":8.422641509433962,"previewContent":{"__typename":"PreviewContent","subtitle":"Learn how Zeta Design built its first Figma plugin."},"previewImage":{"__ref":"ImageMetadata:1*Buv9AgzhmtMU6dkKrqZznw.png"},"isShortform":false,"seoTitle":"","firstPublishedAt":1622552377273,"updatedAt":1641483853491,"shortformType":"SHORTFORM_TYPE_LINK","seoDescription":"","viewerEdge":{"__ref":"PostViewerEdge:postId:402682bb13cb-viewerId:lo_01198530914e"},"isSuspended":false,"license":"ALL_RIGHTS_RESERVED","tags":[{"__ref":"Tag:figma"},{"__ref":"Tag:figma-plugin"},{"__ref":"Tag:ui"},{"__ref":"Tag:ux"},{"__ref":"Tag:development"}],"isNewsletter":false,"statusForCollection":"APPROVED","pendingCollection":null,"detectedLanguage":"en","wordCount":1914,"layerCake":0,"responsesLocked":false}}</script><script src="https://cdn-client.medium.com/lite/static/js/manifest.b2314f6d.js"></script><script src="https://cdn-client.medium.com/lite/static/js/9865.1496d74a.js"></script><script src="https://cdn-client.medium.com/lite/static/js/main.24534aeb.js"></script><script src="https://cdn-client.medium.com/lite/static/js/instrumentation.d9108df7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/reporting.ff22a7a5.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9120.5df29668.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5049.d1ead72d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4810.6318add7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6618.db187378.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2707.b0942613.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9977.5b3eb23a.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8599.1ab63137.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5250.9f9e01d2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6349.b071a958.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2648.26563adf.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8393.826a25fb.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7079.67349d50.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/3735.afb7e926.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5642.a2d9f6a1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6546.cd03f950.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6834.08de95de.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7346.72622eb9.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2420.2a5e2d95.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/839.ca7937c2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7975.d195c6f1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2106.21ff89d3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7394.3d049572.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2961.00a48598.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8204.c4082863.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4391.59acaed3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/PostPage.MainContent.c8a11795.chunk.js"></script><script>window.main();</script></body></html>