<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>André Cipriani Bandarra on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>André Cipriani Bandarra</name>
  </author>
  <link href="https://web.dev/authors/andreban/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/admin/XVGMhdOgHJhch3EBcw89.jpg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>Andre is a Developer Advocate</subtitle>
  
  
  <entry>
    <title>Deep dive into top web developer pain points</title>
    <link href="https://web.dev/deep-dive-into-developer-pain-points/"/>
    <updated>2022-04-25T00:00:00Z</updated>
    <id>https://web.dev/deep-dive-into-developer-pain-points/</id>
    <content type="html" mode="escaped">&lt;p&gt;A few months ago, &lt;a href=&quot;https://twitter.com/Paul_Kinlan&quot; rel=&quot;noopener&quot;&gt;Paul Kinlan&lt;/a&gt; posted about the &lt;a href=&quot;https://paul.kinlan.me/top-web-developer-pain-points-in-2021/&quot; rel=&quot;noopener&quot;&gt;top developer pain points in 2021&lt;/a&gt;, so it feels appropriate to start this article with an update on the last 2 quarters. The numbers have moved around a bit, but the ranking hasn&#39;t changed.&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Challenge&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Q1 2021&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Q2 2021&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Q3 2021&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Q4 2021&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;Keeping up with changes to the web platform or web standards.&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;27%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;26%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;27%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;22%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;Keeping up with a large number of new and existing tools or frameworks.&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;26%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;26%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;25%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;21%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;Making a design or experience work the same across browsers.&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;26%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;28%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;24%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;21%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;Testing across browsers.&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;23%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;24%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;20%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;20%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:center&quot;&gt;Understanding and implementing security measures.&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;23%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;25%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;20%&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;19%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;p&gt;As mentioned in Paul&#39;s blog post we need to address these pain points. As part of a larger effort to do so, my colleague &lt;a href=&quot;https://twitter.com/atopal&quot; rel=&quot;noopener&quot;&gt;Kadir Topal&lt;/a&gt; and I have interviewed over 18 developers. Our aim is to investigate and start making sense of the path to fixing top developer pain points.&lt;/p&gt;
&lt;h2 id=&quot;developer-discussions&quot;&gt;Developer Discussions &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/deep-dive-into-developer-pain-points/#developer-discussions&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; &lt;em&gt;those insights are based on a small number of conversations with developers. When using &amp;quot;all&amp;quot; or &amp;quot;some&amp;quot;, this refers to the developers interviewed, not the entire community. More research is needed to extrapolate those insights more widely.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;These conversations were a great reminder of how amazing and diverse the web developer community is, and I&#39;d like to thank all the developers who talked to us. Some developers had over 25 years of experience, while others started as recently as 2020. Some developers started their careers via a formal computer science degree, while others started their careers independently. Some developers actively seek what is new and keep up by reading browser release notes, while others learn about new things via colleagues and friends. Some think complexity is part of the job and enjoy being challenged, while others just want to get their job done. When thinking about solving those pain points, it&#39;s important to keep this diversity in our minds!&lt;/p&gt;
&lt;p&gt;One of the common things amongst all developers is that all of them are using a CMS or a framework to do their work. Wordpress, React, Bootstrap, Angular, and Tailwind were all mentioned, none of the developers were using the vanilla web platform in production. Choosing a framework when starting a project is a challenge, and developers frequently take into account non-technical requirements. For example, whether it will be easy to hire a developer to work with that framework. We cannot improve developer pain points if frameworks and CMSs are not included in the solution.&lt;/p&gt;
&lt;p&gt;Speaking of the web platform, most developers understand the platform as the thing they are developing on top of. This includes not only the &lt;a href=&quot;https://en.wikipedia.org/wiki/Web_platform&quot; rel=&quot;noopener&quot;&gt;classical definition&lt;/a&gt; of the web platform, but also the CMSs, framework, tools, and polyfills. In many cases, keeping up to date with those is where the biggest difficulties are. This changed our interpretation of that question, and we now know we need to update our survey to break it down into different parts that are less ambiguous.&lt;/p&gt;
&lt;p&gt;Another area of ambiguity is the definition of &lt;a href=&quot;https://www.w3.org/standards/&quot; rel=&quot;noopener&quot;&gt;web standards&lt;/a&gt;. When asked about examples around keeping up with standards, many developers pointed out difficulties with keeping up with best practices instead. This is another area we need to clarify on the survey.&lt;/p&gt;
&lt;p&gt;Developers look for best practices when implementing specific use-cases and patterns. Blog posts and StackOverflow are mentioned as sources for best practices, but developers often wonder if the information they are reading is indeed the best practice and if it is up to date with the latest features and APIs. They would like a more official source to read those.&lt;/p&gt;
&lt;p&gt;Keeping up with features and APIs that enable new use-cases is a smaller problem. Developers struggle more with features, APIs, and changes to the platform that result in a change in best practices.&lt;/p&gt;
&lt;p&gt;Most developers agree that compatibility is one of the biggest challenges. Things are improving via efforts like &lt;a href=&quot;https://web.dev/compat2021/&quot;&gt;Compat 2021&lt;/a&gt; and &lt;a href=&quot;https://web.dev/interop-2022/&quot;&gt;Interop 2022&lt;/a&gt;, but it&#39;s clear that developers don&#39;t see it as a solved problem yet.&lt;/p&gt;
&lt;p&gt;Most developers use polyfills in one way or another. In many cases, however, usage is transparent to developers, since the polyfill can be automatically added by a tool like Babel or a framework. For those who are managing their polyfills themselves, figuring out if a polyfill is &amp;quot;good&amp;quot; can be a problem. Developers mentioned using the number of installs on NPM and the creator of the polyfill as signals. A couple of developers mentioned doing work to remove polyfills that became unnecessary due to dropping support for IE 11.&lt;/p&gt;
&lt;p&gt;Frameworks introduce fragmentation issues. We heard reports where developers were &amp;quot;stuck&amp;quot; into an older version of a framework, and limited on the features they could use because of that, but that migrating to a newer version of the same framework could be costly and hard to justify.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/deep-dive-into-developer-pain-points/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Modern web development has many moving pieces including, standards, browsers, libraries, polyfills, CMSs, frameworks, best practices, and tooling. This diversity is one of the great things about the web but, right now, it&#39;s up to each developer individually to make sense of each piece and how they are compatible with each other.&lt;/p&gt;
&lt;p&gt;I wonder if there&#39;s a way to bring more clarity to developers on how everything ties together and more alignment between all the pieces, without compromising on the diversity. It&#39;s a large, complex problem, and hard to do all at once. But where to even start?&lt;/p&gt;
&lt;p&gt;If you have views and opinions you&#39;d like to share. I&#39;d love to talk to you too. I&#39;ll set up a way for booking conversations directly but, in the meantime, my DMs are open &lt;a href=&quot;https://twitter.com/andreban&quot; rel=&quot;noopener&quot;&gt;on Twitter&lt;/a&gt;. Reach out and we can grab the time to chat!&lt;/p&gt;
</content>
    <author>
      <name>André Cipriani Bandarra</name>
    </author>
  </entry>
  
  <entry>
    <title>How Terra improved user engagement thanks to Dark Mode</title>
    <link href="https://web.dev/terra-dark-mode/"/>
    <updated>2021-12-18T00:00:00Z</updated>
    <id>https://web.dev/terra-dark-mode/</id>
    <content type="html" mode="escaped">&lt;p&gt;Terra, one of Brazil&#39;s largest media companies with 75 million monthly users, reduced the bounce rate by 60% and increased the pages read per session by 170% on desktop for users that prefer dark mode by providing a custom dark theme.&lt;/p&gt;
&lt;p&gt;In this article, we&#39;ll analyze Terra&#39;s journey from identifying the size of the &amp;quot;dark mode&amp;quot; cohort, to applying a custom dark theme, and finally measuring the impact of this implementation on their main KPIs.&lt;/p&gt;
&lt;ul class=&quot;stats&quot;&gt;
  &lt;div class=&quot;stats__item&quot;&gt;
    &lt;p class=&quot;stats__figure&quot;&gt;60&lt;sub&gt;%&lt;/sub&gt;&lt;/p&gt;
    &lt;p&gt;Reduction in Bounce Rates&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;stats__item&quot;&gt;
    &lt;p class=&quot;stats__figure&quot;&gt;170&lt;sub&gt;%&lt;/sub&gt;&lt;/p&gt;
    &lt;p&gt;More pages per session&lt;/p&gt;
  &lt;/div&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-is-dark-mode&quot;&gt;What is dark mode? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#what-is-dark-mode&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Historically user interfaces in devices are displayed in &amp;quot;light mode&amp;quot;, which usually means displaying black text on top of light interfaces. The alternative is &amp;quot;dark mode&amp;quot;, with light text on a dark background, such as gray or black.&lt;/p&gt;
&lt;p&gt;Dark Mode has &lt;a href=&quot;https://web.dev/prefers-color-scheme/#why-dark-mode&quot;&gt;benefits&lt;/a&gt; for user experience. Some people prefer it for aesthetic or accessibility reasons. It has  other advantages, such as preserving battery life in devices. Users can express that they prefer dark mode via a setting in their devices, &lt;a href=&quot;https://web.dev/prefers-color-scheme/#activating-dark-mode-in-the-operating-system&quot;&gt;which depends on the operating system&lt;/a&gt;. For example, the following screenshot shows what the &lt;strong&gt;Dark Theme&lt;/strong&gt; configuration option looks like in devices that run &lt;strong&gt;Android Q&lt;/strong&gt;:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Android Q dark mode settings.&quot; decoding=&quot;async&quot; height=&quot;250&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 218px) 218px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/Yh6SEoWDK1SbqcGjlL6d.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/Yh6SEoWDK1SbqcGjlL6d.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/Yh6SEoWDK1SbqcGjlL6d.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/Yh6SEoWDK1SbqcGjlL6d.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/Yh6SEoWDK1SbqcGjlL6d.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/Yh6SEoWDK1SbqcGjlL6d.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/Yh6SEoWDK1SbqcGjlL6d.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/Yh6SEoWDK1SbqcGjlL6d.png?auto=format&amp;w=436 436w&quot; style=&quot;max-width: 218px; margin: 0 auto;&quot; width=&quot;218&quot; /&gt;
  &lt;figcaption&gt;Android&amp;nbsp;Q dark theme settings.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To offer a better experience to users who prefer &amp;quot;dark mode&amp;quot;, you can use the &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/@media/prefers-color-scheme&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;prefers-color-scheme&lt;/code&gt;&lt;/a&gt; media query, with a value of &lt;code&gt;light&lt;/code&gt; or &lt;code&gt;dark&lt;/code&gt;. This media query reflects the user&#39;s choice in their device. You can then load a &lt;a href=&quot;https://web.dev/prefers-color-scheme/#dark-mode-in-practice&quot;&gt;custom dark theme&lt;/a&gt; for those that prefer dark. For example, by loading a &amp;quot;dark&amp;quot; CSS file, and changing values such as font and background colors. The following code shows an example of that:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;prefers-color-scheme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; dark&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;   // apply a dark theme&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;prefers-color-scheme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; light&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  // apply a light theme&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 76, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      76
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 67, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      67
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 79, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      79
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 12.1, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12.1
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/CSS/@media/prefers-color-scheme#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; This article will only cover the technique of applying a custom dark theme, provided by the developer. Chrome 96 has introduced an &lt;a href=&quot;https://developer.chrome.com/blog/auto-dark-theme/#sign-up-for-the-origin-trial&quot;&gt;origin trial&lt;/a&gt; for &amp;quot;Auto Dark Themes&amp;quot; on Android, for which the browser applies an automatically generated dark theme to light themed sites, when the user has opted into dark themes in the operating system, without requiring the developer to provide styles for it. For more information about &amp;quot;Chrome Auto Dark Mode&amp;quot;, check out &lt;a href=&quot;https://developer.chrome.com/blog/auto-dark-theme/&quot;&gt;this article&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;identifying-the-prefers-light-vs-dark-user-cohorts&quot;&gt;Identifying the &amp;quot;prefers light&amp;quot; vs &amp;quot;dark&amp;quot; user cohorts &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#identifying-the-prefers-light-vs-dark-user-cohorts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At the time of writing (December 2021), &lt;a href=&quot;https://chromestatus.com/features&quot; rel=&quot;noopener&quot;&gt;Chrome Platform Status&lt;/a&gt; determines that approximately &lt;a href=&quot;https://chromestatus.com/metrics/feature/timeline/popularity/3581&quot; rel=&quot;noopener&quot;&gt;22% of the web traffic&lt;/a&gt; comes from users with the &amp;quot;prefer dark&amp;quot; setting.&lt;/p&gt;
&lt;p&gt;This is aggregated data, so the real percentage of users who prefer dark that come to a site can vary. For that reason, to understand the size of this group it is advisable to run in house measurement.&lt;/p&gt;
&lt;p&gt;The following code creates an analytics dimension, to measure the performance of users that prefer &lt;code&gt;light&lt;/code&gt; vs. &lt;code&gt;dark&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getColorScheme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; colorScheme &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Unknown&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;matchMedia&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;matchMedia&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;(prefers-color-scheme: dark)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;matches&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            colorScheme &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Dark&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;matchMedia&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;(prefers-color-scheme: light)&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;matches&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            colorScheme &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Light&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; colorScheme&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ga&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ga&lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ga&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;q&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;ga&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;q&lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;ga&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;l&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ga&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;create&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;UA-ID&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;auto&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;ga&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;set&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;color-scheme-preference&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getColorScheme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;ga&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;send&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;pageview&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Terra implemented this code in their site and compared the behavior of both groups in mobile (Android) and desktop (Windows) devices. At that moment Terra wasn&#39;t providing a custom dark theme, so the goals of this experiment were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Determining the size of the group of users who prefer dark.&lt;/li&gt;
&lt;li&gt;Identifying patterns: for example, do users that prefer dark leave the site more quickly compared to those that prefer light?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Knowing this can inform decisions, for example: if it&#39;s necessary to provide a custom dark theme.
These are the results Terra obtained after testing for 14 days:&lt;/p&gt;
&lt;h3 id=&quot;mobile-android&quot;&gt;Mobile (Android) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#mobile-android&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the case of mobile (Android) the numbers for bounce rate and pages per session didn&#39;t show big differences between the users that prefer &amp;quot;light&amp;quot;, compared to those that prefer &amp;quot;dark&amp;quot;:&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Display Mode&lt;/th&gt;
        &lt;th&gt;Bounce Rate&lt;/th&gt;
        &lt;th&gt;Pages Per Session&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Prefers Light&lt;/td&gt;
        &lt;td&gt;25.84%&lt;/td&gt;
        &lt;td&gt;3.96&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Prefers Dark&lt;/td&gt;
        &lt;td&gt;26.10%&lt;/td&gt;
        &lt;td&gt;3.75&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;desktop-windows&quot;&gt;Desktop (Windows) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#desktop-windows&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the case of desktop (Windows), the group of users that preferred &amp;quot;dark&amp;quot; stayed much less on the site: they had almost &lt;strong&gt;twice the bounce rate and read a little more than half of the pages&lt;/strong&gt; than those users that preferred &amp;quot;light&amp;quot;:&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Display Mode&lt;/th&gt;
        &lt;th&gt;Bounce Rate&lt;/th&gt;
        &lt;th&gt;Pages Per Session&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Prefers Light&lt;/td&gt;
        &lt;td&gt;13.20%&lt;/td&gt;
        &lt;td&gt;7.42&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Prefers Dark&lt;/td&gt;
        &lt;td&gt;24.12%&lt;/td&gt;
        &lt;td&gt;4.68&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Based on this data, Terra hypothesized that users who prefer &amp;quot;dark&amp;quot; stay less in desktop devices, due to the lack of support of a dark theme in their site.&lt;/p&gt;
&lt;p&gt;As a next step Terra decided to work on a &amp;quot;dark theme&amp;quot; strategy to see if they could improve the engagement for the group of users that preferred dark.&lt;/p&gt;
&lt;h2 id=&quot;implementing-a-dark-theme&quot;&gt;Implementing a dark theme &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#implementing-a-dark-theme&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most websites implement a dark theme by using the simple strategy shown previously of listening to user&#39;s configuration changes via the &lt;a href=&quot;https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;prefers-color-scheme&lt;/code&gt;&lt;/a&gt; media query and changing styles based on that.&lt;/p&gt;
&lt;p&gt;Terra decided to give more control to the user: when they detect that they have the &amp;quot;prefer dark&amp;quot; setting turned on in their devices (via the media query), they show them a prompt to ask them if they want to navigate in &amp;quot;night mode&amp;quot;. As long as the user doesn&#39;t deny the prompt (by clicking on the &amp;quot;Ignore&amp;quot; button), they honor the user&#39;s OS-setting, and apply a custom dark theme:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Screenshot of Terra&amp;#x27;s light theme prompting the user to accept dark mode.&quot; decoding=&quot;async&quot; height=&quot;146&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 266px) 266px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/TRqfCAmBe025456JyX1b.png?auto=format&amp;w=532 532w&quot; style=&quot;max-width: 266px; margin: 0 auto;&quot; width=&quot;266&quot; /&gt;
  &lt;figcaption&gt;Terra shows a prompt to the user asking if they want to navigate in dark mode after detecting that they prefer dark in their devices.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As a complement of this strategy they provide additional configuration options in the &amp;quot;settings&amp;quot; screen, where the user can decide if they explicitly prefer &amp;quot;light&amp;quot;, &amp;quot;dark&amp;quot;, or want to rely on the underlying device settings.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Screenshots of Terra&amp;#x27;s configuration screen to opt in and out of dark mode.&quot; decoding=&quot;async&quot; height=&quot;417&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 480px) 480px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/B7g0uvq2QB0eWVjnuMAl.png?auto=format&amp;w=960 960w&quot; style=&quot;max-width: 480px; margin: 0 auto;&quot; width=&quot;480&quot; /&gt;
  &lt;figcaption&gt;Terra&#39;s themes configurations allow users to choose between &quot;Dark&quot; and &quot;Light&quot; themes or rely on the device&#39;s settings.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This is how Terra&#39;s &amp;quot;Night Mode&amp;quot; looks like:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Screenshot of Terra&amp;#x27;s dark theme.&quot; decoding=&quot;async&quot; height=&quot;468&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 286px) 286px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/26V1DWN36MZr3mUo8ChSBlCpzp43/QRW06FYeMghUI8obAQWC.png?auto=format&amp;w=572 572w&quot; style=&quot;max-width: 286px; margin: 0 auto;&quot; width=&quot;286&quot; /&gt;
  &lt;figcaption&gt;Terra&#39;s dark theme, &quot;Night Mode&quot;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; We have used mobile screenshots for simplicity, but Terra has applied the same strategy across mobile and desktop devices. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;measuring-the-impact-of-terras-dark-theme&quot;&gt;Measuring the impact of Terra&#39;s dark theme &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#measuring-the-impact-of-terras-dark-theme&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To measure the impact of the dark theme, Terra took the group of users that have the &amp;quot;Prefer Dark&amp;quot; setting turned on in their devices and compared engagement metrics when showing a &amp;quot;Light&amp;quot; vs. a &amp;quot;DarK&amp;quot; theme.
Here are the results for mobile (Android) and desktop (Windows):&lt;/p&gt;
&lt;h3 id=&quot;mobile-android-2&quot;&gt;Mobile (Android) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#mobile-android-2&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While bounce rates remained similar, pages and sessions almost doubled (from 2.47 to 5.24) when users were exposed to a dark theme:&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Display Mode&lt;/th&gt;
        &lt;th&gt;Bounce Rate&lt;/th&gt;
        &lt;th&gt;Pages Per Session&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Prefers Light&lt;/td&gt;
        &lt;td&gt;26.91%&lt;/td&gt;
        &lt;td&gt;2.47&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Prefers Dark&lt;/td&gt;
        &lt;td&gt;23.91%&lt;/td&gt;
        &lt;td&gt;5.24&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/div&gt;
&lt;ul class=&quot;stats&quot;&gt;
  &lt;div class=&quot;stats__item&quot;&gt;
    &lt;p class=&quot;stats__figure&quot;&gt;2&lt;sub&gt;X&lt;/sub&gt;&lt;/p&gt;
    &lt;p&gt;More pages per session&lt;/p&gt;
  &lt;/div&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;desktop-windows-2&quot;&gt;Desktop (Windows) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#desktop-windows-2&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Both metrics improved when showing a dark theme: bounce rates went from 27.25% to 10.82% and pages per session almost tripled (from 3.7 to 9.99).&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Display Mode&lt;/th&gt;
        &lt;th&gt;Bounce Rate&lt;/th&gt;
        &lt;th&gt;Pages Per Session&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Prefers Light&lt;/td&gt;
        &lt;td&gt;27.5%&lt;/td&gt;
        &lt;td&gt;3.7&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Prefers Dark&lt;/td&gt;
        &lt;td&gt;10.82%&lt;/td&gt;
        &lt;td&gt;9.99&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/div&gt;
&lt;ul class=&quot;stats&quot;&gt;
  &lt;div class=&quot;stats__item&quot;&gt;
    &lt;p class=&quot;stats__figure&quot;&gt;60&lt;sub&gt;%&lt;/sub&gt;&lt;/p&gt;
    &lt;p&gt;Reduction in Bounce Rates&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;stats__item&quot;&gt;
    &lt;p class=&quot;stats__figure&quot;&gt;170&lt;sub&gt;%&lt;/sub&gt;&lt;/p&gt;
    &lt;p&gt;More pages per session&lt;/p&gt;
  &lt;/div&gt;
&lt;/ul&gt;
&lt;p&gt;Based on this data, Terra could confirm the benefits for the users from implementing a dark theme, and has decided to continue maintaining it as a core feature of the site.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/terra-dark-mode/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dark Mode is a preference that users can turn on in their devices  to change the style of the screens into dark themes. This technique has reported benefits from the user experience and for different aspects of the user&#39;s devices such as saving  battery life.&lt;/p&gt;
&lt;p&gt;In this article we saw how providing a custom dark theme improved engagement metrics for the group of Terra&#39;s users that have the preferred dark mode setting turned on in their devices.&lt;/p&gt;
&lt;p&gt;For companies with the resources to implement an alternative dark theme this is the recommended approach. For those that don&#39;t have the time to invest in such a feature, Chrome is starting to roll out an &lt;a href=&quot;https://developer.chrome.com/blog/auto-dark-theme/&quot; rel=&quot;noopener&quot;&gt;Auto Dark Mode feature&lt;/a&gt;.&lt;/p&gt;
</content>
    <author>
      <name>Demian Renzulli</name>
    </author><author>
      <name>André Cipriani Bandarra</name>
    </author><author>
      <name>Guilherme Moser de Souza</name>
    </author>
  </entry>
  
  <entry>
    <title>Web on Android</title>
    <link href="https://web.dev/web-on-android/"/>
    <updated>2020-07-30T00:00:00Z</updated>
    <id>https://web.dev/web-on-android/</id>
    <content type="html" mode="escaped">&lt;p&gt;The Android platform has been around for more than ten years, and since its early days it has had
great support for the Web. It shipped with WebView, a component that allows developers to use the
web inside their own Android Apps. More than that, Android allows developers to bring their own
browser engine into the platform, fostering competition and innovation.&lt;/p&gt;
&lt;p&gt;Developers can include the web in their Android applications in many ways. WebView is frequently
used to render ads, as a layout component used along with Android UI elements, or for packaging HTML 5
games. Custom Tabs allows developers to build in-app browsers and provide a seamless navigation
experience to third-party web content, and Trusted Web Activity allows developers to use their
Progressive Web Apps (PWAs) in Android apps, which can be downloaded from the Play Store.&lt;/p&gt;
&lt;h3 id=&quot;android-webview&quot;&gt;Android WebView &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#android-webview&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;WebView gives developers access to modern HTML, CSS, and JavaScript inside their Android apps, and
allows content to be shipped inside the APK or hosted on the internet. It&#39;s one of Android&#39;s most
flexible and powerful components, which can be used for most of the use-cases where web content is
included in an Android app. From powering ad services like AdMob to building and shipping complete
HTML5 games that use modern APIs such as WebGL.&lt;/p&gt;
&lt;p&gt;But, when used to create an in-app-browser or including a PWA in an Android application, WebView
lacks the security, features, and capabilities of the web platform.&lt;/p&gt;
&lt;h3 id=&quot;the-in-app-browser-challenge&quot;&gt;The in-app browser challenge &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#the-in-app-browser-challenge&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Over time, more and more developers have built browser experiences
incorporating third-party content into their Android application, with the goal
of creating a more seamless experience for their users when navigating to
third-party websites. Those experiences became known
as in-app browsers.&lt;/p&gt;
&lt;p&gt;WebView has extensive support for the modern web tech stack and supports many modern web APIs, like
WebGL. But WebView is primarily a web UI toolkit. It
&lt;a href=&quot;https://research.google/pubs/pub46739/&quot; rel=&quot;noopener&quot;&gt;is not meant to - and does not - support all features of the web platform&lt;/a&gt;. When an API already
has an OS-level alternative, like Web Bluetooth, or it requires browser UI to be implemented, like
push notifications, it may not be supported. As the web platform evolves and adds more features
that were only available to Android apps, this gap will become even larger. As app developers don&#39;t
control which features are used when opening third-party content, it makes WebView a poor choice
for in-app browsers or opening Progressive Web Apps. Even if WebView implemented support for all
web platform features, developers would still need to write code and implement their own UI for
functionality like permissions or push notifications, making it hard to achieve consistency for
users.&lt;/p&gt;
&lt;h4 id=&quot;security-considerations-for-using-webview-as-an-in-app-browser&quot;&gt;Security Considerations for using WebView as an in-app browser &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#security-considerations-for-using-webview-as-an-in-app-browser&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;WebView gives the embedder application full access to the rendered content, including cookies and
the DOM. Those are powerful features that require a high level of trust from users.&lt;/p&gt;
&lt;p&gt;Since WebView is not intended as a framework for building browsers, it lacks security features
available in modern browsers.&lt;/p&gt;
&lt;h5 id=&quot;multi-process-architecture-and-site-isolation&quot;&gt;Multi-process architecture and site isolation &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#multi-process-architecture-and-site-isolation&quot;&gt;#&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;Browsers are designed to be secure while rendering and executing content that is untrusted. To
ensure the user stays safe while navigating content that is potentially untrustworthy or even
malicious, modern browsers employ techniques such as using &lt;a href=&quot;https://blog.chromium.org/2008/09/multi-process-architecture.html&quot; rel=&quot;noopener&quot;&gt;multi-process architecture&lt;/a&gt; and
&lt;a href=&quot;https://www.chromium.org/Home/chromium-security/site-isolation&quot; rel=&quot;noopener&quot;&gt;site isolation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Without the multi-process architecture, a crash caused by the web page can crash the entire browser app, or
a vulnerability can be exploited to take control of the entire device. Site isolation adds another
layer of security that makes it harder for untrustworthy sites to access and steal information from
other sites.&lt;/p&gt;
&lt;p&gt;Until Android 8.0 Oreo, the WebView renderer used the same process as the embedder application. On
newer versions of the OS, and when devices are capable enough, the renderer runs in a different
process. However, a single process is still shared between all pages and WebView instances running
them, making it impossible to fully implement site isolation.&lt;/p&gt;
&lt;p&gt;The lack of a multi-process architecture and site isolation is not an issue for applications that
render content that they own and trust, but can be a problem for applications running untrusted
third-party content, like in-app browsers, and leaves users exposed to vulnerabilities like
&lt;a href=&quot;https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)&quot; rel=&quot;noopener&quot;&gt;Meltdown&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&quot; rel=&quot;noopener&quot;&gt;Spectre&lt;/a&gt;, which could be used for stealing cookies, banking details,
personal information, and more.&lt;/p&gt;
&lt;h5 id=&quot;secure-ui-indicators&quot;&gt;Secure UI Indicators &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#secure-ui-indicators&quot;&gt;#&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;It is also important to provide good security indicators to users, and browsers put a lot of effort
and are &lt;a href=&quot;https://blog.chromium.org/2018/05/evolving-chromes-security-indicators.html&quot; rel=&quot;noopener&quot;&gt;always evolving&lt;/a&gt; in this area. However, the WebView lacks an API for checking if a
site&#39;s connection is secure that allows application developers to build trustworthy security
indicators. The lack of such an API could cause, for instance, a URL displayed in the address bar to
not match the page displayed to the user, even over secure HTTPS connections.&lt;/p&gt;
&lt;p&gt;Another option available to developers is embedding a browser engine in their application. Besides
leading to increased application size, this approach is both complex and time-consuming.&lt;/p&gt;
&lt;h3 id=&quot;custom-tabs-as-a-solution-for-in-app-browsers&quot;&gt;Custom Tabs as a solution for in-app browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#custom-tabs-as-a-solution-for-in-app-browsers&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Custom Tabs was &lt;a href=&quot;https://android-developers.googleblog.com/2015/09/chrome-custom-tabs-smooth-transition.html&quot; rel=&quot;noopener&quot;&gt;introduced in Chrome 45&lt;/a&gt; and allows developers to use a tab from the user&#39;s
default browser as part of their application. Custom Tabs was originally launched by Chrome, and
was therefore known as &amp;quot;Chrome Custom Tabs&amp;quot;. Today it&#39;s an &lt;a href=&quot;https://developer.android.com/reference/androidx/browser/customtabs/package-summary&quot; rel=&quot;noopener&quot;&gt;Android API&lt;/a&gt; and most popular
browsers support Custom Tabs, including Chrome, Firefox, Edge, and Samsung Internet, so it&#39;s more
appropriate to just call it &amp;quot;Custom Tabs&amp;quot;.&lt;/p&gt;
&lt;p&gt;Custom Tabs helps developers seamlessly integrate web content into their app experience. They also
allow developers to customise the activity in which web content is shown by allowing them to
customize the toolbar color, action buttons, transition animation, and more.&lt;/p&gt;
&lt;p&gt;They also offer features that were previously unavailable when using WebView or embedding a browser
engine. Since the in-app browser is powered by the user&#39;s browser, Custom Tabs shares storage
with the browser, so users don&#39;t need to re-login to their favourite websites every time one of
their installed apps starts an In-App browsing session.&lt;/p&gt;
&lt;p&gt;Unlike WebViews, Custom Tabs supports all web platform features and APIs that are supported by the
browser powering it.&lt;/p&gt;
&lt;h3 id=&quot;open-progressive-web-apps-using-trusted-web-activity&quot;&gt;Open Progressive Web Apps using Trusted Web Activity &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#open-progressive-web-apps-using-trusted-web-activity&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://web.dev/progressive-web-apps/&quot;&gt;Progressive Web Apps&lt;/a&gt; bring many behaviors and capabilities that were once only available to
platform-specific apps to the web. With the introduction of app-like behaviour, the desire from developers to
re-use those experiences on Android increased, and developers started asking for ways to integrate
PWAs into their apps.&lt;/p&gt;
&lt;p&gt;Custom Tabs has support for all modern web capabilities and APIs but, since it was primarily
designed to open third-party content, it has a toolbar on the top that tells the users which URL
they are visiting, as well as the lock icon indicating whether the site is secure. When opening an app&#39;s
own experience, the toolbar prevents the application from feeling like it is integrated with the
operating system.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.chrome.com/docs/android/trusted-web-activity/&quot; rel=&quot;noopener&quot;&gt;Trusted Web Activities&lt;/a&gt; was introduced in Chrome 72 and allows developers to
&lt;a href=&quot;https://web.dev/using-a-pwa-in-your-android-app/&quot;&gt;use their PWA inside an Android&lt;/a&gt; app. Its protocol is similar to the Custom Tabs protocol,
but introduces APIs that allow developers to verify (through &lt;a href=&quot;https://developers.google.com/digital-asset-links&quot; rel=&quot;noopener&quot;&gt;Digital Asset Links&lt;/a&gt;) that they
control both the Android app and the URL being opened and remove the URL bar when both are true.&lt;/p&gt;
&lt;p&gt;They also introduced APIs for creating splash screens when opening the PWA or delegating web
notifications to be handled by Android code. More features like support for Play Billing are coming
soon.&lt;/p&gt;
&lt;p&gt;Since URLs opened in Trusted Web Activities are expected to be PWAs and have a set of behaviors and
performance characteristics, Trusted Web Activities introduces &lt;a href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#quality-criteria&quot;&gt;quality criteria&lt;/a&gt; for PWAs
being opened inside it.&lt;/p&gt;
&lt;h3 id=&quot;limitations-of-the-current-solutions&quot;&gt;Limitations of the current solutions &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#limitations-of-the-current-solutions&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Developer feedback showed a need for the platform compatibility of Custom Tabs combined with the
flexibility of WebView so they could, for instance, access the DOM or inject JavaScript, into their
in-app browsers.&lt;/p&gt;
&lt;p&gt;Custom Tabs is effectively a tab rendered by the user&#39;s browser, with a custom UI or with no UI
at all. This means that the browser needs to honour the user&#39;s expectations around privacy and
security towards the browser, making some of those features impossible.&lt;/p&gt;
&lt;p&gt;The Web on Android team at Google is looking into alternatives and experimenting with solutions
to solve those use-cases. Stay tuned for details!&lt;/p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/web-on-android/#summary&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;WebView is useful when an application needs HTML, CSS, and JavaScript inside their Android app, but
doesn&#39;t use more advanced features and capabilities available on the modern web such as Push
Notifications, Web Bluetooth and others. It is not recommended when opening content that has been
designed for the modern web platform, as it may not be displayed in the way the developer intended.
WebView is not recommended for creating in-app browsers. On the other hand displaying first-party
web content is an area where WebViews really shine.&lt;/p&gt;
&lt;p&gt;Trusted Web Activity should be used when the developers want to render their own Progressive Web
App in fullscreen inside their Android application. It can be used as the only activity in the app
or used along with other Android activities.&lt;/p&gt;
&lt;p&gt;Custom Tabs is the recommended way for opening third-party content that is designed for the web
platform, also known as in-app browsers.&lt;/p&gt;
</content>
    <author>
      <name>André Cipriani Bandarra</name>
    </author>
  </entry>
  
  <entry>
    <title>Using a PWA in your Android app</title>
    <link href="https://web.dev/using-a-pwa-in-your-android-app/"/>
    <updated>2020-03-19T00:00:00Z</updated>
    <id>https://web.dev/using-a-pwa-in-your-android-app/</id>
    <content type="html" mode="escaped">&lt;h2 id=&quot;start-a-pwa-in-an-android-app&quot;&gt;Start a PWA in an Android app &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#start-a-pwa-in-an-android-app&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://web.dev/progressive-web-apps/&quot;&gt;Progressive Web Apps&lt;/a&gt; (PWA) are web applications that use app-like features to create
high quality experiences that are fast, reliable, and engaging.&lt;/p&gt;
&lt;p&gt;The web has incredible reach and offers powerful ways for users to discover new experiences. But
users are also used to searching for applications in their operating system store. Those users are,
in many cases, already familiar with the brand or service they&#39;re seeking and have a high level of intentionality
that results in higher than average engagement metrics.&lt;/p&gt;
&lt;p&gt;The Play Store is a store for Android apps, and developers often want to open their Progressive Web
Apps from their Android apps.&lt;/p&gt;
&lt;p&gt;Trusted Web Activity is an open standard that allows browsers to provide a fully web platform
compatible container that renders PWAs inside an Android app. The feature
is available in &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.android.chrome&quot; rel=&quot;noopener&quot;&gt;Chrome&lt;/a&gt;, and in development in &lt;a href=&quot;https://play.google.com/store/apps/details?id=org.mozilla.fenix&quot; rel=&quot;noopener&quot;&gt;Firefox Nightly&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;existing-solutions-were-limited&quot;&gt;Existing solutions were limited &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#existing-solutions-were-limited&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It has always been possible to include web experiences in an Android app, using technologies like
the &lt;a href=&quot;https://developer.android.com/reference/android/webkit/WebView&quot; rel=&quot;noopener&quot;&gt;Android WebView&lt;/a&gt; or frameworks like &lt;a href=&quot;https://cordova.apache.org/&quot; rel=&quot;noopener&quot;&gt;Cordova&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The limitation with Android WebView is that it&#39;s not intended as a browser replacement. The Android
WebView is a developer tool for using web UI in an Android app and it doesn&#39;t provide complete
access to modern web platform features such as &lt;a href=&quot;https://web.dev/contact-picker/&quot;&gt;contact picker&lt;/a&gt;, or &lt;a href=&quot;https://web.dev/file-system-access/&quot;&gt;filesystem&lt;/a&gt;,
&lt;a href=&quot;https://web.dev/fugu-status/&quot;&gt;among others&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cordova was designed to augment the shortcomings of WebView, but the APIs are then limited to the
Cordova environment.  That means you need to maintain an additional codebase for using Cordova APIs
for your Android app, separate from your PWA on the open web.&lt;/p&gt;
&lt;p&gt;In addition, feature discoverability often doesn&#39;t always work as expected and compatibility issues
between Android versions and OEMs can also be a problem. When using one of those solutions,
developers need additional quality assurance processes and incur an extra development cost to
detect and create workarounds.&lt;/p&gt;
&lt;h3 id=&quot;trusted-web-activity-is-a-new-container-for-web-apps-on-android&quot;&gt;Trusted Web Activity is a new container for Web apps on Android &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#trusted-web-activity-is-a-new-container-for-web-apps-on-android&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Developers can now use a &lt;a href=&quot;https://developers.google.com/web/updates/2019/02/using-twa&quot; rel=&quot;noopener&quot;&gt;Trusted Web Activity&lt;/a&gt; as a container to include a PWA as a launch
activity for an Android app. The technology leverages the browser to render the PWA in full screen,
ensuring the Trusted Web Activity has the same compatibility with the Web Platform features and
APIs that the underlying browser does. There are also open source utilities to make implementing
an Android app using a Trusted Web Activity even easier.&lt;/p&gt;
&lt;p&gt;Another advantage not available in other solutions is that the container shares storage with the
browser. Login states and users preferences are shared seamlessly across experiences.&lt;/p&gt;
&lt;h4 id=&quot;browser-compatibility&quot;&gt;Browser Compatibility &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#browser-compatibility&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The feature has been available in Chrome since version 75, with Firefox implementing it in their
nightly version.&lt;/p&gt;
&lt;h3 id=&quot;quality-criteria&quot;&gt;Quality Criteria &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#quality-criteria&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Web developers should use a Trusted Web Activity when they want to include web content in an
Android app.&lt;/p&gt;
&lt;p&gt;Web content in a Trusted Web Activity must meet the PWA installability criteria.&lt;/p&gt;
&lt;p&gt;Additionally, to match the behavior users expect from Android applications,
&lt;a href=&quot;https://blog.chromium.org/2020/06/changes-to-quality-criteria-for-pwas.html&quot; rel=&quot;noopener&quot;&gt;Chrome 86 introduced a change&lt;/a&gt; where failing to handle the following scenarios is considered a
crash:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Failure to verify digital asset links at application launch.&lt;/li&gt;
&lt;li&gt;Failure to return HTTP 200 for an offline network resource request.&lt;/li&gt;
&lt;li&gt;A navigation request returning an HTTP 404 or 5xx error&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When one of those scenarios happens in the Trusted Web Activity, it causes a user visible
crash of the Android application. Check out the &lt;a href=&quot;https://developer.chrome.com/docs/android/trusted-web-activity/whats-new/#updates-to-the-quality-criteria&quot; rel=&quot;noopener&quot;&gt;guidance&lt;/a&gt; on handling those scenarios in your
service worker.&lt;/p&gt;
&lt;p&gt;The application must also meet additional Android-specific criteria such as &lt;a href=&quot;https://play.google.com/about/developer-content-policy/&quot; rel=&quot;noopener&quot;&gt;policy compliance&lt;/a&gt;.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-bad-bg color-state-bad-text&quot;&gt;&lt;p class=&quot;cluster color-state-bad-text&quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Error sign&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Caution&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; When your app is designed primarily for children under 13, additional &lt;a href=&quot;https://play.google.com/about/families/&quot;&gt;Play Family policies&lt;/a&gt; apply, which may be incompatible with using Trusted Web Activity. &lt;/div&gt;&lt;/aside&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A screenshot showing the Lighthouse score for AirHorn, with the PWA badge and a performance score of 100.&quot; decoding=&quot;async&quot; height=&quot;141&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/9Z70W3aCI8ropKpMXHcz.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;
    The PWA badge in Lighthouse shows if your PWA passes the installability criteria.
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;tooling&quot;&gt;Tooling &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#tooling&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Web developers who want to take advantage of Trusted Web Activity don&#39;t need to learn new
technologies or APIs to transform their PWA into an Android Application. Together, Bubblewrap and
PWABuilder provide developer tooling in the form of a library, Command Line Interface (CLI) and
Graphical User Interface (GUI).&lt;/p&gt;
&lt;h3 id=&quot;bubblewrap&quot;&gt;Bubblewrap &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#bubblewrap&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/GoogleChromeLabs/bubblewrap&quot; rel=&quot;noopener&quot;&gt;Bubblewrap&lt;/a&gt; project generates Android apps in the form of a NodeJS
library and a Command Line Interface (CLI).&lt;/p&gt;
&lt;p&gt;Bootstrapping a new project is achieved by running the tool and passing the URL of the Web
Manifest:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;npx @bubblewrap/cli init --manifest&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;https://pwa-directory.appspot.com/manifest.json&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The tool can also build the project, and running the command below will output an Android
application ready to be uploaded to the Play Store:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;npx @bubblewrap/cli build&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;After running this command, a file called &lt;code&gt;app-release-signed.apk&lt;/code&gt; will be available in the root
directory for the project. This is the file that will be &lt;a href=&quot;https://support.google.com/googleplay/android-developer/answer/3131213?hl=en-GB&quot; rel=&quot;noopener&quot;&gt;uploaded to the Play Store&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;pwabuilder&quot;&gt;PWABuilder &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#pwabuilder&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://pwabuilder.com/&quot; rel=&quot;noopener&quot;&gt;PWABuilder&lt;/a&gt; helps developers transform existing websites into Progressive Web Apps. It also
integrates with Bubblewrap to provide a GUI interface to wrap those PWAs into an Android app.
The PWABuilder team has put together a &lt;a href=&quot;https://www.davrous.com/2020/02/07/publishing-your-pwa-in-the-play-store-in-a-couple-of-minutes-using-pwa-builder/&quot; rel=&quot;noopener&quot;&gt;great blog post&lt;/a&gt; on how to generate an Android application
using the tool.&lt;/p&gt;
&lt;h2 id=&quot;verifying-ownership-of-the-pwa-in-the-android-app&quot;&gt;Verifying ownership of the PWA in the Android app &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#verifying-ownership-of-the-pwa-in-the-android-app&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A developer building a great Progressive Web App wouldn&#39;t want another developer to build an
Android app with it without their permission. To ensure this doesn&#39;t happen, the Android
application must be paired with the Progressive Web App using a tool called
&lt;a href=&quot;https://developers.google.com/digital-asset-links/v1/getting-started&quot; rel=&quot;noopener&quot;&gt;Digital Asset Links&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bubblewrap and PWABuilder take care of the necessary configuration on the Android application, but
a last step remains, which is adding the &lt;code&gt;assetlinks.json&lt;/code&gt; file to the PWA.&lt;/p&gt;
&lt;p&gt;To generate this file, developers need the SHA-256 signature of the key used to sign the APK that
is being downloaded by the users.&lt;/p&gt;
&lt;p&gt;The key can be generated in multiple ways, and the easiest way to find which key that signed the
APK being served to end users is to download it from the Play Store itself.&lt;/p&gt;
&lt;p&gt;To avoid showing a broken application to users, deploy the application to a
&lt;a href=&quot;https://support.google.com/googleplay/android-developer/answer/3131213?hl=en-GB&quot; rel=&quot;noopener&quot;&gt;closed test channel&lt;/a&gt;, install it into a test device then use &lt;a href=&quot;https://play.google.com/store/apps/details?id=dev.conn.assetlinkstool&quot; rel=&quot;noopener&quot;&gt;Peter&#39;s Asset Link Tool&lt;/a&gt; to
generate the correct &lt;code&gt;assetlinks.json&lt;/code&gt; file for the app. Make the generated &lt;code&gt;assetlinks.json&lt;/code&gt; file
available at &lt;code&gt;/.well-known/assetlinks.json&lt;/code&gt;, in the domain being validated.&lt;/p&gt;
&lt;h2 id=&quot;where-to-go-next&quot;&gt;Where to go next &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/using-a-pwa-in-your-android-app/#where-to-go-next&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A Progressive Web App is a high quality web experience. Trusted Web Activity is a new way to open
those high quality experiences from an Android app when they meet the minimum quality criteria.&lt;/p&gt;
&lt;p&gt;If you are getting started with Progressive Web Apps, read
&lt;a href=&quot;https://web.dev/progressive-web-apps/&quot;&gt;our guidance on how to build a great PWA&lt;/a&gt;. For developers who already have a PWA, use
&lt;a href=&quot;https://developer.chrome.com/docs/lighthouse/overview/&quot; rel=&quot;noopener&quot;&gt;Lighthouse&lt;/a&gt; to verify if it meets the quality criteria.&lt;/p&gt;
&lt;p&gt;Then, use &lt;a href=&quot;https://github.com/GoogleChromeLabs/bubblewrap&quot; rel=&quot;noopener&quot;&gt;Bubblewrap&lt;/a&gt; or &lt;a href=&quot;https://pwabuilder.com/&quot; rel=&quot;noopener&quot;&gt;PWABuilder&lt;/a&gt; to generate the Android application,
&lt;a href=&quot;https://support.google.com/googleplay/android-developer/answer/3131213?hl=en-GB&quot; rel=&quot;noopener&quot;&gt;upload the application to a closed test channel on the Play Store&lt;/a&gt; and pair it with the PWA
using &lt;a href=&quot;https://play.google.com/store/apps/details?id=dev.conn.assetlinkstool&quot; rel=&quot;noopener&quot;&gt;Peter&#39;s Asset Link Tool&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, move your application from the closed test channel to production!&lt;/p&gt;
</content>
    <author>
      <name>André Cipriani Bandarra</name>
    </author>
  </entry>
</feed>
