CINXE.COM

Frontend Weekly

<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>Frontend Weekly</title><meta name="description" content="The best articles, links and news related to Frontend Development delivered once a week to your inbox."/><meta name="robots" content="index, follow"/><meta property="og:title" content="Frontend Weekly"/><meta property="og:description" content="The best articles, links and news related to Frontend Development delivered once a week to your inbox."/><meta property="og:type" content="website"/><meta property="og:url" content="https://www.frontendweekly.co"/><meta property="og:site_name" content="Frontend Weekly"/><meta property="og:image" content="/images/logo.png"/><meta name="twitter:card" content="summary"/><meta name="twitter:url" content="https://www.frontendweekly.co"/><meta name="twitter:title" content="Frontend Weekly"/><meta name="twitter:description" content="The best articles, links and news related to Frontend Development delivered once a week to your inbox."/><meta name="twitter:image" content="/images/logo-192x192.png"/><meta name="twitter:creator" content="Frontend Weekly"/><meta name="application-name" content="CuratedLetters"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-status-bar-style" content="default"/><meta name="apple-mobile-web-app-title" content="CuratedLetters"/><meta name="format-detection" content="telephone=no"/><meta name="mobile-web-app-capable" content="yes"/><meta name="msapplication-TileColor" content="#2B5797"/><meta name="msapplication-tap-highlight" content="no"/><meta name="theme-color" content="#000000"/><link rel="apple-touch-icon" href="/images/apple-touch-icon.png"/><link rel="apple-touch-icon" sizes="152x152" href="https://curated-letters.s3.wasabisys.com/cc46d016-91b0-4e42-bdee-b81a4765e1f7.png"/><link rel="apple-touch-icon" sizes="180x180" href="https://curated-letters.s3.wasabisys.com/cc46d016-91b0-4e42-bdee-b81a4765e1f7.png"/><link rel="apple-touch-icon" sizes="167x167" href="https://curated-letters.s3.wasabisys.com/cc46d016-91b0-4e42-bdee-b81a4765e1f7.png"/><link rel="icon" type="image/png" sizes="32x32" href="https://curated-letters.s3.wasabisys.com/cc46d016-91b0-4e42-bdee-b81a4765e1f7.png"/><link rel="icon" type="image/png" sizes="16x16" href="https://curated-letters.s3.wasabisys.com/cc46d016-91b0-4e42-bdee-b81a4765e1f7.png"/><link rel="manifest" href="/site.webmanifest"/><link rel="shortcut icon" href="https://curated-letters.s3.wasabisys.com/cc46d016-91b0-4e42-bdee-b81a4765e1f7.png"/><link rel="alternate" type="application/json+oembed" href="https://app.curatedletters.com/api/oembed?url=https%3A%2F%2Fwww.frontendweekly.co" title="Frontend Weekly oEmbed Subscribe"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com"/><meta property="og:description" content="This week&#x27;s edition of Frontend Weekly brings valuable insights and resources for frontend development enthusiasts. Discover the best websites to find free Bootstrap templates, aiding your web design projects without extra costs. Gain a glimpse into the &#x27;Success at Scale&#x27; book, offering strategies to scale your business effectively just before its pre-sale offer concludes. Dive into a detailed comparison of frontend vs backend developers, outlining their distinct roles and skill sets vital for web development. Explore the challenges of mobile accessibility for assistive technology users and learn ways to enhance inclusivity. Delve into the interactions of throttling and debouncing in asynchronous programming to optimize code execution. Understand how to design robust digital products for unpredictable user needs with an article focused on adaptability. Learn unit testing in Angular 16 with a comprehensive guide for ensuring application robustness. Finally, the article on voice content explores its potential to revolutionize usability through intuitive and accessible user experiences."/><meta property="og:url" content=""/><meta name="next-head-count" content="40"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /><link rel="preload" href="/_next/static/css/bde417a3cc0df500.css" as="style"/><link rel="stylesheet" href="/_next/static/css/bde417a3cc0df500.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="/_next/static/chunks/webpack-bccbf73956388a58.js" defer=""></script><script src="/_next/static/chunks/framework-3c00f86f832277ab.js" defer=""></script><script src="/_next/static/chunks/main-b29a75a9812761ae.js" defer=""></script><script src="/_next/static/chunks/pages/_app-7017b763d5f3fdf0.js" defer=""></script><script src="/_next/static/chunks/0c428ae2-2c914cf5123ae7e0.js" defer=""></script><script src="/_next/static/chunks/d7eeaac4-dcc6b5eb55815ec5.js" defer=""></script><script src="/_next/static/chunks/d0c16330-07bb9c8b599a21ac.js" defer=""></script><script src="/_next/static/chunks/75fc9c18-1a4184c57e89acb3.js" defer=""></script><script src="/_next/static/chunks/8700-e6929d714c24b0f0.js" defer=""></script><script src="/_next/static/chunks/6104-2595f9fcdac52678.js" defer=""></script><script src="/_next/static/chunks/5516-f4ed12485e0d12ba.js" defer=""></script><script src="/_next/static/chunks/1882-5fc74e6381da7586.js" defer=""></script><script src="/_next/static/chunks/pages/index-01dbc9cf88c3bdd5.js" defer=""></script><script src="/_next/static/M6y-RlZQD-9EPWE2883MC/_buildManifest.js" defer=""></script><script src="/_next/static/M6y-RlZQD-9EPWE2883MC/_ssgManifest.js" defer=""></script><style data-href="https://fonts.googleapis.com/css2?family=Abril+Fatface&family=DM+Serif+Display:ital@0;1&family=EB+Garamond:ital,wght@0,400;0,700;1,400;1,700&family=Lato:ital,wght@0,400;0,900;1,300;1,400&family=Merriweather:ital,wght@0,400;0,900;1,400&display=swap">@font-face{font-family:'Abril Fatface';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/abrilfatface/v23/zOL64pLDlL1D99S8g8PtiKchm-M.woff) format('woff')}@font-face{font-family:'DM Serif Display';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/dmserifdisplay/v15/-nFhOHM81r4j6k0gjAW3mujVU2B2G_Vx1A.woff) format('woff')}@font-face{font-family:'DM Serif Display';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/dmserifdisplay/v15/-nFnOHM81r4j6k0gjAW3mujVU2B2K_Q.woff) format('woff')}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGFmQSNjdsmc35JDF1K5GRwUjcdlttVFm-rI7e8QI95.woff) format('woff')}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGFmQSNjdsmc35JDF1K5GRwUjcdlttVFm-rI7dbR495.woff) format('woff')}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGDmQSNjdsmc35JDF1K5E55YMjF_7DPuGi-6_RUAA.woff) format('woff')}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGDmQSNjdsmc35JDF1K5E55YMjF_7DPuGi-DPNUAA.woff) format('woff')}@font-face{font-family:'Lato';font-style:italic;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u_w4BMUTPHjxsI9w2PHw.woff) format('woff')}@font-face{font-family:'Lato';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u8w4BMUTPHjxswWA.woff) format('woff')}@font-face{font-family:'Lato';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHvxo.woff) format('woff')}@font-face{font-family:'Lato';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh50Xeww.woff) format('woff')}@font-face{font-family:'Merriweather';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4m0qyriQwlOrhSvowK_l5-eSZK.woff) format('woff')}@font-face{font-family:'Merriweather';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-440qyriQwlOrhSvowK_l5OeA.woff) format('woff')}@font-face{font-family:'Merriweather';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4n0qyriQwlOrhSvowK_l52_wFpXA.woff) format('woff')}@font-face{font-family:'Abril Fatface';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/abrilfatface/v23/zOL64pLDlL1D99S8g8PtiKchq-lmjcDidBeT5g.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Abril Fatface';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/abrilfatface/v23/zOL64pLDlL1D99S8g8PtiKchq-dmjcDidBc.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'DM Serif Display';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/dmserifdisplay/v15/-nFhOHM81r4j6k0gjAW3mujVU2B2G_VB3vD2xWr53BJl.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'DM Serif Display';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/dmserifdisplay/v15/-nFhOHM81r4j6k0gjAW3mujVU2B2G_VB0PD2xWr53A.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'DM Serif Display';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/dmserifdisplay/v15/-nFnOHM81r4j6k0gjAW3mujVU2B2G_5x0vrx52jJ3Q.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'DM Serif Display';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/dmserifdisplay/v15/-nFnOHM81r4j6k0gjAW3mujVU2B2G_Bx0vrx52g.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDY1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweD81ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDc1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDg1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDQ1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDU1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDs1ZyHKpWg.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDY1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweD81ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDc1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDg1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDQ1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDU1ZyHKpWiGIg.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'EB Garamond';font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGWmQSNjdsmc35JDF1K5GRweDs1ZyHKpWg.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR4SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GRxSDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR5SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR2SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR6SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR7SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR1SDk_YAPI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR4SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GRxSDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR5SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR2SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR6SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR7SDk_YAPIlWk.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'EB Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/ebgaramond/v30/SlGUmQSNjdsmc35JDF1K5GR1SDk_YAPI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Lato';font-style:italic;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u_w4BMUTPHjxsI9w2_FQftx9897sxZ.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Lato';font-style:italic;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u_w4BMUTPHjxsI9w2_Gwftx9897g.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Lato';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u8w4BMUTPHjxsAUi-qNiXg7eU0.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Lato';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u8w4BMUTPHjxsAXC-qNiXg7Q.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Lato';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjxAwXiWtFCfQ7A.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Lato';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXiWtFCc.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Lato';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh50XSwaPGQ3q5d0N7w.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Lato';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh50XSwiPGQ3q5d0.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Merriweather';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4m0qyriQwlOrhSvowK_l5-eRZDf-LVrPHpBXw.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Merriweather';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4m0qyriQwlOrhSvowK_l5-eRZKf-LVrPHpBXw.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Merriweather';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4m0qyriQwlOrhSvowK_l5-eRZBf-LVrPHpBXw.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Merriweather';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4m0qyriQwlOrhSvowK_l5-eRZAf-LVrPHpBXw.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Merriweather';font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4m0qyriQwlOrhSvowK_l5-eRZOf-LVrPHp.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Merriweather';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-440qyriQwlOrhSvowK_l5-cSZMdeX3rsHo.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Merriweather';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-440qyriQwlOrhSvowK_l5-eCZMdeX3rsHo.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Merriweather';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-440qyriQwlOrhSvowK_l5-cyZMdeX3rsHo.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Merriweather';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-440qyriQwlOrhSvowK_l5-ciZMdeX3rsHo.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Merriweather';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-440qyriQwlOrhSvowK_l5-fCZMdeX3rg.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Merriweather';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4n0qyriQwlOrhSvowK_l52_wFZVcf6hPvhPUWH.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Merriweather';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4n0qyriQwlOrhSvowK_l52_wFZXMf6hPvhPUWH.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Merriweather';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4n0qyriQwlOrhSvowK_l52_wFZV8f6hPvhPUWH.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Merriweather';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4n0qyriQwlOrhSvowK_l52_wFZVsf6hPvhPUWH.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Merriweather';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/merriweather/v30/u-4n0qyriQwlOrhSvowK_l52_wFZWMf6hPvhPQ.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}</style></head><body><div id="__next"><style> #nprogress { pointer-events: none; } #nprogress .bar { background: var(--color-primary-900); position: fixed; z-index: 9999; top: 0; left: 0; width: 100%; height: 3px; } #nprogress .peg { display: block; position: absolute; right: 0px; width: 100px; height: 100%; box-shadow: 0 0 10px var(--color-primary-900), 0 0 5px var(--color-primary-900); opacity: 1; -webkit-transform: rotate(3deg) translate(0px, -4px); -ms-transform: rotate(3deg) translate(0px, -4px); transform: rotate(3deg) translate(0px, -4px); } #nprogress .spinner { display: block; position: fixed; z-index: 1031; top: 15px; right: 15px; } #nprogress .spinner-icon { width: 18px; height: 18px; box-sizing: border-box; border: solid 2px transparent; border-top-color: var(--color-primary-900); border-left-color: var(--color-primary-900); border-radius: 50%; -webkit-animation: nprogresss-spinner 400ms linear infinite; animation: nprogress-spinner 400ms linear infinite; } .nprogress-custom-parent { overflow: hidden; position: relative; } .nprogress-custom-parent #nprogress .spinner, .nprogress-custom-parent #nprogress .bar { position: absolute; } @-webkit-keyframes nprogress-spinner { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } @keyframes nprogress-spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style><div class="Toastify"></div><div><div class="flex h-full flex-col"><div style="position:relative" class="pb-10"><div style="background-color:#eee;color:black;background-image:url()" class="absolute -z-10 h-full w-full bg-cover"></div><section class="mx-auto px-4 py-6 sm:px-6 md:py-10 lg:max-w-5xl"><nav class="flex-1" data-headlessui-state=""><div class="mx-auto max-w-7xl px-4 md:px-6 lg:px-8"><div class="flex h-16 items-center justify-between"><div class="flex w-full items-center"><div class="flex-shrink-0"><a href="/"><img src="https://curated-letters.s3.wasabisys.com/6dbf0ff0-1467-4a26-9ff1-47fa33e2ff7f.png" width="64" alt="publication logo"/></a></div><div class="hidden flex-grow md:block"><div class="flex justify-end"><a class="cursor-pointer px-3 py-3 text-sm uppercase leading-3 hover:font-bold" style="color:black;scroll-behavior:smooth" href="/#latest-issue">Latest Issues</a><a class="cursor-pointer px-3 py-3 text-sm uppercase leading-3 hover:font-bold" style="color:black" href="/archives">Archives</a><a class="cursor-pointer px-3 py-3 text-sm uppercase leading-3 hover:font-bold" style="color:black" href="https://app.curatedletters.com/landing-marketplace">Sponsor with us</a></div></div></div><div class="-mr-2 flex md:hidden"><button class="relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" id="headlessui-disclosure-button-:R15in7m:" type="button" aria-expanded="false" data-headlessui-state=""><span class="absolute -inset-0.5"></span><span class="sr-only">Open main menu</span><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 448 512" class="block h-6 w-6" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"></path></svg></button></div></div></div></nav></section><div><div><section class="mx-auto px-4 py-6 sm:px-6 md:py-10 lg:max-w-5xl flex justify-center h-full"><p style="color:black;font-size:36px" class="max-w-prose whitespace-pre-wrap text-center ">The best articles, links and news related to Frontend Development delivered once a week to your inbox.</p></section></div></div><section class="mx-auto px-4 sm:px-6 lg:max-w-5xl py-2 md:py-2"><div class="flex items-center justify-center bg-opacity-25"><div class="relative max-w-lg flex-1"><input type="email" id="subscribe" class="block w-full rounded-md border border-gray-300 bg-white p-4 text-sm text-black focus:border-black focus:ring-black" placeholder="Your email address" required="" value=""/><button type="submit" class="btn absolute bottom-1.5 right-2.5 rounded-md px-4 py-2 text-sm font-medium text-white focus:outline-none focus:ring-4 focus:ring-black disabled:opacity-30">Subscribe</button></div></div></section></div><div id="latest-issue" class="flex items-center justify-center"><p></p></div><section class="mx-auto sm:px-6 md:py-10 lg:max-w-5xl w-full bg-white px-1 py-8 h-full"><div class="flex items-center justify-between"><div class="flex-1"><a class="inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2" href="/451"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 16 16" class="mr-2 h-4 w-4" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"></path></svg><div class="flex flex-col"><span class="font-semibold text-black">Pervious issue</span><span class="text-xs text-gray-500">February 19th, 2025</span></div></a></div><div class="min-w-fit px-2 text-center"><span class="text-sm font-medium text-gray-700">452 of 452</span></div><div class="flex flex-1 justify-end"></div></div></section><div style="background-color:#eee;color:black"><section class="mx-auto px-4 py-6 sm:px-6 md:py-10 lg:max-w-5xl h-full"><section class="mx-auto px-4 sm:px-6 lg:max-w-5xl py-2 md:py-2"><div class="flex items-center justify-center bg-opacity-25"><div class="relative max-w-lg flex-1"><input type="email" id="subscribe" class="block w-full rounded-md border border-gray-300 bg-white p-4 text-sm text-black focus:border-black focus:ring-black" placeholder="Your email address" required="" value=""/><button type="submit" class="btn absolute bottom-1.5 right-2.5 rounded-md px-4 py-2 text-sm font-medium text-white focus:outline-none focus:ring-4 focus:ring-black disabled:opacity-30">Subscribe</button></div></div></section><section class="mx-auto px-4 sm:px-6 lg:max-w-5xl flex items-center justify-center py-0 md:py-0"><p class="max-w-prose px-4 text-center font-sans text-sm" style="color:black"><b>No spam</b>, ever. We&#x27;ll never share your email address and you can opt out at any time.</p></section><div class="my-10 flex items-center justify-center"><div class="h-[1px] w-[200px] bg-gray-200"></div></div><div class="flex flex-col items-center justify-center py-5"><p class="text-center font-light " style="color:black">© 2023 - 2025 Frontend Weekly</p><p class="max-w-prose px-4 text-center text-xs font-thin opacity-60" style="color:black">This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.</p><div class="mt-5 flex content-center items-center justify-items-center gap-2 text-center"><div><a target="_blank" rel="noopener noreferrer" class="text-sm font-medium hover:underline" style="color:black" href="https://www.curatedletters.com/?utm_source=newsletter&amp;utm_medium=web&amp;utm_campaign=Frontend Weekly">Published with CuratedLetters</a></div><img src="/_next/static/media/logo.9433c6a1.png" height="27" width="27" alt="curated-letters logo"/></div></div></section></div><div class="fixed right-4 top-1/3 hidden flex-col space-y-4 lg:flex"><button class="text-gray-600 hover:text-black"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 448 512" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"></path></svg></button><button class="text-gray-600 hover:text-black"><svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></svg></button><button class="text-gray-600 hover:text-black"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M504 256C504 119 393 8 256 8S8 119 8 256c0 123.78 90.69 226.38 209.25 245V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.28c-30.8 0-40.41 19.12-40.41 38.73V256h68.78l-11 71.69h-57.78V501C413.31 482.38 504 379.78 504 256z"></path></svg></button><button class="text-gray-600 hover:text-black"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"></path></svg></button></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"_sentryTraceData":"e720362a2d4a4d9b84ae5c6320f6cdd8-a2e32e5705313b42-0","_sentryBaggage":"sentry-environment=production,sentry-release=M6y-RlZQD-9EPWE2883MC,sentry-public_key=30d1ed702d78ef004618354912033b30,sentry-trace_id=e720362a2d4a4d9b84ae5c6320f6cdd8,sentry-sample_rate=0.04,sentry-transaction=%2F,sentry-sampled=false","session":null,"newsletter":{"id":"clpwppyvd0068pu0avdxqsp42","detectedLanguage":"english","detectedLanguageAt":"2025-02-07T03:29:15.186Z","name":"Frontend Weekly","description":"The best articles, links and news related to Frontend Development delivered once a week to your inbox.","isArchived":false,"archivedAt":null,"active":true,"createdAt":"2023-12-08T14:18:44.040Z","updatedAt":"2025-03-01T02:02:11.899Z","createdById":"clikcel5r00008e0bh37oib88","logo":"https://curated-letters.s3.wasabisys.com/6dbf0ff0-1467-4a26-9ff1-47fa33e2ff7f.png","logoWidth":0,"favicon":"https://curated-letters.s3.wasabisys.com/cc46d016-91b0-4e42-bdee-b81a4765e1f7.png","status":"REVIEWED","language":"EN","backgroundColor":"#eee","backgroundImage":"","textColor":"","headerFontSize":36,"footerBackgroundColor":"#eee","footerTextColor":"","darkenBackgroundColor":false,"includeIssueTitleInHeader":false,"includeIssueDateInHeader":false,"additionalFooterText":null,"subscribeMethodText":null,"twitterSocialLink":null,"linkedinSocialLink":null,"facebookSocialLink":null,"instagramSocialLink":null,"youtubeSocialLink":null,"primaryFont":null,"secondaryFont":null,"dateFormat":"MONTH_DAY_YEAR","useCardinalNumbers":false,"publishFrequency":7,"frequencyType":"EVERY_DAYS","schedulingDateTime":15,"schedulingMinutes":0,"postaAddress":null,"subscriptionFormEnabled":true,"subscriptionFormDescription":null,"subscripeButtonText":"Subscribe","subscripeButtonColor":"#4949f8","issueTemplateTile":"Issue %%issue_number%%","socialImage":"","publicationDomain":"frontendweekly","customPublicationDomain":"www.frontendweekly.co","customPublicationDomainStatus":"VERIFIED","customPublicationLastUpdate":"2024-01-09T11:13:42.939Z","firstIssuePublished":true,"menuOptionLabel":null,"menuOptionURL":null,"customHtmlTitle":null,"rewardEnabled":false,"doubleOptInEnabled":true,"emailSenderName":"Frontend Weekly","replyToAddressEmail":"info@frontendweekly.co","replyToEmailDomain":"frontendweekly.co","replyToDomainVerified":true,"optimizeDescriptionCount":301,"aiContentGeneratorSentence":"I'm creating this article for a newsletter, give me a 2 sentence summary of the article. Make it factual and professional. Do not mention the article title or source, just the summary of the article.","newsletterAIGenerationId":null,"injectAdsEnabled":true,"primaryCategory":"Web Development","secondaryCategory":"Tech \u0026 Innovation","prune_unopenedIssueCount":5,"prune_lastAt":"2025-02-27T00:24:24.314Z","prune_frequencyInDays":30,"lastMonthlySummaryAt":"2025-03-01T02:02:14.868Z","socialLinks":[],"Issue":[{"id":"n4uh1aqpegbquqp84m7mimgt","isNext":false,"publishingAt":"2025-02-26T17:00:00.000Z","due":"2025-02-26T17:00:00.000Z","status":"PUBLISHED","titleTemplate":"Issue %%issue_number%%","number":452,"createdAt":"2025-02-25T17:00:00.052Z","updatedAt":"2025-03-01T05:13:02.886Z","shortSummary":"This issue of Frontend Weekly features free Bootstrap templates, scaling strategies from 'Success at Scale,' frontend vs backend roles, mobile accessibility challenges, and more insights for developers.","longSummary":"This week's edition of Frontend Weekly brings valuable insights and resources for frontend development enthusiasts. Discover the best websites to find free Bootstrap templates, aiding your web design projects without extra costs. Gain a glimpse into the 'Success at Scale' book, offering strategies to scale your business effectively just before its pre-sale offer concludes. Dive into a detailed comparison of frontend vs backend developers, outlining their distinct roles and skill sets vital for web development. Explore the challenges of mobile accessibility for assistive technology users and learn ways to enhance inclusivity. Delve into the interactions of throttling and debouncing in asynchronous programming to optimize code execution. Understand how to design robust digital products for unpredictable user needs with an article focused on adaptability. Learn unit testing in Angular 16 with a comprehensive guide for ensuring application robustness. Finally, the article on voice content explores its potential to revolutionize usability through intuitive and accessible user experiences.","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdById":"clikcel5r00008e0bh37oib88","imported":false,"emailTitle":"Frontend Magic: Bootstrap, Angular \u0026 More! ✨","emailDescription":null,"bannerImageUrl":null,"emailTemplateId":"cm4mt35w60002ipkl46ycluat","aiTitleGenerationEnabled":null,"subscribersCount":13647,"failedMailsCount":0,"spamMailsCount":0,"openedCount":3789,"uniqueOpenedCount":2394,"totalClicks":522,"uniqueClicks":512,"publishingStatus":"SENDING_IN_PROGRESS","lockedAt":null,"lockId":null,"Items":[{"id":"de3jfkhqxgfol5l5wnw2hpls","title":"Best Websites to Find Free Bootstrap Templates","favorite":false,"body":"Explore the top websites offering free Bootstrap templates to enhance web design projects without incurring additional costs.","fullBody":"This is a roundup of the best websites where you can find and download free Bootstrap templates. There are many template creators in the online space. Here is why those mentioned below stand out from the crowd: They offer free Bootstrap 5 templates besides older versions Templates are offered free for both personal and commercial use Items look modern and are presented with the mandatory Live Preview You are not required more than an email address or signup to download As a template maker myself I ' ve browsed thousands of templates. From experience I know that many \" free \" templates are licensed just for personal use. That means you can ' t use them for client projects which can be quite disappointing. Not the case with the sources below. HTMLrev HTMLrev (free) is a gallery that showcases a wide range of free templates for web developers. The Bootstrap category is the largest and showcases the best work of generous template creators around the world. Find items for business, product, agency, hospitality, services, events, blogs, portfolios, ecommerce, dashboards and more. Features Showcases the best templates created by top makers Bootstrap category is the largest on the website All featured items are Bootstrap 5 Start Bootstrap Start Bootstrap (free + paid) is an established source of premium quality free Bootstrap templates for startup, agency, portfolio, personal and blogs. It even provides feature-rich admin dashboard templates. They ' re built at such high standards that one can even learn web development from them. Features Incredibly well built and varied templates Designs align to the form follows function mantra Doesn ' t require email or signup for download Templatemo Templatemo (free + paid) is a generous and impressive source of free Bootstrap templates. The sheer number of items is mind blowing and the quality is great. It will be hard not to find a solid foundation for your project among the listed items. Besides looking good the templates are also marketing oriented. Features Comprehensive library of templates on many subjects Doesn ' t require email or signup for download 3rd Wave Media 3rd Wave Media (free + paid) is one of the most developer friendly resources in the list. It ' s made by developers for developers and it shows in terms of design efficiency and code structure. Templates are well constructed and results oriented. You will find items for a wide range of subjects. Features Startup, mobile app, ebook, event, personal, portfolio, docs The website is easy to navigate without intrusive ads Doesn ' t require email or signup for download Tooplate Tooplate (free) is a huge library of well designed Bootstrap templates. Designs are modern and well polished. Each template is carefully crafted to look good on all devices. Ads can be intrusive at times but it ' s important to notice that downloads are 100% free without restrictions. Features Big collection of various Bootstrap templates Advanced components specific to premium class items Doesn ' t require email or signup for download Creative Tim Creative Tim (free + paid) is one of the most loved Bootstrap resource suppliers among web developers. The free Bootstrap UI kits \u0026amp; dashboard templates are on par with their premium items. They are just as well designed and smoothly polished. Since these templates are used to build web apps the documentation quality is in a league of its own. Features Designs are superb and consistent Components with advanced functionalities Themesberg Themesberg (free + paid) provides a couple of high quality free Bootstrap templates. You can get dashboards, landing pages, design systems and UI kits. Design quality and refinement levels are in a league of their own. Besides looking amazing the items are well structured and documented. Features Great dashboard templates and UI kit Advanced components for complex functionalities TemplateDeck TemplateDeck (free) is a great resource offering very few but very high quality Bootstrap templates. The right words to describe them would be minimalist, creative and impressive. The company, personal and startup website templates are crafted to the highest design and code standards. Features Presentation website is nice and easy to navigate Templates are both professionally designed and coded Pixel Rocket Pixel Rocket (free) provides a small but useful collection of free Bootstrap templates. Designs look amazing with modern color schemes. Each item comes with many basic and advanced sections and components. Use cases covered are ecommerce, dashboard, portfolio and business websites. Features Small collection of high quality Bootstrap templates Doesn ' t require email or signup for download HTML Codex HTML Codex (free + paid) provides a large number of free templates. All templates are Bootstrap based, look good and can be downloaded without any restrictions. There is huge variation which covers multiple use cases. Business, course, product, agency, service, portfolio, resume and the list goes on. Features Results oriented designs covering a wide range of use cases Doesn ' t require email or signup for download Subtle scroll based animations W3Layouts W3Layouts (free + paid) provides many free Bootstrap templates. Basically all templates on their website are available for free. Check the Free Download button just below the Demo one. Designs are modern and usable for a wide range of subjects. Business style templates seems to be their specialty. Features Good number of business style templates Covers a wide range of use cases Bootstrapious Bootstrapious (free) is a useful resource for free Bootstrap templates. Ads are present everywhere but not extremely intrusive. You need to provide your email to download but on the upside there is a large selection to choose from. Designs look good and some items pack advanced components. Features Large number of free items on various subjects Some of the designs are exceptionally good AdminMart AdminMart (free + paid) doesn ' t provide many free Bootstrap templates. But what it lacks in numbers it more than makes up in quality and complexity. The free items are professionally designed and come with tons of ready-made sections and components. Definitely worth checking out. Features SaaS, agency and dashboard templates Items usable for professional projects TemplatesJungle TemplatesJungle (free + paid) is a generous resource providing many Bootstrap templates for free download. Designs are awesome, marketing oriented and cover multiple use cases. Business, agency, service, portfolio, ecommerce. You will find a template for just about any subject you can imagine. Features Huge number of well designed templates to choose from Designs are impressive and will make your project stand out MonsterOne MonsterOne (free + paid) is the subscription based template library by Template Monster. If you register for a Free account you get access to free items without paying the subscription. They are of high quality and come with multiple pages, sections and components. Will save you a lot of design and development time. Features Modern templates with multiple pages Well structured website with many filters Item quality varies because of multiple makers Untree Untree (free) creates free Bootstrap templates that save developers time and money. They are beautifully designed, with great attention to details. Templates come with multiple pages and advanced components like dropdown navigation, sliders and subtle animations. Even though they ' re built on Bootstrap they still have a lot of character. Features Designs have personality and don ' t look repetitive Doesn ' t require email or signup for download Tabler Tabler (free) is an amazing Bootstrap UI kit providing multiple dashboard templates and components for web apps. It ' s quite incredible that a package so big and well polished is available for free. Designs are great, documentation is thorough, code is very well structured. This resource is a gem. Features Bootstrap templates focused on dashboards Top of the range design and code quality Many premium level, advanced components Wrappixel Wrappixel (free + paid) provides a good sized collection of free Bootstrap templates for admin dashboards. There are plenty of options when it comes to design and structure. You can choose between corporate style for business use cases or choose a creative versions for more fun websites. Features Solid collection of Bootstrap dashboards Different designs and color schemes KeenThemes KeenThemes (free + paid) is a reliable supplier of well designed free Bootstrap templates for admin dashboards. Each free template comes with multiple time saving components wrapped up in modern designs. There are different styles to choose from adapting to many possible scenarios. Features Niched on web app admin dashboards Clean website without ads or other annoyances BootstrapDash BootstrapDash (free + paid) provides a useful selection for free Bootstrap website and dashboard templates. The packages are generous in terms of different pages and components. Designs are consistent, modern and optimized for results. The website is free of ads and a pleasure to navigate since the authors monetize with Pro items. Features Great templates for website, landing page and dashboard Presentation website is modern and easy to navigate There are a couple more template websites especially if you check Google search results pages. I didn ' t mention those because they fit in one or more of the situations below: Claim they offer free templates but they are actually paid They are specific to visual builders and not downloadable Old websites offering only Bootstrap 4 templates and lower The license doesn ' t allow commercial or client use To assemble this roundup I ' ve went through each website on relevant Google search pages including blog posts. I ' ve searched through comments of similar roundup posts on Dev. To. I ' ve scoured Gumroad Discovery for $0 priced items. Checked Dribbble and GitHub. Hope it will save your time and help you build projects easier.","url":"https://dev.to/devluc/best-websites-to-find-free-bootstrap-templates-f6a","image":"","numberInCategoryInIssue":0,"curatedById":null,"issueId":"n4uh1aqpegbquqp84m7mimgt","categoryId":"clpwrwzi600enpu0a2r98t2li","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdAt":"2024-03-07T10:27:50.596Z","updatedAt":"2024-10-21T19:02:08.848Z","updatedById":null,"createdById":null,"sponsoredById":null,"openPixelUrl":null,"sponsorStatus":[],"sourceName":"RSSFEED","RSSFeedSourceId":"clpwq09u3006xpu0ajcarv458","collectImage":true,"cleanTextProcessed":true,"archived":false,"autoEnhancedBodyFlag":true,"sponsoredBy":null},{"id":"k14x5534fjcmqyr35zik0dy2","title":"Success At Scale: Last Chance For Pre-Sale Price","favorite":false,"body":"A detailed discussion on the upcoming book 'Success at Scale,' which provides insights and strategies for scaling businesses effectively, highlighted through an exclusive pre-release overview.","fullBody":"Our next book, “Success at Scale” is finally at the printer, which means we’ll be shipping books soon. It’s also your last chance to get the book at the presale price. Get your copy and save now!","url":"https://smashingmagazine.com/2024/03/success-at-scale-book-pre-release/","image":"https://curated-letters.s3.wasabisys.com/sas-presale-ending-opt7041d963-7f82-4425-94d2-88a61d2bfa1f.png","numberInCategoryInIssue":0,"curatedById":null,"issueId":"n4uh1aqpegbquqp84m7mimgt","categoryId":"clpwpy59r000a0apugdok9rud","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdAt":"2024-03-09T12:29:50.654Z","updatedAt":"2024-10-08T20:03:04.312Z","updatedById":null,"createdById":null,"sponsoredById":null,"openPixelUrl":null,"sponsorStatus":[],"sourceName":"RSSFEED","RSSFeedSourceId":"clpwq57w900blpu0a7p9d928k","collectImage":true,"cleanTextProcessed":true,"archived":false,"autoEnhancedBodyFlag":true,"sponsoredBy":null},{"id":"kdnf1lm8va3y8m1mb26cjilu","title":"Frontend vs Backend Developer","favorite":false,"body":"This article provides an in-depth comparison between frontend and backend developers, highlighting their respective roles, skills, and responsibilities in web development.","fullBody":"Hay Dev, In web development, there are two important roles: frontend and backend development. These two disciplines are essential for any successful web project, but they have different roles, skills, and responsibilities. In this blog, we will explore the world of frontend and backend development, comparing their characteristics, required skills, and challenges. So, whether you ' re an experienced developer or just starting, get ready to explore the fascinating world of frontend vs. Backend development! Frontend Development: Frontend developers are responsible for creating the user-facing side of a website. They focus on crafting visually appealing and interactive elements that users directly engage with. Frontend developers specialize in programming languages such as HTML, CSS, and JavaScript, which enable them to create seamless user experiences. Their skills include creating responsive designs, optimizing website performance, and using frameworks like React, Angular, or Vue. Js. Skills Required for Frontend Development: Proficient in HTML and CSS: Frontend developers should deeply understand HTML for structuring webpages and CSS for styling and layout. Mastery of JavaScript: JavaScript is a core language that adds interactivity, animations, and dynamic elements to websites. Frontend developers should have a solid grasp of JS concepts and libraries. Cross-Browser Compatibility: They must possess the ability to create websites that function consistently across different browsers. Challenges Faced by Frontend Developers: Responsive Design: Frontend developers need to ensure that websites render correctly on various devices, adapting to different screen sizes and resolutions. Browser Compatibility: Since users browse the internet using multiple browsers, achieving consistent performance across each one can be a challenge. Continuous Learning: Given the ever-evolving nature of front-end technologies, developers must keep up with the latest frameworks, tools, and design trends to stay competitive. Backend Development: Let ' s dive into backend development—the powerhouse of a website that drives its functionalities. Backend developers operate behind the scenes, orchestrating databases and server-side programming to ensure seamless operation. They tackle infrastructure, server management, and the integration of third-party services, all while emphasizing data security and managing scalability. Backend developers are adept at using languages like Python, Ruby, PHP, or Java, alongside frameworks such as Django, Ruby on Rails, or Laravel. Skills Required for Backend Development: Server-Side Programming: Backend developers should be proficient in at least one programming language commonly used for server-side development. Databases and Data Handling: Knowledge of database management systems like MySQL, PostgreSQL, or MongoDB is crucial for organizing and retrieving data efficiently. API Integration: The ability to integrate external services and APIs is essential for backend developers, enabling seamless functionality and improved user experience. Challenges Faced by Backend Developers: Scalability and Performance: Backend developers are responsible for architecting systems that can handle high traffic and load bursts, ensuring consistent performance. Security: Protecting sensitive user data, implementing encryption, and guarding against cyber threats form a significant challenge for backend developers. Collaborating with Frontend Developers: Backend developers need to collaborate closely with frontend developers to ensure smooth integration of the frontend and backend components. Conclusion: \" Frontend and backend development collaborate to craft amazing user experiences. Front-end developers concentrate on creating visually appealing and user-friendly designs, while back-end developers establish the infrastructure and manage data to ensure seamless functionality. Both roles require unique skills and play an equally important part in the success of web projects. \"","url":"https://dev.to/azadnishad/frontend-vs-backend-developer-3hl3","image":"https://curated-letters.s3.wasabisys.com/development-scaled56eafc89-3c31-40cf-9030-fe64ba7b7365.jpg","numberInCategoryInIssue":0,"curatedById":null,"issueId":"n4uh1aqpegbquqp84m7mimgt","categoryId":"clpwrwt5v00elpu0aj8tszo0y","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdAt":"2024-07-26T12:40:50.931Z","updatedAt":"2024-10-08T20:21:01.886Z","updatedById":null,"createdById":null,"sponsoredById":null,"openPixelUrl":null,"sponsorStatus":[],"sourceName":"RSSFEED","RSSFeedSourceId":"clpwq09u3006xpu0ajcarv458","collectImage":true,"cleanTextProcessed":true,"archived":false,"autoEnhancedBodyFlag":true,"sponsoredBy":null},{"id":"hvhrhla6pe4yh91h71tlmxgl","title":"Mobile Accessibility Barriers For Assistive Technology Users","favorite":false,"body":"This article examines the common barriers to mobile accessibility faced by users of assistive technologies, providing insights into improving user experiences and fostering inclusivity.","fullBody":"Accessibility goes beyond making products user-friendly. It can significantly impact the quality of life for people with disabilities. Kate Kalcevich shares lessons she learned from assistive technology users \u0026mdash; challenges and barriers they encounter on mobile devices.","url":"https://smashingmagazine.com/2024/02/mobile-accessibility-barriers-assistive-technology-users/","image":"https://curated-letters.s3.wasabisys.com/mobile-accessibility-barriers-assistive-technology-usersb4106d82-6759-411e-a0c9-dfc818b977d9.jpg","numberInCategoryInIssue":0,"curatedById":null,"issueId":"n4uh1aqpegbquqp84m7mimgt","categoryId":"clpwrwt5v00elpu0aj8tszo0y","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdAt":"2024-02-20T12:11:50.433Z","updatedAt":"2024-10-08T18:24:03.539Z","updatedById":null,"createdById":null,"sponsoredById":null,"openPixelUrl":null,"sponsorStatus":[],"sourceName":"RSSFEED","RSSFeedSourceId":"clpwq57w900blpu0a7p9d928k","collectImage":true,"cleanTextProcessed":true,"archived":false,"autoEnhancedBodyFlag":true,"sponsoredBy":null},{"id":"nogy1zo5pcky1t664ig77wt7","title":"When throttling and debouncing meet asynchronous, what kind of sparks will they create? Published at","favorite":false,"body":"This article explores the interaction between throttling and debouncing in asynchronous programming, explaining their differences and how they can be effectively combined in code execution.","fullBody":"Hi there, I ' m Bowen. I just wrote an article that showcases an implementation of asynchronous throttling, and its twin brother, asynchronous debouncing. You can find it here: https: //blog. Bowen. Cool/posts/when-throttling-meets-asynchrony","url":"https://dev.to/bowencool/when-throttling-and-debouncing-meet-asynchronous-what-kind-of-sparks-will-they-createpublished-at-3jlk","image":"https://curated-letters.s3.wasabisys.com/y7j2kvxf527ov5u6x4jya8dddbfb-6b06-4264-bd7d-7c82711cd326.png","numberInCategoryInIssue":0,"curatedById":null,"issueId":"n4uh1aqpegbquqp84m7mimgt","categoryId":"clpwrwzi600enpu0a2r98t2li","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdAt":"2024-02-23T10:14:51.242Z","updatedAt":"2024-10-21T23:48:10.233Z","updatedById":null,"createdById":null,"sponsoredById":null,"openPixelUrl":null,"sponsorStatus":[],"sourceName":"RSSFEED","RSSFeedSourceId":"clpwq09u3006xpu0ajcarv458","collectImage":true,"cleanTextProcessed":true,"archived":false,"autoEnhancedBodyFlag":true,"sponsoredBy":null},{"id":"ljen816wzdsfelkldpp4zqc9","title":"Designing for the Unexpected","favorite":false,"body":"The article explores strategies for designing digital products that can adapt to various user needs and unpredictable situations, emphasizing the importance of flexibility and resilience in user experience design.","fullBody":"I’m not sure when I first heard this quote, but it’s something that has stayed with me over the years. How do you create services for situations you can’t imagine? Or design products that work on devices yet to be invented? Flash, Photoshop, and responsive design When I first started designing websites, my go-to software was Photoshop. I created a 960px canvas and set about creating a layout that I would later drop content in. The development phase was about attaining pixel-perfect accuracy using fixed widths, fixed heights, and absolute positioning. Ethan Marcotte’s talk at An Event Apart and subsequent article “ Responsive Web Design ” in A List Apart in 2010 changed all this. I was sold on responsive design as soon as I heard about it, but I was also terrified. The pixel-perfect designs full of magic numbers that I had previously prided myself on producing were no longer good enough. The fear wasn’t helped by my first experience with responsive design. My first project was to take an existing fixed-width website and make it responsive. What I learned the hard way was that you can’t just add responsiveness at the end of a project. To create fluid layouts, you need to plan throughout the design phase. A new way to design Designing responsive or fluid sites has always been about removing limitations, producing content that can be viewed on any device. It relies on the use of percentage-based layouts, which I initially achieved with native CSS and utility classes: . Column-span-6 { width: 49%; float: left; margin-right: 0. 5%; margin-left: 0. 5%; }. Column-span-4 { width: 32%; float: left; margin-right: 0. 5%; margin-left: 0. 5%; }. Column-span-3 { width: 24%; float: left; margin-right: 0. 5%; margin-left: 0. 5%; } Then with Sass so I could take advantage of @includes to re-use repeated blocks of code and move back to more semantic markup: . Logo { @include colSpan(6); }. Search { @include colSpan(3); }. Social-share { @include colSpan(3); } Media queries The second ingredient for responsive design is media queries. Without them, content would shrink to fit the available space regardless of whether that content remained readable (The exact opposite problem occurred with the introduction of a mobile-first approach). Components becoming too small at mobile breakpoints Media queries prevented this by allowing us to add breakpoints where the design could adapt. Like most people, I started out with three breakpoints: one for desktop, one for tablets, and one for mobile. Over the years, I added more and more for phablets, wide screens, and so on. \u0026nbsp; For years, I happily worked this way and improved both my design and front-end skills in the process. The only problem I encountered was making changes to content, since with our Sass grid system in place, there was no way for the site owners to add content without amending the markup—something a small business owner might struggle with. This is because each row in the grid was defined using a div as a container. Adding content meant creating new row markup, which requires a level of HTML knowledge. Row markup was a staple of early responsive design, present in all the widely used frameworks like Bootstrap and Skeleton. \u0026lt; section class= \" row \" \u0026gt; \u0026lt; div class= \" column-span-4 \" \u0026gt; 1 of 7\u0026lt; /div\u0026gt; \u0026lt; div class= \" column-span-4 \" \u0026gt; 2 of 7\u0026lt; /div\u0026gt; \u0026lt; div class= \" column-span-4 \" \u0026gt; 3 of 7\u0026lt; /div\u0026gt; \u0026lt; /section\u0026gt; \u0026lt; section class= \" row \" \u0026gt; \u0026lt; div class= \" column-span-4 \" \u0026gt; 4 of 7\u0026lt; /div\u0026gt; \u0026lt; div class= \" column-span-4 \" \u0026gt; 5 of 7\u0026lt; /div\u0026gt; \u0026lt; div class= \" column-span-4 \" \u0026gt; 6 of 7\u0026lt; /div\u0026gt; \u0026lt; /section\u0026gt; \u0026lt; section class= \" row \" \u0026gt; \u0026lt; div class= \" column-span-4 \" \u0026gt; 7 of 7\u0026lt; /div\u0026gt; \u0026lt; /section\u0026gt; Components placed in the rows of a Sass grid Another problem arose as I moved from a design agency building websites for small- to medium-sized businesses, to larger in-house teams where I worked across a suite of related sites. In those roles I started to work much more with reusable components. \u0026nbsp; Our reliance on media queries resulted in components that were tied to common viewport sizes. If the goal of component libraries is reuse, then this is a real problem because you can only use these components if the devices you’re designing for correspond to the viewport sizes used in the pattern library—in the process not really hitting that “devices that don’t yet exist” \u0026nbsp; goal. Then there’s the problem of space. Media queries allow components to adapt based on the viewport size, but what if I put a component into a sidebar, like in the figure below? Components responding to the viewport width with media queries Container queries: our savior or a false dawn? Container queries have long been touted as an improvement upon media queries, but at the time of writing are unsupported in most browsers. There are JavaScript workarounds, but they can create dependency and compatibility issues. The basic theory underlying container queries is that elements should change based on the size of their parent container and not the viewport width, as seen in the following illustrations. Components responding to their parent container with container queries One of the biggest arguments in favor of container queries is that they help us create components or design patterns that are truly reusable because they can be picked up and placed anywhere in a layout. This is an important step in moving toward a form of component-based design that works at any size on any device. In other words, responsive components to replace responsive layouts. Container queries will help us move from designing pages that respond to the browser or device size to designing components that can be placed in a sidebar or in the main content, and respond accordingly. My concern is that we are still using layout to determine when a design needs to adapt. This approach will always be restrictive, as we will still need pre-defined breakpoints. For this reason, my main question with container queries is, How would we decide when to change the CSS used by a component? \u0026nbsp; A component library removed from context and real content is probably not the best place for that decision. \u0026nbsp; As the diagrams below illustrate, we can use container queries to create designs for specific container widths, but what if I want to change the design based on the image size or ratio? Cards responding to their parent container with container queries Cards responding based on their own content In this example, the dimensions of the container are not what should dictate the design; rather, the image is. It’s hard to say for sure whether container queries will be a success story until we have solid cross-browser support for them. Responsive component libraries would definitely evolve how we design and would improve the possibilities for reuse and design at scale. But maybe we will always need to adjust these components to suit our content. CSS is changing Whilst the container query debate rumbles on, there have been numerous advances in CSS that change the way we think about design. The days of fixed-width elements measured in pixels and floated div elements used to cobble layouts together are long gone, consigned to history along with table layouts. Flexbox and CSS Grid have revolutionized layouts for the web. We can now create elements that wrap onto new rows when they run out of space, not when the device changes. . Wrapper { display: grid; grid-template-columns: repeat(auto-fit, 450px); gap: 10px; } The repeat() function paired with auto-fit or auto-fill allows us to specify how much space each column should use while leaving it up to the browser to decide when to spill the columns onto a new line. Similar things can be achieved with Flexbox, as elements can wrap over multiple rows and “flex” to fill available space. . Wrapper { display: flex; flex-wrap: wrap; justify-content: space-between; }. Child { flex-basis: 32%; margin-bottom: 20px; } The biggest benefit of all this is you don’t need to wrap elements in container rows. Without rows, content isn’t tied to page markup in quite the same way, allowing for removals or additions of content without additional development. A traditional Grid layout without the usual row containers This is a big step forward when it comes to creating designs that allow for evolving content, but the real game changer for flexible designs is CSS Subgrid. Remember the days of crafting perfectly aligned interfaces, only for the customer to add an unbelievably long header almost as soon as they ' re given CMS access, like the illustration below? Cards unable to respond to a sibling’s content changes Subgrid allows elements to respond to adjustments in their own content and in the content of sibling elements, helping us create designs more resilient to change. Cards responding to content in sibling cards. Wrapper { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); grid-template-rows: auto 1fr auto; gap: 10px; }. Sub-grid { display: grid; grid-row: span 3; grid-template-rows: subgrid; /* sets rows to parent grid */ } CSS Grid allows us to separate layout and content, thereby enabling flexible designs. Meanwhile, Subgrid allows us to create designs that can adapt in order to suit morphing content. Subgrid at the time of writing is only supported in Firefox but the above code can be implemented behind an @supports feature query. \u0026nbsp; Intrinsic layouts\u0026nbsp; I’d be remiss not to mention intrinsic layouts, the term created by Jen Simmons to describe a mixture of new and old CSS features used to create layouts that respond to available space. Responsive layouts have flexible columns using percentages. Intrinsic layouts, on the other hand, use the fr unit to create flexible columns that won’t ever shrink so much that they render the content illegible. Fr units is a way to say I want you to distribute the extra space in this way, but. . . Don’t ever make it smaller than the content that’s inside of it. —Jen Simmons, “Designing Intrinsic Layouts” Intrinsic layouts can also utilize a mixture of fixed and flexible units, allowing the content to dictate the space it takes up. Slide from “Designing Intrinsic Layouts” by Jen Simmons What makes intrinsic design stand out is that it not only creates designs that can withstand future devices but also helps scale design without losing flexibility. Components and patterns can be lifted and reused without the prerequisite of having the same breakpoints or the same amount of content as in the previous implementation. \u0026nbsp; We can now create designs that adapt to the space they have, the content within them, and the content around them. With an intrinsic approach, we can construct responsive components without depending on container queries. Another 2010 moment? This intrinsic approach should in my view be every bit as groundbreaking as responsive web design was ten years ago. For me, it’s another “everything changed” moment. \u0026nbsp; But it doesn’t seem to be moving quite as fast; I haven’t yet had that same career-changing moment I had with responsive design, despite the widely shared and brilliant talk that brought it to my attention. \u0026nbsp; One reason for that could be that I now work in a large organization, which is quite different from the design agency role I had in 2010. In my agency days, every new project was a clean slate, a chance to try something new. Nowadays, projects use existing tools and frameworks and are often improvements to existing websites with an existing codebase. \u0026nbsp; Another could be that I feel more prepared for change now. In 2010 I was new to design in general; the shift was frightening and required a lot of learning. Also, an intrinsic approach isn’t exactly all-new; it’s about using existing skills and existing CSS knowledge in a different way. \u0026nbsp; You can’t framework your way out of a content problem Another reason for the slightly slower adoption of intrinsic design could be the lack of quick-fix framework solutions available to kick-start the change. \u0026nbsp; Responsive grid systems were all over the place ten years ago. With a framework like Bootstrap or Skeleton, you had a responsive design template at your fingertips. Intrinsic design and frameworks do not go hand in hand quite so well because the benefit of having a selection of units is a hindrance when it comes to creating layout templates. The beauty of intrinsic design is combining different units and experimenting with techniques to get the best for your content. And then there are design tools. We probably all, at some point in our careers, used Photoshop templates for desktop, tablet, and mobile devices to drop designs in and show how the site would look at all three stages. How do you do that now, with each component responding to content and layouts flexing as and when they need to? This type of design must happen in the browser, which personally I’m a big fan of. \u0026nbsp; The debate about “whether designers should code” is another that has rumbled on for years. When designing a digital product, we should, at the very least, design for a best- and worst-case scenario when it comes to content. To do this in a graphics-based software package is far from ideal. In code, we can add longer sentences, more radio buttons, and extra tabs, and watch in real time as the design adapts. Does it still work? Is the design too reliant on the current content? Personally, I look forward to the day intrinsic design is the standard for design, when a design component can be truly flexible and adapt to both its space and content with no reliance on device or container dimensions. Content first\u0026nbsp; Content is not constant. After all, to design for the unknown or unexpected we need to account for content changes like our earlier Subgrid card example that allowed the cards to respond to adjustments to their own content and the content of sibling elements. Thankfully, there’s more to CSS than layout, and plenty of properties and values can help us put content first. Subgrid and pseudo-elements like: : first-line and: : first-letter help to separate design from markup so we can create designs that allow for changes. Instead of old markup hacks like this— \u0026lt; p\u0026gt; \u0026lt; span class= \" first-line \" \u0026gt; First line of text with different styling\u0026lt; /span\u0026gt; . . . \u0026lt; /p\u0026gt; —we can target content based on where it appears. . Element: : first-line { font-size: 1. 4em; }. Element: : first-letter { color: red; } Much bigger additions to CSS include l ogical properties, which change the way we construct designs using logical dimensions (start and end) instead of physical ones (left and right), something CSS Grid also does with functions like min(), max(), and clamp(). This flexibility allows for directional changes according to content, a common requirement when we need to present content in multiple languages. In the past, this was often achieved with Sass mixins but was often limited to switching from left-to-right to right-to-left orientation. In the Sass version, directional variables need to be set. $direction: rtl; $opposite-direction: ltr; $start-direction: right; $end-direction: left; These variables can be used as values— body { direction: $direction; text-align: $start-direction; } —or as properties. Margin-#{$end-direction}: 10px; padding-#{$start-direction}: 10px; However, now we have native logical properties, removing the reliance on both Sass (or a similar tool) and pre-planning that necessitated using variables throughout a codebase. These properties also start to break apart the tight coupling between a design and strict physical dimensions, creating more flexibility for changes in language and in direction. Margin-block-end: 10px; padding-block-start: 10px; There are also native start and end values for properties like text-align, which means we can replace text-align: right with text-align: start. Like the earlier examples, these properties help to build out designs that aren’t constrained to one language; the design will reflect the content’s needs. Fixed and fluid\u0026nbsp; We briefly covered the power of combining fixed widths with fluid widths with intrinsic layouts. The min() and max() functions are a similar concept, allowing you to specify a fixed value with a flexible alternative. For min() this means setting a fluid minimum value and a maximum fixed value. . Element { width: min(50%, 300px); } The element in the figure above will be 50% of its container as long as the element’s width doesn’t exceed 300px. For max() we can set a flexible max value and a minimum fixed value. . Element { width: max(50%, 300px); } Now the element will be 50% of its container as long as the element’s width is at least 300px. This means we can set limits but allow content to react to the available space. The clamp() function builds on this by allowing us to set a preferred value with a third parameter. Now we can allow the element to shrink or grow if it needs to without getting to a point where it becomes unusable. . Element { width: clamp(300px, 50%, 600px); } This time, the element’s width will be 50% (the preferred value) of its container but never less than 300px and never more than 600px. With these techniques, we have a content-first approach to responsive design. We can separate content from markup, meaning the changes users make will not affect the design. We can start to future-proof designs by planning for unexpected changes in language or direction. And we can increase flexibility by setting desired dimensions alongside flexible alternatives, allowing for more or less content to be displayed correctly. Situation first Thanks to what we’ve discussed so far, we can cover device flexibility by changing our approach, designing around content and space instead of catering to devices. But what about that last bit of Jeffrey Zeldman’s quote, “. . . Situations you haven’t imagined”? It’s a very different thing to design for someone seated at a desktop computer as opposed to someone using a mobile phone and moving through a crowded street in glaring sunshine. Situations and environments are hard to plan for or predict because they change as people react to their own unique challenges and tasks. This is why choice is so important. One size never fits all, so we need to design for multiple scenarios to create equal experiences for all our users. Thankfully, there is a lot we can do to provide choice. Responsible design\u0026nbsp; “There are parts of the world where mobile data is prohibitively expensive, and where there is little or no broadband infrastructure. ” “ I Used the Web for a Day on a 50 MB Budget ” Chris Ashton One of the biggest assumptions we make is that people interacting with our designs have a good wifi connection and a wide screen monitor. But in the real world, our users may be commuters traveling on trains or other forms of transport using smaller mobile devices that can experience drops in connectivity. There is nothing more frustrating than a web page that won’t load, but there are ways we can help users use less data or deal with sporadic connectivity. The srcset attribute allows the browser to decide which image to serve. This means we can create smaller ‘cropped’ images to display on mobile devices in turn using less bandwidth and less data. \u0026lt; img src= \" image-file. Jpg \" srcset= \" large. Jpg 1024w, medium. Jpg 640w, small. Jpg 320w \" alt= \" Image alt text \" /\u0026gt; The preload attribute can also help us to think about how and when media is downloaded. It can be used to tell a browser about any critical assets that need to be downloaded with high priority, improving perceived performance and the user experience. \u0026lt; link rel= \" stylesheet \" href= \" style. Css \" \u0026gt; \u0026lt; ! --Standard stylesheet markup--\u0026gt; \u0026lt; link rel= \" preload \" href= \" style. Css \" as= \" style \" \u0026gt; \u0026lt; ! --Preload stylesheet markup--\u0026gt; There’s also native lazy loading, which indicates assets that should only be downloaded when they are needed. \u0026lt; img src= \" image. Png \" loading= \" lazy \" alt= \" … \" \u0026gt; With srcset, preload, and lazy loading, we can start to tailor a user’s experience based on the situation they find themselves in. What none of this does, however, is allow the user themselves to decide what they want downloaded, as the decision is usually the browser’s to make. So how can we put users in control? The return of media queries\u0026nbsp; Media queries have always been about much more than device sizes. They allow content to adapt to different situations, with screen size being just one of them. We’ve long been able to check for media types like print and speech and features such as hover, resolution, and color. These checks allow us to provide options that suit more than one scenario; it’s less about one-size-fits-all and more about serving adaptable content. \u0026nbsp; As of this writing, the Media Queries Level 5 spec is still under development. It introduces some really exciting queries that in the future will help us design for multiple other unexpected situations. For example, there’s a light-level feature that allows you to modify styles if a user is in sunlight or darkness. Paired with custom properties, these features allow us to quickly create designs or themes for specific environments. @media (light-level: normal) { --background-color: #fff; --text-color: #0b0c0c; } @media (light-level: dim) { --background-color: #efd226; --text-color: #0b0c0c; } Another key feature of the Level 5 spec is personalization. Instead of creating designs that are the same for everyone, users can choose what works for them. This is achieved by using features like prefers-reduced-data, prefers-color-scheme, and prefers-reduced-motion, the latter two of which already enjoy broad browser support. These features tap into preferences set via the operating system or browser so people don’t have to spend time making each site they visit more usable. Media queries like this go beyond choices made by a browser to grant more control to the user. Expect the unexpected In the end, the one thing we should always expect is for things to change. Devices in particular change faster than we can keep up, with foldable screens already on the market. We can’t design the same way we have for this ever-changing landscape, but we can design for content. By putting content first and allowing that content to adapt to whatever space surrounds it, we can create more robust, flexible designs that increase the longevity of our products. \u0026nbsp; A lot of the CSS discussed here is about moving away from layouts and putting content at the heart of design. From responsive components to fixed and fluid units, there is so much more we can do to take a more intrinsic approach. Even better, we can test these techniques during the design phase by designing in-browser and watching how our designs adapt in real-time. When it comes to unexpected situations, we need to make sure our products are usable when people need them, whenever and wherever that might be. We can move closer to achieving this by involving users in our design decisions, by creating choice via browsers, and by giving control to our users with user-preference-based media queries. \u0026nbsp; Good design for the unexpected should allow for change, provide choice, and give control to those we serve: our users themselves.","url":"\n\t\t\t\t\thttps://alistapart.com/article/designing-for-the-unexpected/\t\t\t\t","image":"https://curated-letters.s3.wasabisys.com/image5f1b55630-733a-41af-acab-5fa837fcc5fb.png","numberInCategoryInIssue":0,"curatedById":null,"issueId":"n4uh1aqpegbquqp84m7mimgt","categoryId":"clpwpy59r000a0apugdok9rud","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdAt":"2024-07-30T15:49:56.682Z","updatedAt":"2024-10-08T21:15:00.613Z","updatedById":null,"createdById":null,"sponsoredById":null,"openPixelUrl":null,"sponsorStatus":[],"sourceName":"RSSFEED","RSSFeedSourceId":"clz8lg8nj02crpe0a7npk7k2f","collectImage":true,"cleanTextProcessed":true,"archived":false,"autoEnhancedBodyFlag":true,"sponsoredBy":null},{"id":"qjtcdkby4pal8dz7pcy7g4e1","title":"Guía Completa sobre Pruebas Unitarias en Angular 16","favorite":false,"body":"A comprehensive guide to unit testing in Angular 16, covering essential techniques and tools to ensure robust application development.","fullBody":"Las pruebas unitarias son una parte esencial del desarrollo de software, ya que garantizan que cada componente de nuestra aplicación funcione correctamente. En este artículo, veremos cómo realizar pruebas unitarias en Angular 16, una de las versiones no tan recientes pero potentes de este popular framework. ¿Qué son las Pruebas Unitarias? Son pruebas automáticas que validan el comportamiento de una unidad de código, como una función o un componente. Estas pruebas son fundamentales para asegurar que el código funcione según lo esperado y para facilitar el mantenimiento y la evolución de la aplicación. Beneficios de las Pruebas Unitarias en Angular Detección Temprana de Errores: Permiten identificar y corregir errores en etapas tempranas del desarrollo. Facilitan el Refactorizado: Al tener una suite de pruebas, podemos refactorizar el código con confianza, sabiendo que cualquier cambio que rompa la funcionalidad será detectado. Mejoran la Documentación: Las pruebas actúan como una documentación viva del comportamiento esperado de la aplicación. Aumentan la Confianza en el Código: Desarrolladores y stakeholders pueden tener mayor confianza en la estabilidad y la calidad del código. Configuración Inicial Para empezar a trabajar con pruebas unitarias en Angular 16, necesitamos tener configurado nuestro entorno de desarrollo. Asumiremos que ya tienes Node. Js y Angular CLI instalados. 1. - Crear un Nuevo Proyecto Angular: ng new angular-testing cd angular-testing 2. - Instalar Dependencias Necesarias: Angular ya viene con Jasmine y Karma configurados para pruebas unitarias. Jasmine es el framework de pruebas y Karma es el ejecutor de pruebas. Estructura de una Prueba Unitaria en Angular Supongamos que tenemos un servicio simple llamado DataService: // src/app/data. Service. Ts import { Injectable } from ' @angular/core ' ; @Injectable({ providedIn: ' root ' }) export class DataService { getData(): string { return ' Hello, Angular 16! ' ; } } Crear la Prueba Unitaria Vamos a crear una prueba unitaria para este servicio. // src/app/data. Service. Spec. Ts import { TestBed } from ' @angular/core/testing ' ; import { DataService } from ' . /data. Service ' ; describe( ' DataService ' , () =\u0026gt; { let service: DataService; beforeEach(() =\u0026gt; { TestBed. ConfigureTestingModule({}); service = TestBed. Inject(DataService); }); it( ' should be created ' , () =\u0026gt; { expect(service). ToBeTruthy(); }); it( ' should return \" Hello, Angular 16! \" ' , () =\u0026gt; { const data = service. GetData(); expect(data). ToBe( ' Hello, Angular 16! ' ); }); }); Desglose de la Prueba Configuración del Módulo de Pruebas: TestBed. ConfigureTestingModule se usa para configurar y compilar el entorno de pruebas para el servicio. Inyección del Servicio: TestBed. Inject(DataService) se usa para obtener una instancia del servicio que queremos probar. Expectativas: Utilizamos expect para verificar que el servicio se crea correctamente y que el método getData devuelve el valor esperado. Pruebas Unitarias de Componentes Vamos a crear un componente simple y escribir pruebas unitarias para él. // src/app/hello. Component. Ts import { Component } from ' @angular/core ' ; @Component({ selector: ' app-hello ' , template: ' \u0026lt; h1\u0026gt; {{ title }}\u0026lt; /h1\u0026gt; ' }) export class HelloComponent { title = ' Hello, Angular 16! ' ; } Crear la Prueba Unitaria para el Componente // src/app/hello. Component. Spec. Ts import { ComponentFixture, TestBed } from ' @angular/core/testing ' ; import { HelloComponent } from ' . /hello. Component ' ; describe( ' HelloComponent ' , () =\u0026gt; { let component: HelloComponent; let fixture: ComponentFixture\u0026lt; HelloComponent\u0026gt; ; beforeEach(() =\u0026gt; { TestBed. ConfigureTestingModule({ declarations: [HelloComponent] }). CompileComponents(); fixture = TestBed. CreateComponent(HelloComponent); component = fixture. ComponentInstance; fixture. DetectChanges(); }); it( ' should create ' , () =\u0026gt; { expect(component). ToBeTruthy(); }); it( ' should have title \" Hello, Angular 16! \" ' , () =\u0026gt; { const compiled = fixture. NativeElement as HTMLElement; expect(compiled. QuerySelector( ' h1 ' )? . TextContent). ToBe( ' Hello, Angular 16! ' ); }); }); Desglose de la Prueba de Componente Configuración del Módulo de Pruebas: Se declara el componente HelloComponent en el módulo de pruebas. Creación del Componente: TestBed. CreateComponent se usa para crear una instancia del componente. Detección de Cambios: fixture. DetectChanges se llama para actualizar el DOM con los cambios del componente. Expectativas: Verificamos que el componente se crea correctamente y que el título se renderiza como se espera. Ejecutar las Pruebas Para ejecutar las pruebas, simplemente corre el siguiente comando: ng test Este comando ejecutará Karma, que abrirá un navegador y ejecutará todas las pruebas unitarias, mostrando los resultados en tiempo real. Conclusión Las pruebas unitarias son una herramienta poderosa para mantener la calidad del código en proyectos Angular. Angular 16 proporciona un entorno robusto y fácil de usar para escribir y ejecutar estas pruebas. Al seguir buenas prácticas y realizar pruebas constantes, puedes asegurarte de que tu aplicación sea confiable y fácil de mantener. Espero que esta guía te haya proporcionado una comprensión clara y útil sobre cómo implementar pruebas unitarias en Angular 16.","url":"https://dev.to/nerm_frontend/guia-completa-sobre-pruebas-unitarias-en-angular-16-4djl","image":"https://curated-letters.s3.wasabisys.com/wab7j2tmhks9f3ukk7ii021dbb0a-c060-4a7d-85fa-f675399881a9.jpg","numberInCategoryInIssue":0,"curatedById":null,"issueId":"n4uh1aqpegbquqp84m7mimgt","categoryId":"clpwrwt5v00elpu0aj8tszo0y","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdAt":"2024-05-28T11:45:50.430Z","updatedAt":"2024-10-22T01:10:10.784Z","updatedById":null,"createdById":null,"sponsoredById":null,"openPixelUrl":null,"sponsorStatus":[],"sourceName":"RSSFEED","RSSFeedSourceId":"clpwq09u3006xpu0ajcarv458","collectImage":true,"cleanTextProcessed":true,"archived":false,"autoEnhancedBodyFlag":true,"sponsoredBy":null},{"id":"y61w28xqv03xc39ueamtzr9w","title":"Voice Content and Usability","favorite":false,"body":"An exploration of how voice content can enhance usability by providing intuitive and accessible user experiences, discussing key design principles for integrating voice interfaces.","fullBody":"We’ve been having conversations for thousands of years. Whether to convey information, conduct transactions, or simply to check in on one another, people have yammered away, chattering and gesticulating, through spoken conversation for countless generations. Only in the last few millennia have we begun to commit our conversations to writing, and only in the last few decades have we begun to outsource them to the computer, a machine that shows much more affinity for written correspondence than for the slangy vagaries of spoken language. Computers have trouble because between spoken and written language, speech is more primordial. To have successful conversations with us, machines must grapple with the messiness of human speech: the disfluencies and pauses, the gestures and body language, and the variations in word choice and spoken dialect that can stymie even the most carefully crafted human-computer interaction. In the human-to-human scenario, spoken language also has the privilege of face-to-face contact, where we can readily interpret nonverbal social cues. In contrast, written language immediately concretizes as we commit it to record and retains usages long after they become obsolete in spoken communication (the salutation “To whom it may concern, ” for example), generating its own fossil record of outdated terms and phrases. Because it tends to be more consistent, polished, and formal, written text is fundamentally much easier for machines to parse and understand. Spoken language has no such luxury. Besides the nonverbal cues that decorate conversations with emphasis and emotional context, there are also verbal cues and vocal behaviors that modulate conversation in nuanced ways: how something is said, not what. Whether rapid-fire, low-pitched, or high-decibel, whether sarcastic, stilted, or sighing, our spoken language conveys much more than the written word could ever muster. So when it comes to voice interfaces—the machines we conduct spoken conversations with—we face exciting challenges as designers and content strategists. Voice Interactions We interact with voice interfaces for a variety of reasons, but according to Michael McTear, Zoraida Callejas, and David Griol in The Conversational Interface, those motivations by and large mirror the reasons we initiate conversations with other people, too (http: //bkaprt. Com/vcu36/01-01). Generally, we start up a conversation because: we need something done (such as a transaction), we want to know something (information of some sort), or we are social beings and want someone to talk to (conversation for conversation’s sake). These three categories—which I call transactional, informational, and prosocial —also characterize essentially every voice interaction: a single conversation from beginning to end that realizes some outcome for the user, starting with the voice interface’s first greeting and ending with the user exiting the interface. Note here that a conversation in our human sense—a chat between people that leads to some result and lasts an arbitrary length of time—could encompass multiple transactional, informational, and prosocial voice interactions in succession. In other words, a voice interaction is a conversation, but a conversation is not necessarily a single voice interaction. Purely prosocial conversations are more gimmicky than captivating in most voice interfaces, because machines don’t yet have the capacity to really want to know how we’re doing and to do the sort of glad-handing humans crave. There’s also ongoing debate as to whether users actually prefer the sort of organic human conversation that begins with a prosocial voice interaction and shifts seamlessly into other types. In fact, in Voice User Interface Design, Michael Cohen, James Giangola, and Jennifer Balogh recommend sticking to users’ expectations by mimicking how they interact with other voice interfaces rather than trying too hard to be human—potentially alienating them in the process (http: //bkaprt. Com/vcu36/01-01). That leaves two genres of conversations we can have with one another that a voice interface can easily have with us, too: a transactional voice interaction realizing some outcome (“buy iced tea”) and an informational voice interaction teaching us something new (“discuss a musical”). Transactional voice interactions Unless you’re tapping buttons on a food delivery app, you’re generally having a conversation—and therefore a voice interaction—when you order a Hawaiian pizza with extra pineapple. Even when we walk up to the counter and place an order, the conversation quickly pivots from an initial smattering of neighborly small talk to the real mission at hand: ordering a pizza (generously topped with pineapple, as it should be). Alison: Hey, how’s it going? Burhan: Hi, welcome to Crust Deluxe! It’s cold out there. How can I help you? Alison: Can I get a Hawaiian pizza with extra pineapple? Burhan: Sure, what size? Alison: Large. Burhan: Anything else? Alison: No thanks, that’s it. Burhan: Something to drink? Alison: I’ll have a bottle of Coke. Burhan: You got it. That’ll be $13. 55 and about fifteen minutes. Each progressive disclosure in this transactional conversation reveals more and more of the desired outcome of the transaction: a service rendered or a product delivered. Transactional conversations have certain key traits: they’re direct, to the point, and economical. They quickly dispense with pleasantries. Informational voice interactions Meanwhile, some conversations are primarily about obtaining information. Though Alison might visit Crust Deluxe with the sole purpose of placing an order, she might not actually want to walk out with a pizza at all. She might be just as interested in whether they serve halal or kosher dishes, gluten-free options, or something else. Here, though we again have a prosocial mini-conversation at the beginning to establish politeness, we’re after much more. Alison: Hey, how’s it going? Burhan: Hi, welcome to Crust Deluxe! It’s cold out there. How can I help you? Alison: Can I ask a few questions? Burhan: Of course! Go right ahead. Alison: Do you have any halal options on the menu? Burhan: Absolutely! We can make any pie halal by request. We also have lots of vegetarian, ovo-lacto, and vegan options. Are you thinking about any other dietary restrictions? Alison: What about gluten-free pizzas? Burhan: We can definitely do a gluten-free crust for you, no problem, for both our deep-dish and thin-crust pizzas. Anything else I can answer for you? Alison: That’s it for now. Good to know. Thanks! Burhan: Anytime, come back soon! This is a very different dialogue. Here, the goal is to get a certain set of facts. I nf ormational conversations are investigative quests for the truth—research expeditions to gather data, news, or facts. Voice interactions that are informational might be more long-winded than transactional conversations by necessity. Responses tend to be lengthier, more informative, and carefully communicated so the customer understands the key takeaways. Voice Interfaces At their core, voice interfaces employ speech to support users in reaching their goals. But simply because an interface has a voice component doesn’t mean that every user interaction with it is mediated through voice. Because multimodal voice interfaces can lean on visual components like screens as crutches, we’re most concerned in this book with pure voice interfaces, which depend entirely on spoken conversation, lack any visual component whatsoever, and are therefore much more nuanced and challenging to tackle. Though voice interfaces have long been integral to the imagined future of humanity in science fiction, only recently have those lofty visions become fully realized in genuine voice interfaces. Interactive voice response (IVR) systems Though written conversational interfaces have been fixtures of computing for many decades, voice interfaces first emerged in the early 1990s with text-to-speech (TTS) dictation programs that recited written text aloud, as well as speech-enabled in-car systems that gave directions to a user-provided address. With the advent of interactive voice response (IVR) systems, intended as an alternative to overburdened customer service representatives, we became acquainted with the first true voice interfaces that engaged in authentic conversation. IVR systems allowed organizations to reduce their reliance on call centers but soon became notorious for their clunkiness. Commonplace in the corporate world, these systems were primarily designed as metaphorical switchboards to guide customers to a real phone agent (“Say R eservations to book a flight or check an itinerary”); chances are you will enter a conversation with one when you call an airline or hotel conglomerate. Despite their functional issues and users’ frustration with their inability to speak to an actual human right away, IVR systems proliferated in the early 1990s across a variety of industries (http: //bkaprt. Com/vcu36/01-02, PDF). While IVR systems are great for highly repetitive, monotonous conversations that generally don’t veer from a single format, they have a reputation for less scintillating conversation than we’re used to in real life (or even in science fiction). Screen readers Parallel to the evolution of IVR systems was the invention of the screen reader, a tool that transcribes visual content into synthesized speech. For Blind or visually impaired website users, it’s the predominant method of interacting with text, multimedia, or form elements. Screen readers represent perhaps the closest equivalent we have today to an out-of-the-box implementation of content delivered through voice. Among the first screen readers known by that moniker was the Screen Reader for the BBC Micro and NEEC Portable developed by the Research Centre for the Education of the Visually Handicapped (RCEVH) at the University of Birmingham in 1986 (http: //bkaprt. Com/vcu36/01-03). That same year, Jim Thatcher created the first IBM Screen Reader for text-based computers, later recreated for computers with graphical user interfaces (GUIs) (http: //bkaprt. Com/vcu36/01-04). With the rapid growth of the web in the 1990s, the demand for accessible tools for websites exploded. Thanks to the introduction of semantic HTML and especially ARIA roles beginning in 2008, screen readers started facilitating speedy interactions with web pages that ostensibly allow disabled users to traverse the page as an aural and temporal space rather than a visual and physical one. In other words, screen readers for the web “provide mechanisms that translate visual design constructs—proximity, proportion, etc. —into useful information, ” writes Aaron Gustafson in A List Apart. “At least they do when documents are authored thoughtfully” (http: //bkaprt. Com/vcu36/01-05). Though deeply instructive for voice interface designers, there’s one significant problem with screen readers: they’re difficult to use and unremittingly verbose. The visual structures of websites and web navigation don’t translate well to screen readers, sometimes resulting in unwieldy pronouncements that name every manipulable HTML element and announce every formatting change. For many screen reader users, working with web-based interfaces exacts a cognitive toll. In Wired, accessibility advocate and voice engineer Chris Maury considers why the screen reader experience is ill-suited to users relying on voice: From the beginning, I hated the way that Screen Readers work. Why are they designed the way they are? It makes no sense to present information visually and then, and only then, translate that into audio. All of the time and energy that goes into creating the perfect user experience for an app is wasted, or even worse, adversely impacting the experience for blind users. (http: //bkaprt. Com/vcu36/01-06) In many cases, well-designed voice interfaces can speed users to their destination better than long-winded screen reader monologues. After all, visual interface users have the benefit of darting around the viewport freely to find information, ignoring areas irrelevant to them. Blind users, meanwhile, are obligated to listen to every utterance synthesized into speech and therefore prize brevity and efficiency. Disabled users who have long had no choice but to employ clunky screen readers may find that voice interfaces, particularly more modern voice assistants, offer a more streamlined experience. Voice assistants When we think of voice assistants (the subset of voice interfaces now commonplace in living rooms, smart homes, and offices), many of us immediately picture HAL from 2001: A Space Odyssey or hear Majel Barrett’s voice as the omniscient computer in Star Trek. Voice assistants are akin to personal concierges that can answer questions, schedule appointments, conduct searches, and perform other common day-to-day tasks. And they’re rapidly gaining more attention from accessibility advocates for their assistive potential. Before the earliest IVR systems found success in the enterprise, Apple published a demonstration video in 1987 depicting the Knowledge Navigator, a voice assistant that could transcribe spoken words and recognize human speech to a great degree of accuracy. Then, in 2001, Tim Berners-Lee and others formulated their vision for a Semantic Web “agent” that would perform typical errands like “checking calendars, making appointments, and finding locations” (http: //bkaprt. Com/vcu36/01-07, behind paywall). It wasn’t until 2011 that Apple’s Siri finally entered the picture, making voice assistants a tangible reality for consumers. Thanks to the plethora of voice assistants available today, there is considerable variation in how programmable and customizable certain voice assistants are over others (Fig 1. 1). At one extreme, everything except vendor-provided features is locked down; for example, at the time of their release, the core functionality of Apple’s Siri and Microsoft’s Cortana couldn’t be extended beyond their existing capabilities. Even today, it isn’t possible to program Siri to perform arbitrary functions, because there’s no means by which developers can interact with Siri at a low level, apart from predefined categories of tasks like sending messages, hailing rideshares, making restaurant reservations, and certain others. At the opposite end of the spectrum, voice assistants like Amazon Alexa and Google Home offer a core foundation on which developers can build custom voice interfaces. For this reason, programmable voice assistants that lend themselves to customization and extensibility are becoming increasingly popular for developers who feel stifled by the limitations of Siri and Cortana. Amazon offers the Alexa Skills Kit, a developer framework for building custom voice interfaces for Amazon Alexa, while Google Home offers the ability to program arbitrary Google Assistant skills. Today, users can choose from among thousands of custom-built skills within both the Amazon Alexa and Google Assistant ecosystems. Fig 1. 1: Voice assistants like Amazon Alexa and Google Home tend to be more programmable, and thus more flexible, than their counterpart Apple Siri. As corporations like Amazon, Apple, Microsoft, and Google continue to stake their territory, they’re also selling and open-sourcing an unprecedented array of tools and frameworks for designers and developers that aim to make building voice interfaces as easy as possible, even without code. Often by necessity, voice assistants like Amazon Alexa tend to be monochannel —they’re tightly coupled to a device and can’t be accessed on a computer or smartphone instead. By contrast, many development platforms like Google’s Dialogflow have introduced omnichannel capabilities so users can build a single conversational interface that then manifests as a voice interface, textual chatbot, and IVR system upon deployment. I don’t prescribe any specific implementation approaches in this design-focused book, but in Chapter 4 we’ll get into some of the implications these variables might have on the way you build out your design artifacts. Voice Content Simply put, voice content is content delivered through voice. To preserve what makes human conversation so compelling in the first place, voice content needs to be free-flowing and organic, contextless and concise—everything written content isn’t. Our world is replete with voice content in various forms: screen readers reciting website content, voice assistants rattling off a weather forecast, and automated phone hotline responses governed by IVR systems. In this book, we’re most concerned with content delivered auditorily—not as an option, but as a necessity. For many of us, our first foray into informational voice interfaces will be to deliver content to users. There’s only one problem: any content we already have isn’t in any way ready for this new habitat. So how do we make the content trapped on our websites more conversational? And how do we write new copy that lends itself to voice interactions? Lately, we’ve begun slicing and dicing our content in unprecedented ways. Websites are, in many respects, colossal vaults of what I call macrocontent: lengthy prose that can extend for infinitely scrollable miles in a browser window, like microfilm viewers of newspaper archives. Back in 2002, well before the present-day ubiquity of voice assistants, technologist Anil Dash defined microcontent as permalinked pieces of content that stay legible regardless of environment, such as email or text messages: A day’s weather forcast [sic], the arrival and departure times for an airplane flight, an abstract from a long publication, or a single instant message can all be examples of microcontent. (http: //bkaprt. Com/vcu36/01-08) I’d update Dash’s definition of microcontent to include all examples of bite-sized content that go well beyond written communiqués. After all, today we encounter microcontent in interfaces where a small snippet of copy is displayed alone, unmoored from the browser, like a textbot confirmation of a restaurant reservation. Microcontent offers the best opportunity to gauge how your content can be stretched to the very edges of its capabilities, informing delivery channels both established and novel. As microcontent, voice content is unique because it’s an example of how content is experienced in time rather than in space. We can glance at a digital sign underground for an instant and know when the next train is arriving, but voice interfaces hold our attention captive for periods of time that we can’t easily escape or skip, something screen reader users are all too familiar with. Because microcontent is fundamentally made up of isolated blobs with no relation to the channels where they’ll eventually end up, we need to ensure that our microcontent truly performs well as voice content—and that means focusing on the two most important traits of robust voice content: voice content legibility and voice content discoverability. Fundamentally, the legibility and discoverability of our voice content both have to do with how voice content manifests in perceived time and space.","url":"\n\t\t\t\t\thttps://alistapart.com/article/voice-content-and-usability/\t\t\t\t","image":"https://curated-letters.s3.wasabisys.com/1bb4a2a27-b04a-4bcd-ae47-c8c4fda99cb1.png","numberInCategoryInIssue":0,"curatedById":null,"issueId":"n4uh1aqpegbquqp84m7mimgt","categoryId":"clpwpy59r000a0apugdok9rud","newsletterId":"clpwppyvd0068pu0avdxqsp42","createdAt":"2024-07-30T15:49:56.682Z","updatedAt":"2024-10-09T06:57:08.145Z","updatedById":null,"createdById":null,"sponsoredById":null,"openPixelUrl":null,"sponsorStatus":[],"sourceName":"RSSFEED","RSSFeedSourceId":"clz8lg8nj02crpe0a7npk7k2f","collectImage":true,"cleanTextProcessed":true,"archived":false,"autoEnhancedBodyFlag":true,"sponsoredBy":null}],"issueCategories":[{"id":"qte6cbeexfb2fehgc5hm90gh","categoryOrder":0,"categoryName":"Unassigned","categoryId":"clpwpy59r000a0apugdok9rud","issueId":"n4uh1aqpegbquqp84m7mimgt","categoryBackgroundColor":null,"categoryIcon":null,"categoryTitleColor":null,"categoryIconWidth":null,"categoryDefault":true,"createdAt":"2025-02-25T17:00:06.802Z","updatedAt":"2025-02-25T17:00:06.802Z"},{"id":"ekr1v9wigty125s6h0stvg6w","categoryOrder":2,"categoryName":"Learn","categoryId":"clpwrwt5v00elpu0aj8tszo0y","issueId":"n4uh1aqpegbquqp84m7mimgt","categoryBackgroundColor":null,"categoryIcon":null,"categoryTitleColor":null,"categoryIconWidth":null,"categoryDefault":false,"createdAt":"2025-02-25T17:00:07.981Z","updatedAt":"2025-02-25T17:00:07.981Z"},{"id":"z0bisr5nhgxgjh8q9wfdpzei","categoryOrder":4,"categoryName":"Tools \u0026 Code","categoryId":"clpwrwzi600enpu0a2r98t2li","issueId":"n4uh1aqpegbquqp84m7mimgt","categoryBackgroundColor":null,"categoryIcon":null,"categoryTitleColor":null,"categoryIconWidth":null,"categoryDefault":false,"createdAt":"2025-02-25T17:00:09.377Z","updatedAt":"2025-02-25T17:00:09.377Z"}],"IssueAd":[{"id":"intyfvksys0kwmpz4027pm08","issueId":"n4uh1aqpegbquqp84m7mimgt","cost":0,"newsletterAdId":"cm20rn6tt0092mh0ecud1zjna","url":"https://www.elitecoders.co/","description":null,"title":"EliteCoders 280x140 Transparent","imageUrl":null,"logoUrl":"https://curated-letters.s3.wasabisys.com/b36a2200-2f3d-4543-ab8d-4c2e52c893d1.png","placement":"LOGO","createdAt":"2024-10-08T18:20:06.353Z","updatedAt":"2025-02-27T11:38:19.969Z","totalClicks":30,"uniqueClicks":20,"newsletterAd":{"id":"cm20rn6tt0092mh0ecud1zjna","url":"https://www.elitecoders.co/","description":null,"title":"EliteCoders 280x140 Transparent","imageUrl":null,"logoUrl":"https://curated-letters.s3.wasabisys.com/b36a2200-2f3d-4543-ab8d-4c2e52c893d1.png","budget":1,"usedAmount":0,"cpc":null,"status":"ACTIVE","placement":"LOGO","contactEmail":null,"invoiceLink":null,"invoiceId":null,"invoiceDue":null,"isPlaceholder":true,"publishCount":3103,"createdAt":"2024-10-08T18:20:06.353Z","updatedAt":"2025-03-01T02:13:25.844Z","paidAt":"2024-10-08T18:20:06.351Z","totalClicks":5085,"uniqueClicks":3227,"archived":false,"archivedAt":null,"createdById":"clikcel5r00008e0bh37oib88","notes":"","selectedNewsletterIds":[],"selectAllNewsletters":true}},{"id":"isruhp3w0jm74mnl3z578b94","issueId":"n4uh1aqpegbquqp84m7mimgt","cost":0,"newsletterAdId":"cm6pe8f1605wtqh0e0vzwdtn5","url":"https://sparklp.co/p/616bb41e49","description":"\u003cdiv\u003e\u003cspan style=\"color: var(--tw-prose-body); font-size: 0.875rem; background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003eGet the most important tech, science, \u0026amp; coding news in a free daily email. Read by +1,250,000 software engineers and tech workers.\u0026nbsp; TLDR Newsletter.\u003c/span\u003e\u003c/div\u003e","title":"Keep up with Tech in 5 minutes","imageUrl":"","logoUrl":null,"placement":"FOOTER","createdAt":"2025-02-03T18:37:45.882Z","updatedAt":"2025-02-27T12:48:06.603Z","totalClicks":34,"uniqueClicks":33,"newsletterAd":{"id":"cm6pe8f1605wtqh0e0vzwdtn5","url":"https://sparklp.co/p/616bb41e49","description":"\u003cdiv\u003e\u003cspan style=\"color: var(--tw-prose-body); font-size: 0.875rem; background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003eGet the most important tech, science, \u0026amp; coding news in a free daily email. Read by +1,250,000 software engineers and tech workers.\u0026nbsp; TLDR Newsletter.\u003c/span\u003e\u003c/div\u003e","title":"Keep up with Tech in 5 minutes","imageUrl":"","logoUrl":null,"budget":1,"usedAmount":0,"cpc":0,"status":"ACTIVE","placement":"FOOTER","contactEmail":null,"invoiceLink":null,"invoiceId":null,"invoiceDue":null,"isPlaceholder":true,"publishCount":1287,"createdAt":"2025-02-03T18:37:45.882Z","updatedAt":"2025-02-28T13:03:30.186Z","paidAt":"2025-02-03T18:37:45.880Z","totalClicks":581,"uniqueClicks":546,"archived":false,"archivedAt":null,"createdById":"clikcel5r00008e0bh37oib88","notes":"","selectedNewsletterIds":[],"selectAllNewsletters":true}},{"id":"uaw4pbko1nyip8i4egzcbkci","issueId":"n4uh1aqpegbquqp84m7mimgt","cost":0,"newsletterAdId":"cm4j0qs4p1db3qs0d7t5mw8g6","url":"https://ibrief.co?utm_source=Newsletter+Ad\u0026utm_medium=Banner+and+Text\u0026utm_campaign=launch\u0026utm_id=CuratedLetters","description":"\u003cp\u003eEver feel like you're drowning in browser tabs? iBrief turns long articles into clear insights in seconds. Share them on LinkedIn and Twitter with one click.\u003c/p\u003e\u003cp\u003e\u003cb\u003eBe The Expert\u003c/b\u003e and stay on top of industry news without being overwhelmed\u003cbr\u003e\u003cb style=\"color: var(--color-text-light); background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003eShare Smarter\u003c/b\u003e\u003cfont color=\"rgba(0, 0, 0, 0)\"\u003e \u003c/font\u003ewith auto-format insights for each social platform\u003cbr\u003e\u003cb style=\"color: var(--tw-prose-body); font-size: 0.875rem; background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003eSave Hours\u003c/b\u003e\u003cspan style=\"color: var(--tw-prose-body); font-size: 0.875rem; background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003e with our users cutting content time by 80%\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://ibrief.co?utm_source=Newsletter+Ad\u0026amp;utm_medium=Banner+and+Text\u0026amp;utm_campaign=launch\u0026amp;utm_id=CuratedLetters\"\u003eTry it free →\u003c/a\u003e\u003cspan style=\"color: var(--tw-prose-body); font-size: 0.875rem; background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003e\u003c/span\u003e\u003c/p\u003e","title":"Found a great article but have no time to read it?","imageUrl":"https://curated-letters.s3.wasabisys.com/23f81d36-4708-4111-bcac-0d4a56bcde72.png","logoUrl":null,"placement":"HEADER","createdAt":"2024-12-10T22:14:06.313Z","updatedAt":"2025-02-28T11:25:31.366Z","totalClicks":34,"uniqueClicks":33,"newsletterAd":{"id":"cm4j0qs4p1db3qs0d7t5mw8g6","url":"https://ibrief.co?utm_source=Newsletter+Ad\u0026utm_medium=Banner+and+Text\u0026utm_campaign=launch\u0026utm_id=CuratedLetters","description":"\u003cp\u003eEver feel like you're drowning in browser tabs? iBrief turns long articles into clear insights in seconds. Share them on LinkedIn and Twitter with one click.\u003c/p\u003e\u003cp\u003e\u003cb\u003eBe The Expert\u003c/b\u003e and stay on top of industry news without being overwhelmed\u003cbr\u003e\u003cb style=\"color: var(--color-text-light); background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003eShare Smarter\u003c/b\u003e\u003cfont color=\"rgba(0, 0, 0, 0)\"\u003e \u003c/font\u003ewith auto-format insights for each social platform\u003cbr\u003e\u003cb style=\"color: var(--tw-prose-body); font-size: 0.875rem; background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003eSave Hours\u003c/b\u003e\u003cspan style=\"color: var(--tw-prose-body); font-size: 0.875rem; background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003e with our users cutting content time by 80%\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://ibrief.co?utm_source=Newsletter+Ad\u0026amp;utm_medium=Banner+and+Text\u0026amp;utm_campaign=launch\u0026amp;utm_id=CuratedLetters\"\u003eTry it free →\u003c/a\u003e\u003cspan style=\"color: var(--tw-prose-body); font-size: 0.875rem; background-color: rgb(255 255 255/var(--tw-bg-opacity));\"\u003e\u003c/span\u003e\u003c/p\u003e","title":"Found a great article but have no time to read it?","imageUrl":"https://curated-letters.s3.wasabisys.com/23f81d36-4708-4111-bcac-0d4a56bcde72.png","logoUrl":null,"budget":1,"usedAmount":0,"cpc":null,"status":"ACTIVE","placement":"HEADER","contactEmail":null,"invoiceLink":null,"invoiceId":null,"invoiceDue":null,"isPlaceholder":true,"publishCount":1369,"createdAt":"2024-12-10T22:14:06.313Z","updatedAt":"2025-02-28T13:38:58.885Z","paidAt":"2024-12-10T22:14:06.310Z","totalClicks":1093,"uniqueClicks":900,"archived":false,"archivedAt":null,"createdById":"clikcel5r00008e0bh37oib88","notes":"","selectedNewsletterIds":[],"selectAllNewsletters":true}}]}]},"totalNumber":452,"next":null,"prev":{"publishingAt":"2025-02-19T17:00:00.000Z"},"subscriberId":"","disableReCaptcha":false},"__lang":"en","__namespaces":{"common":{"settings":"Settings","stripe-redirect":"You'll be redirected to Stripe","sign-in":"Sign In","sign-in/up":"Sign In/Up","to-app":"Go to App","new-issue-button":"New Issue","save":"Save","links":{"dashboard":"Dashboard","draft-issues":"Draft Issues","published-issues":"Published Issues","scheduled-issues":"Scheduled Issues","billing":"Billing","sign-out":"Sign Out","items":"Collected Items","categories":"Categories","next-issue":"Next Issue","subscriber":"Email Subscribers","pricing":"Pricing","settings":"Publication Settings","statistics":"Statistics","rewards":"Rewards","account":"Account","publications":"Publications","users":"Users","issues":"Issues","sponsors":"Sponsors","earnings":"Earnings","subscription":"Subscription","social-media-integrations":"Social Media Integrations","admin":{"pending-newsletters":"Pending Newsletters","users":"Users","app-settings":"App Settings","questions":"Subscriber Questions","search-newsletters":"Search Newsletters","monitoring":"Monitoring"},"marketplace":{"campaign-manager":"Campaign Manager","newsletter-campaign":"Newsletter Campaign","link-campaign":"Link Campaign","home":"Dashboard","ads":"Ads","running-ads":"Running Ads","old-ads":"Old Ads","payments":{"manage":"Billing"}}},"publication":"Publication","attention-needed":"Attention needed","subscribe-first-to-be-able-to-refer":"Subscribe first to be able to refer to your publication","thanks-for-subscribing":"Thanks for subscribing!","subscriber-already-verified":"You have already verified your email address.","subscriber-verified":"Your email address has been verified.","subscriber-login-verified":"You have successfully logged in.","ad-campaign-approved":"Ad campaign has been approved successfully.","ad-campaign-rejected":"Ad campaign has been rejected successfully.","ad-campaign-taken-action-before":"You or someone form team have already taken action on this ad campaign.","newsletter-ad-taken-action-before":"You or someone from team have already taken action on this newsletter ad.","link-expired":"Link has expired.","newsletter-ad-approved":"Newsletter ad has been approved successfully.","newsletter-ad-rejected":"Newsletter ad has been rejected.","subscriber-unsubscribed":"You have successfully unsubscribed.","subscriber-reactivated":"You have successfully reactivated your subscription.","subscriber-already-unsubscribed":"You have already unsubscribed.","newsletter-not-found":"Newsletter not found","subscriber-login-verification-expired":"Your subscription verification link has expired, we just sent you a new one.","invalid-token":"Token might be invalid or expired, please try again.","activation":{"alert-newsletter-deactivated":"Your publications is deactivated, please renew/upgrade your plan","your-news-letter-will-be-deactivated":"Kindly note that you have exceeded the limit of your subscribers for you plan, please upgrade to a higher plan or your newsletters will be deactivated before next Monday!"},"invalid-token-response":"Invalid token response","linkedin-callback-error":"Something went wrong, please try again.","linkedin-callback-success":"LinkedIn integration has been added successfully.","reddit-callback-error":"Something went wrong, please try again.","reddit-callback-success":"Reddit integration has been added successfully."},"publication":{"subscribe":"Subscribe","your-email-address":"Your email address","latest-issues":"Latest Issues","archives":"Archives","prev-issues":"Pervious issue","next-issues":"Next issue","publication_domain":"Publication Domain","publication_domain_popover":"Unless a custom domain has been set below your publication will be hosted on a curatedletters.co subdomain. This can be changed until you publish your first issue. If you've already published your first issue and would like to change this, please contact support@curatedletters.co.","archive_description":"Browse back issues of","brew_brand":"Brew Brand","topics":"Topics","podcasts":"Podcasts","games":"Games","events":"Events","courses":"Courses","shop":"Shop","refer-a-friend":"Refer a friend","sponsorship":"Sponsorship","sponsor-with-us":"Sponsor with us","my-subscription":"My Subscription","unsubscribe-modal":{"title":"Unsubscribe","description":"Are you sure you want to unsubscribe from this publication?","cancel":"Cancel","confirm":"Confirm","unsubscribe":"Unsubscribe"},"unsubscribed-successfully":"You have been unsubscribed successfully, We have sent you an email to confirm your unsubscription.","add-publication":"Add Publication","my-publications":"My Publications","archived-publications":"Archived Publications","edit-publication":"Edit","archive-publication":"Archive","un-archive-publication":"Unarchive","archive-publication-title":"Archive Publication","archive-publication-description":"Are you sure you want to archive this publication? This will remove it from the public directory and prevent new subscribers from signing up.","un-archive-publication-title":"Unarchive Publication","un-archive-publication-description":"Are you sure you want to unarchive this publication? This will make it available in the public directory and allow new subscribers to sign up.","cancel":"Cancel","settings":"Settings","no-publications":"You don't have any publications yet.","other-publications":"Other Publications","no-un-archived-publications":"You don't have any unarchived publications yet."},"home":{"title":"Your Best Newsletter Creator","description":"The easiest way to create a newsletter and deliver it to your followers.","join":"Join Now","benefit-1":{"title":"Step One","description":"Create your team."},"benefit-2":{"title":"Step Two","description":"Invite your team members."},"benefit-3":{"title":"Step Three","description":"See all team updates in one place, get daily emails to answer your questions."}}},"__N_SSP":true},"page":"/","query":{},"buildId":"M6y-RlZQD-9EPWE2883MC","isFallback":false,"gssp":true,"appGip":true,"locale":"en","locales":["en"],"defaultLocale":"en","scriptLoader":[]}</script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10