
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Tue, 14 Apr 2026 19:01:20 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Building vertical microfrontends on Cloudflare’s platform]]></title>
            <link>https://blog.cloudflare.com/vertical-microfrontends/</link>
            <pubDate>Fri, 30 Jan 2026 14:00:00 GMT</pubDate>
            <description><![CDATA[ Deploy multiple Workers under a single domain with the ability to make them feel like single-page applications. We take a look at how service bindings enable URL path routing to multiple projects. ]]></description>
            <content:encoded><![CDATA[ <p><i>Updated at 6:55 a.m. PT</i></p><p>Today, we’re introducing a new Worker template for Vertical Microfrontends (VMFE). <a href="https://dash.cloudflare.com/?to=/:account/workers-and-pages/create?type=vmfe"><u>This template</u></a> allows you to map multiple independent <a href="https://workers.cloudflare.com/"><u>Cloudflare Workers</u></a> to a single domain, enabling teams to work in complete silos — shipping marketing, docs, and dashboards independently — while presenting a single, seamless application to the user.</p><a href="https://dash.cloudflare.com/?to=/:account/workers-and-pages/create?type=vmfe"><img src="https://deploy.workers.cloudflare.com/button" /></a>
<p></p><p>Most microfrontend architectures are "horizontal", meaning different <i>parts</i> of a single page are fetched from different services. Vertical microfrontends take a different approach by splitting the application by URL path. In this model, a team owning the `/blog` path doesn't <i>just</i> own a component; they own the entire vertical stack for that route – framework, library choice, CI/CD and more. Owning the entire stack of a path, or set of paths, allows teams to have true ownership of their work and ship with confidence.</p><p>Teams face problems as they grow, where different frameworks serve varying use cases. A marketing website could be better utilized with Astro, for example, while a dashboard might be better with React. Or say you have a monolithic code base where many teams ship as a collective. An update to add new features from several teams can get frustratingly rolled back because a single team introduced a regression. How do we solve the problem of obscuring the technical implementation details away from the user and letting teams ship a cohesive user experience with full autonomy and control of their domains?</p><p>Vertical microfrontends can be the answer. Let’s dive in and explore how they solve developer pain points together.</p>
    <div>
      <h2>What are vertical microfrontends?</h2>
      <a href="#what-are-vertical-microfrontends">
        
      </a>
    </div>
    <p>A vertical microfrontend is an architectural pattern where a single independent team owns an entire slice of the application’s functionality, from the user interface all the way down to the <a href="https://www.cloudflare.com/learning/serverless/glossary/what-is-ci-cd/">CI/CD pipeline</a>. These slices are defined by paths on a domain where you can associate individual Workers with specific paths:</p>
            <pre><code>/      = Marketing
/docs  = Documentation
/blog  = Blog
/dash  = Dashboard</code></pre>
            <p>We could take it a step further and focus on more granular sub-path Worker associations, too, such as a dashboard. Within a dashboard, you likely segment out various features or products by adding depth to your URL path (e.g. <code>/dash/product-a</code>) and navigating between two products could mean two entirely different code bases. </p><p>Now with vertical microfrontends, we could also have the following:</p>
            <pre><code>/dash/product-a  = WorkerA
/dash/product-b  = WorkerB</code></pre>
            <p>Each of the above paths are their own frontend project with zero shared code between them. The <code>product-a</code> and <code>product-b</code> routes map to separately deployed frontend applications that have their own frameworks, libraries, CI/CD pipelines defined and owned by their own teams. FINALLY.</p><p>You can now own your own code from end to end. But now we need to find a way to stitch these separate projects together, and even more so, make them feel as if they are a unified experience.</p><p>We experience this pain point ourselves here at Cloudflare, as the dashboard has many individual teams owning their own products. Teams must contend with the fact that changes made outside their control impact how users experience their product. </p><p>Internally, we are now using a similar strategy for our own dashboard. When users navigate from the core dashboard into our ZeroTrust product, in reality they are two entirely separate projects and the user is simply being routed to that project by its path <code>/:accountId/one</code>.</p>
    <div>
      <h2>Visually unified experiences</h2>
      <a href="#visually-unified-experiences">
        
      </a>
    </div>
    <p>Stitching these individual projects together to make them feel like a unified experience isn’t as difficult as you might think: It only takes a few lines of CSS magic. What we <i>absolutely do not want</i> to happen is to leak our implementation details and internal decisions to our users. If we fail to make this user experience feel like one cohesive frontend, then we’ve done a grave injustice to our users. </p><p>To accomplish this sleight of hand, let us take a little trip in understanding how view transitions and document preloading come into play.</p>
    <div>
      <h3>View transitions</h3>
      <a href="#view-transitions">
        
      </a>
    </div>
    <p>When we want to seamlessly navigate between two distinct pages while making it feel smooth to the end user, <a href="https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API"><u>view transitions</u></a> are quite useful. Defining specific <a href="https://www.w3schools.com/jsref/dom_obj_all.asp"><u>DOM elements</u></a> on our page to stick around until the next page is visible, and defining how any changes are handled, make for quite the powerful quilt-stitching tool for multi-page applications.</p><p>There may be, however, instances where making the various vertical microfrontends feel different is more than acceptable. Perhaps our marketing website, documentation, and dashboard are each uniquely defined, for instance. A user would not expect all three of those to feel cohesive as you navigate between the three parts. But… if you decide to introduce vertical slices to an individual experience such as the dashboard (e.g. <code>/dash/product-a</code> &amp; <code>/dash/product-b</code>), then users should <b>never</b> know they are two different repositories/workers/projects underneath.</p><p>Okay, enough talk — let’s get to work. I mentioned it was low-effort to make two separate projects feel as if they were one to a user, and if you have yet to hear about <a href="https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API"><u>CSS View Transitions</u></a> then I’m about to blow your mind.</p><p>What if I told you that you could make animated transitions between different views  — single-page app (SPA) or multi-page app (MPA) — feel as if they were one? Before any view transitions are added, if we navigate between pages owned by two different Workers, the interstitial loading state would be the white blank screen in our browser for some few hundred milliseconds until the full next page began rendering. Pages would not feel cohesive, and it certainly would not feel like a single-page application.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4vw1Am7gYUQPtmFFCRcsu1/774b881dff7ce1c26db88f30623dfc13/image3.png" />
          </figure><p><sup>Appears as multiple navigation elements between each site.</sup></p><p>If we want elements to stick around, rather than seeing a white blank page, we can achieve that by defining CSS View Transitions. With the code below, we’re telling our current document page that when a view transition event is about to happen, keep the <code>nav</code> DOM element on the screen, and if any delta in appearance exists between our existing page and our destination page, then we’ll animate that with an <code>ease-in-out</code> transition.</p><p>All of a sudden, two different Workers feel like one.</p>
            <pre><code>@supports (view-transition-name: none) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.3s;
    animation-timing-function: ease-in-out;
  }
  nav { view-transition-name: navigation; }
}</code></pre>
            
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4h6Eh5LSX4552QJDvV1l7o/a5a43ee0e6e011bca58ecc2d74902744/image1.png" />
          </figure><p><sup>Appears as a single navigation element between three distinct sites.</sup></p>
    <div>
      <h3>Preloading</h3>
      <a href="#preloading">
        
      </a>
    </div>
    <p>Transitioning between two pages makes it <i>look</i> seamless — and we also want it to <i>feel</i> as instant as a client-side SPA. While currently Firefox and Safari do not support <a href="https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API"><u>Speculation Rules</u></a>, Chrome/Edge/Opera do support the more recent newcomer. The speculation rules API is designed to improve performance for future navigations, particularly for document URLs, making multi-page applications feel more like single-page applications.</p><p>Breaking it down into code, what we need to define is a script rule in a specific format that tells the supporting browsers how to prefetch the other vertical slices that are connected to our web application — likely linked through some shared navigation.</p>
            <pre><code>&lt;script type="speculationrules"&gt;
  {
    "prefetch": [
      {
        "urls": ["https://product-a.com", "https://product-b.com"],
        "requires": ["anonymous-client-ip-when-cross-origin"],
        "referrer_policy": "no-referrer"
      }
    ]
  }
&lt;/script&gt;</code></pre>
            <p>With that, our application prefetches our other microfrontends and holds them in our in-memory cache, so if we were to navigate to those pages it would feel nearly instant.</p><p>You likely won’t require this for clearly discernible vertical slices (marketing, docs, dashboard) because users would expect a slight load between them. However, it is highly encouraged to use when vertical slices are defined within a specific visible experience (e.g. within dashboard pages).</p><p>Between <a href="https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API"><u>View Transitions</u></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API"><u>Speculation Rules</u></a>, we are able to tie together entirely different code repositories to feel as if they were served from a single-page application. Wild if you ask me.</p>
    <div>
      <h2>Zero-config request routing</h2>
      <a href="#zero-config-request-routing">
        
      </a>
    </div>
    <p>Now we need a mechanism to host multiple applications, and a method to stitch them together as requests stream in. Defining a single Cloudflare Worker as the “Router” allows a single logical point (at the edge) to handle network requests and then forward them to whichever vertical microfrontend is responsible for that URL path. Plus it doesn’t hurt that then we can map a single domain to that router Worker and the rest “just works.”</p>
    <div>
      <h3>Service bindings</h3>
      <a href="#service-bindings">
        
      </a>
    </div>
    <p>If you have yet to explore Cloudflare Worker <a href="https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/"><u>service bindings</u></a>, then it is worth taking a moment to do so. </p><p>Service bindings allow one Worker to call into another, without going through a publicly-accessible URL. A Service binding allows Worker A to call a method on Worker B, or to forward a request from Worker A to Worker. Breaking it down further, the Router Worker can call into each vertical microfrontend Worker that has been defined (e.g. marketing, docs, dashboard), assuming each of them were Cloudflare Workers.</p><p>Why is this important? This is precisely the mechanism that “stitches” these vertical slices together. We’ll dig into how the request routing is handling the traffic split in the next section. But to define each of these microfrontends, we’ll need to update our Router Worker’s wrangler definition, so it knows which frontends it’s allowed to call into.
</p>
            <pre><code>{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "router",
  "main": "./src/router.js",
  "services": [
    {
      "binding": "HOME",
      "service": "worker_marketing"
    },
    {
      "binding": "DOCS",
      "service": "worker_docs"
    },
    {
      "binding": "DASH",
      "service": "worker_dash"
    },
  ]
}</code></pre>
            <p>Our above sample definition is defined in our Router Worker, which then tells us that we are permitted to make requests into three separate additional Workers (marketing, docs, and dash). Granting permissions is as simple as that, but let’s tumble into some of the more complex logic with request routing and HTML rewriting network responses.</p>
    <div>
      <h3>Request routing</h3>
      <a href="#request-routing">
        
      </a>
    </div>
    <p>With knowledge of the various other Workers we are able to call into if needed, now we need some logic in place to know where to direct network requests when. Since the Router Worker is assigned to our custom domain, all incoming requests hit it first at the network edge. It then determines which Worker should handle the request and manages the resulting response. </p><p>The first step is to map URL paths to associated Workers. When a certain request URL is received, we need to know where it needs to be forwarded. We do this by defining rules. While we support wildcard routes, dynamic paths, and parameter constraints, we are going to stay focused on the basics — literal path prefixes — as it illustrates the point more clearly. </p><p> In this example, we have three microfrontends:</p>
            <pre><code>/      = Marketing
/docs  = Documentation
/dash  = Dashboard</code></pre>
            <p>Each of the above paths need to be mapped to an actual Worker (see our wrangler definition for services in the section above). For our Router Worker, we define an additional variable with the following data, so we can know which paths should map to which service bindings. We now know where to route users as requests come in! Define a wrangler variable with the name ROUTES and the following contents:</p>
            <pre><code>{
  "routes":[
    {"binding": "HOME", "path": "/"},
    {"binding": "DOCS", "path": "/docs"},
    {"binding": "DASH", "path": "/dash"}
  ]
}</code></pre>
            <p>Let’s envision a user visiting our website path <code>/docs/installation</code>. Under the hood, what happens is the request first reaches our Router Worker which is in charge of understanding what URL paths map to which individual Workers. It understands that the <code>/docs</code> path prefix is mapped to our <code>DOCS</code> service binding which referencing our wrangler file points us at our <code>worker_docs</code> project. Our Router Worker, knowing that <code>/docs</code> is defined as a vertical microfrontend route, removes the <code>/docs</code> prefix from the path and forwards the request to our <code>worker_docs</code> Worker to handle the request and then finally returns whatever response we get.</p><p>Why does it drop the <code>/docs</code> path, though? This was an implementation detail choice that was made so that when the Worker is accessed via the Router Worker, it can clean up the URL to handle the request <i>as if </i>it were called from outside our Router Worker. Like any Cloudflare Worker, our <code>worker_docs</code> service might have its own individual URL where it can be accessed. We decided we wanted that service URL to continue to work independently. When it’s attached to our new Router Worker, it would automatically handle removing the prefix, so the service could be accessible from its own defined URL or through our Router Worker… either place, doesn’t matter.</p>
    <div>
      <h3>HTMLRewriter</h3>
      <a href="#htmlrewriter">
        
      </a>
    </div>
    <p>Splitting our various frontend services with URL paths (e.g. <code>/docs</code> or <code>/dash</code>) makes it easy for us to forward a request, but when our response contains HTML that doesn’t know it’s being reverse proxied through a path component… well, that causes problems. </p><p>Say our documentation website has an image tag in the response <code>&lt;img src="./logo.png" /&gt;</code>. If our user was visiting this page at <code>https://website.com/docs/</code>, then loading the <code>logo.png</code> file would likely fail because our <code>/docs</code> path is somewhat artificially defined only by our Router Worker.</p><p>Only when our services are accessed through our Router Worker do we need to do some HTML rewriting of absolute paths so our returned browser response references valid assets. In practice what happens is that when a request passes through our Router Worker, we pass the request to the correct Service Binding, and we receive the response from that. Before we pass that back to the client, we have an opportunity to rewrite the DOM — so where we see absolute paths, we go ahead and prepend that with the proxied path. Where previously our HTML was returning our image tag with <code>&lt;img src="./logo.png" /&gt;</code> we now modify it before returning to the client browser to <code>&lt;img src="./docs/logo.png" /&gt;</code>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/10jKx6qt2YcarpDyEsFNYV/3b0f11f56e3c9b2deef59934cf8efa7f/image2.png" />
          </figure><p>Let’s return for a moment to the magic of CSS view transitions and document preloading. We could of course manually place that code into our projects and have it work, but this Router Worker will <i>automatically</i> handle that logic for us by also using <a href="https://developers.cloudflare.com/workers/runtime-apis/html-rewriter/"><u>HTMLRewriter</u></a>. </p><p>In your Router Worker <code>ROUTES</code> variable, if you set <code>smoothTransitions</code> to <code>true</code> at the root level, then the CSS transition views code will be added automatically. Additionally, if you set the <code>preload</code> key within a route to <code>true</code>, then the script code speculation rules for that route will automatically be added as well. </p><p>Below is an example of both in action:</p>
            <pre><code>{
  "smoothTransitions":true, 
  "routes":[
    {"binding": "APP1", "path": "/app1", "preload": true},
    {"binding": "APP2", "path": "/app2", "preload": true}
  ]
}</code></pre>
            
    <div>
      <h2>Get started</h2>
      <a href="#get-started">
        
      </a>
    </div>
    <p>You can start building with the Vertical Microfrontend template today.</p><p>Visit the Cloudflare Dashboard <a href="https://dash.cloudflare.com/?to=/:account/workers-and-pages/create?type=vmfe"><u>deeplink here</u></a> or go to “Workers &amp; Pages” and click the “Create application” button to get started. From there, click “Select a template” and then “Create microfrontend” and you can begin configuring your setup.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1teTcTNHzQH3yCvbTz3xyU/8f9a4b2ef3ec1c6ed13cbdc51d6b13c5/image5.png" />
          </figure><p>
Check out the <a href="https://developers.cloudflare.com/workers/framework-guides/web-apps/microfrontends"><u>documentation</u></a> to see how to map your existing Workers and enable View Transitions. We can't wait to see what complex, multi-team applications you build on the edge!</p> ]]></content:encoded>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Front End]]></category>
            <category><![CDATA[Micro-frontends]]></category>
            <guid isPermaLink="false">2u7SNZ4BZcQYHZYKqmdEaM</guid>
            <dc:creator>Brayden Wilmoth</dc:creator>
        </item>
        <item>
            <title><![CDATA[Troubleshooting network connectivity and performance with Cloudflare AI]]></title>
            <link>https://blog.cloudflare.com/AI-troubleshoot-warp-and-network-connectivity-issues/</link>
            <pubDate>Fri, 29 Aug 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Troubleshoot network connectivity issues by using Cloudflare AI-Power to quickly self diagnose and resolve WARP client and network issues. ]]></description>
            <content:encoded><![CDATA[ <p>Monitoring a corporate network and troubleshooting any performance issues across that network is a hard problem, and it has become increasingly complex over time. Imagine that you’re maintaining a corporate network, and you get the dreaded IT ticket. An executive is having a performance issue with an application, and they want you to look into it. The ticket doesn’t have a lot of details. It simply says: “Our internal documentation is taking forever to load. PLS FIX NOW”.</p><p>In the early days of IT, a corporate network was built on-premises. It provided network connectivity between employees that worked in person and a variety of corporate applications that were hosted locally.</p><p>The shift to cloud environments, the rise of SaaS applications, and a “work from anywhere” model has made IT environments significantly more complex in the past few years. Today, it’s hard to know if a performance issue is the result of:</p><ul><li><p>An employee’s device</p></li><li><p>Their home or corporate wifi</p></li><li><p>The corporate network</p></li><li><p>A cloud network hosting a SaaS app</p></li><li><p>An intermediary ISP</p></li></ul><p>A performance ticket submitted by an employee might even be a combination of multiple performance issues all wrapped together into one nasty problem.</p><p>Cloudflare built <a href="https://developers.cloudflare.com/cloudflare-one/"><u>Cloudflare One</u></a>, our <a href="https://www.cloudflare.com/learning/access-management/what-is-sase/">Secure Access Service Edge (SASE) </a>platform, to protect enterprise applications, users, devices, and networks. In particular, this platform relies on two capabilities to simplify troubleshooting performance issues:</p><ul><li><p>Cloudflare’s Zero Trust client, also known as <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/"><u>WARP</u></a>, forwards and encrypts traffic from devices to Cloudflare edge.</p></li><li><p>Digital Experience Monitoring (<a href="https://developers.cloudflare.com/cloudflare-one/insights/dex/"><u>DEX</u></a>) works alongside WARP to monitor device, network, and application performance.</p></li></ul><p>We’re excited to announce two new AI-powered tools that will make it easier to troubleshoot WARP client connectivity and performance issues.  We’re releasing a new WARP diagnostic analyzer in the <a href="https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/">Zero Trust</a> dashboard and a <a href="https://www.cloudflare.com/learning/ai/what-is-model-context-protocol-mcp/"><u>MCP (Model Context Protocol)</u></a> server for DEX. Today, every Cloudflare One customer has free access to both of these new features by default.</p>
    <div>
      <h2>WARP diagnostic analyzer</h2>
      <a href="#warp-diagnostic-analyzer">
        
      </a>
    </div>
    <p>The WARP client provides diagnostic logs that can be used to troubleshoot connectivity issues on a device. For desktop clients, the most common issues can be investigated with the information captured in logs called <a href="https://developers.cloudflare.com/learning-paths/warp-overview-course/series/warp-basics-2/"><u>WARP diagnostic</u></a>. Each WARP diagnostic log contains an extensive amount of information spanning days of captured events occurring on the client. It takes expertise to manually go through all of this information and understand the full picture of what is occurring on a client that is having issues. In the past, we’ve advised customers having issues to send their WARP diagnostic log straight to us so that our trained support experts can do a root cause analysis for them. While this is effective, we want to give our customers the tools to take control of deciphering common troubleshooting issues for even quicker resolution. </p><p>Enter the WARP diagnostic analyzer, a new AI available for free in the Cloudflare One dashboard as of today! This AI demystifies information in the WARP diagnostic log so you can better understand events impacting the performance of your clients and network connectivity. Now, when you run a <a href="https://developers.cloudflare.com/cloudflare-one/insights/dex/remote-captures/"><u>remote capture for WARP diagnostics</u></a> in the Cloudflare One dashboard, you can generate an <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/troubleshooting/warp-logs/#view-warp-diagnostics-summary-beta"><u>AI analysis of the WARP diagnostic file</u></a>. Simply go to your organization’s Zero Trust dashboard and select DEX &gt; Remote Captures from the side navigation bar. After you successfully run diagnostics and produce a WARP diagnostic file, you can open the status details and select View WARP Diag to generate your AI analysis.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/50lz9CFKKJJjL5GpppLu8V/4b404a2ec700713579b3ec9a616ee4c4/image4.png" />
          </figure><p>In the WARP Diag analysis, you will find a Cloudy summary of events that we recommend a deeper dive into.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6rV0XPL9aayuljbw9X46bQ/6fd046dfcf6d882948d1a98912cf7cab/image1.png" />
          </figure><p>Below this summary is an events section, where the analyzer highlights occurrences of events commonly occurring when there are client and connectivity issues. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4OxLtM2CQ4SSs8NTGUdcpn/b7e4f0e3eb519838d50759e6d1decf75/image7.png" />
          </figure><p>Expanding on any of the events detected will reveal a detailed page explaining the event, recommended resources to help troubleshoot, and a list of time stamped recent occurrences of the event on the device. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4ceezR6L1MybxhMtJGuL5U/31f24b0a057871a1f4330ea87f050873/Screenshot_2025-09-03_at_4.20.27%C3%A2__PM.png" />
          </figure><p>To further help with trouble shooting we’ve added a Device and WARP details section at the bottom of this page with a quick view of the device specifications and WARP configurations such as Operating system, WARP version, and the device profile ID.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/41N2iTeHQ9JfrOOsqG8MY5/550fa7573a6d4ed61479679cb4e954d3/image6.png" />
          </figure><p>Finally, we’ve made it easy to take all the information created in your AI summary with you by navigating to the JSON file tab and copying the contents. Your WARP Diag file is also available to download from this screen for any further analysis.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1Sha8rpC7XwSkCvBWt6lv2/2702873ce14fe80904d4f0886e6f3528/image2.png" />
          </figure>
    <div>
      <h2>MCP server for DEX</h2>
      <a href="#mcp-server-for-dex">
        
      </a>
    </div>
    <p>Alongside the new WARP Diagnostic Analyzer, we’re excited to announce that all Cloudflare One customers have access to a MCP (Model Context Protocol) server for our Digital Experience Monitoring (DEX) product. Let’s dive into how this will save our customers time and money.</p><p>Cloudflare One customers use Digital Experience Monitoring (DEX) to monitor devices across their employee network and troubleshoot any connectivity or performance issues. Like many products at Cloudflare, every data point generated by DEX is available to customers via Cloudflare’s API or log ingestion. DEX API and log data is valuable because it enables Enterprises to create custom analytics for their devices’ connectivity and performance in a SIEM (<a href="https://www.cloudflare.com/learning/security/what-is-siem/"><u>Security Information and Event Management</u></a>). Building new data pipelines and various dashboards can take a lot of time and can be expensive. Some of Cloudflare One customers aren’t able to dedicate the engineering time to build custom analytics: whether it’s due to budget, resource constraints, time constraints, or other factors.</p><p>Model Context Protocol (MCP) is an AI standardization that allows AI to connect to other applications. In this instance, using MCP together with DEX gives users a custom analytics experience — without all the work of integrating log data into a SIEM. Network security practitioners can type out a question (like “Show me the performance data for alice@acme.com’s device in a few graphs”), and an MCP server will answer that question with a customized graph on Alice’s device data from the DEX API.</p>
    <div>
      <h2>Troubleshooting DNS query performance with the DEX MCP server</h2>
      <a href="#troubleshooting-dns-query-performance-with-the-dex-mcp-server">
        
      </a>
    </div>
    <p>Any IT admin, security engineer, or network engineer can ask the MCP server a question like: “I received an IT ticket from bob@acme.com who is an enterprise employee. He is complaining about the performance of his device. Can you investigate this for me?”.</p><p>After you submit this question, the DEX MCP server will start by reviewing the device’s overall health.</p>
            <pre><code>Overall Device Health:
✅ Connection Status: Consistently connected for the past 24 hours with 100% availability
✅ WARP Mode: Running in optimal "warp+doh" (WARP + DNS over HTTPS) mode
✅ Client Version: Up-to-date with version 2025.1.7.2</code></pre>
            <p>So far, the device’s health looks great. Next, the DEX MCP server will begin analyzing the results of the performance tests that are configured on Bob’s device.</p>
            <pre><code>📊 Performance Metrics Analysis

HTTP Response Times:
Google.com test: Average 247ms (Range: 81-649ms)
  • Shows significant improvement throughout the day: Started at ~317ms, dropped to ~211ms by evening
Wiki.internal.acme.com: Average 1,374ms (Range: 877-2,431ms)
  • This is notably high and could be the source of performance complaints
  • DNS resolution particularly slow: Average 616ms with spikes up to 1,600ms</code></pre>
            <p>Now we’re making progress in our troubleshooting effort. The DEX MCP server identified that the HTTP GET test for wiki.internal.acme.com has a high average resource fetch time when compared to other websites (like google.com). In particular, high resource fetch time is the result of slow DNS resolution. Now, the DEX MCP server will summarize its findings.</p>
            <pre><code>🚨 Performance Issues Identified
Extremely Slow DNS Resolution:
  • Average DNS response time of 616ms is significantly high
  • Normal DNS should be &lt;50ms for good performance
High Resource Fetch Times on wiki.internal.acme.com:
   • 1.3+ second response times indicate potential application-level issues
   • Could be related to DNS performance or server-side delays
HTTP Status Code Issues:
        • wiki.internal.acme.com is showing consistent HTTP 400 errors
        • This suggests potential configuration or routing issues</code></pre>
            <p>Now, we’ve successfully identified that Bob’s slow wiki performance is the result of a high average DNS response time. Slow DNS resolution increases the average resource fetch time, and also generates HTTP 400 errors for Enterprise employees that are attempting to access wiki.internal.acme.com. Notably, it’s likely that if the wiki is seeing slow DNS response times, other internal applications are experiencing performance issues as well.</p><p>We can ask the DEX MCP server to suggest potential solutions that would fix this wider DNS performance issue.</p>
            <pre><code>🔧 DNS Optimization Strategies

Check WARP DNS configuration and settings
  • Since the device is using WARP+DoH mode, you can optimize the DNS settings
Implement or improve local DNS caching
  • Implement or improve local DNS caching to reduce repeated lookups
Network stack tuning
  • Optimize TCP / UDP settings for DNS</code></pre>
            
    <div>
      <h2>Try out the DEX MCP server today</h2>
      <a href="#try-out-the-dex-mcp-server-today">
        
      </a>
    </div>
    
    <div>
      <h3>Fast and easy option for testing an MCP server</h3>
      <a href="#fast-and-easy-option-for-testing-an-mcp-server">
        
      </a>
    </div>
    <p>Any Cloudflare One customer with a Free, PayGo, or ENT plan can start using the DEX MCP server in less than one minute. The fastest and easiest way to try out the DEX MCP server is to visit <a href="http://playground.ai.cloudflare.com"><u>playground.ai.cloudflare.com</u></a>. There are five steps to get started:</p><ol><li><p>Copy the URL for the DEX MCP server: https://dex.mcp.cloudflare.com/sse</p></li><li><p>Open <a href="http://playground.ai.cloudflare.com"><u>playground.ai.cloudflare.com</u></a> in a browser</p></li><li><p>Find the section in the left side bar titled <b>MCP Servers</b></p></li><li><p>Paste the URL for the DEX MCP server into the URL input box and click <b>Connect</b></p></li><li><p>Authenticate your Cloudflare account, and then start asking questions to the DEX MCP server</p></li></ol><p>It’s worth noting that end users will need to ask specific and explicit questions to the DEX MCP server to get a response. For example, you may need to say, “Set my production account as the active  account”, and then give the separate command, “Fetch the DEX test results for the user bob@acme.com over the past 24 hours”.</p>
    <div>
      <h3>Better experience for MCP servers that requires additional steps</h3>
      <a href="#better-experience-for-mcp-servers-that-requires-additional-steps">
        
      </a>
    </div>
    <p>Customers will get a more flexible prompt experience by configuring the DEX MCP server with their preferred AI assistant (Claude, Gemini, ChatGPT, etc.) that has MCP server support. MCP server support may require a subscription for some AI assistants. You can read the <a href="https://developers.cloudflare.com/cloudflare-one/insights/dex/dex-mcp-server"><u>Digital Experience Monitoring - MCP server documentation</u></a> for step by step instructions on how to get set up with each of the major AI assistants that are available today.</p><p>As an example, you can configure the DEX MCP server in Claude by downloading the Claude Desktop client, then selecting Claude Code &gt; Developer &gt; Edit Config. You will be prompted to open “claude_desktop_config.json” in a code editor of your choice. Simply add the following JSON configuration, and you’re ready to use Claude to call the DEX MCP server.</p>
            <pre><code>{
  "globalShortcut": "",
  "mcpServers": {
    "cloudflare-dex-analysis": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://dex.mcp.cloudflare.com/sse"
      ]
    }
  }
}</code></pre>
            
    <div>
      <h2>Get started with Cloudflare One today</h2>
      <a href="#get-started-with-cloudflare-one-today">
        
      </a>
    </div>
    <p>Are you ready to secure your Internet traffic, employee devices, and private resources without compromising speed? You can get started with our new Cloudflare One AI powered tools today.</p><p>The WARP diagnostic analyzer and the DEX MCP server are generally available to all customers. Head to the Zero Trust dashboard to run a WARP diagnostic and learn more about your client’s connectivity with the WARP diagnostic analyzer. You can test out the new DEX MCP server (https://dex.mcp.cloudflare.com/sse) in less than one minute at <a href="http://playground.ai.cloudflare.com"><u>playground.ai.cloudflare.com</u></a>, and you can also configure an AI assistant like Claude to use the new <a href="https://developers.cloudflare.com/cloudflare-one/insights/dex/dex-mcp-server"><u>DEX MCP server</u></a>.</p><p>If you don’t have a Cloudflare account, and you want to try these new features, you can create a free account for up to 50 users. If you’re an Enterprise customer, and you’d like a demo of these new Cloudflare One AI features, you can reach out to your account team to set up a demo anytime. </p><p>You can stay up to date on latest feature releases across the Cloudflare One platform by following the <a href="https://developers.cloudflare.com/cloudflare-one/changelog/"><u>Cloudflare One changelogs</u></a> and joining the conversation in the <a href="https://community.cloudflare.com/"><u>Cloudflare community hub</u></a> or on our <a href="https://discord.cloudflare.com/"><u>Discord Server</u></a>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/CvbpyPLYM62H7B0GhGqcZ/79317635029a9d09d31dacbec6793887/image5.png" />
          </figure><div>
  
</div><p></p> ]]></content:encoded>
            <category><![CDATA[AI Week]]></category>
            <category><![CDATA[Monitoring]]></category>
            <category><![CDATA[Analytics]]></category>
            <category><![CDATA[WARP]]></category>
            <category><![CDATA[Device Security]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Cloudflare One]]></category>
            <category><![CDATA[AI]]></category>
            <guid isPermaLink="false">7vSTlKJvMibVnsLp1YLWKe</guid>
            <dc:creator>Chris Draper</dc:creator>
            <dc:creator>Koko Uko</dc:creator>
        </item>
        <item>
            <title><![CDATA[Making Application Security simple with a new unified dashboard experience]]></title>
            <link>https://blog.cloudflare.com/new-application-security-experience/</link>
            <pubDate>Thu, 20 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ We’re introducing a new Application Security experience in the Cloudflare dashboard, with a reworked UI organized by use cases, making it easier for customers to navigate and secure their accounts. ]]></description>
            <content:encoded><![CDATA[ <p>Over the years, we have framed our Application Security features against market-defined product groupings such as Web Application Firewall (WAF), DDoS Mitigation, Bot Management, API Security (API Shield), Client Side Security (Page Shield), and so forth. This has led to unnecessary artificial separation of what is, under the hood, a well-integrated single platform.</p><p>This separation, which has sometimes guided implementation decisions that have led to different systems being built for the same purpose, makes it harder for our users to adopt our features and implement a simple effective security posture for their environment.</p><p>Today, following user feedback and our drive to constantly innovate and simplify, we are going back to our roots by breaking these artificial product boundaries and revising our dashboard, so it highlights our strengths. The ultimate goal remains: to make it shockingly easy to secure your web assets.</p><p><b>Introducing a new unified Application Security experience.</b></p><p>If you are a Cloudflare Application Security user, log in <a href="http://dash.cloudflare.com/:account/:zone/security"><u>to the dashboard</u></a> today and try out the updated dashboard interface. To make the transition easier, you can toggle between old and new interfaces.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/iyOx4HWAdpFyp0W6nECvi/5f67090ee17c9db87ce2c130f80d493a/image5.png" />
          </figure>
    <div>
      <h2>Security, simplified</h2>
      <a href="#security-simplified">
        
      </a>
    </div>
    <p>Modern applications are built using a variety of technologies. Your app might include a web interface and a mobile version, both powered by an API, each with its own unique security requirements. As these technologies increasingly overlap, traditional security categories like Web, API, client-side, and bot protection start to feel artificial and disconnected when applied to real-world application security.</p><p>Consider scenarios where you want to secure your API endpoints with proper authentication, or prevent vulnerability scanners from probing for weaknesses. These tasks often require switching between multiple dashboards, creating different policies, and managing disjointed configurations. This fragmented approach not only complicates workflows but also increases the risk of overlooking a critical vulnerability. The result? A security posture that is harder to manage and potentially less effective.</p><p>When you zoom out, a pattern emerges. Whether it’s managing bots, securing APIs, or filtering web traffic, these solutions ultimately analyze incoming traffic looking for specific patterns, and the resulting signal is used to perform actions. The primary difference between these tools is the type of signal they generate, such as identifying bots, enforcing authorization, or flagging suspicious requests. </p><p>At Cloudflare, we saw an opportunity to address this complexity by unifying our application security tools into a single platform with one cohesive UI. A unified approach means security practitioners no longer have to navigate multiple interfaces or piece together different security controls. With a single UI, you can configure policies more efficiently, detect threats faster, and maintain consistent protection across all aspects of your application. This simplicity doesn’t just save time, it ensures that your applications remain secure, even as threats evolve.</p><p>At the end of the day, attackers won’t care which product you’re using. But by unifying application security, we ensure they’ll have a much harder time finding a way in.</p>
    <div>
      <h2>Many products, one common approach</h2>
      <a href="#many-products-one-common-approach">
        
      </a>
    </div>
    <p>To redefine the experience across Application Security products, we can start by defining three concepts that commonly apply:</p><ul><li><p>Web traffic (HTTP/S), which can be generalised even further as “data”</p></li><li><p>Signals and detections, which provide intelligence about the traffic. Can be generalised as “metadata”</p></li><li><p>Security rules that let you combine any signal or detection (metadata), to block, challenge or otherwise perform an action on the web traffic (data)</p></li></ul><p>We can diagram the above as follows:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/46XB4bR8DSCZWe7PDQNDLp/4043ff4d123c4b8c5eafe0948c2fdefe/image1.png" />
          </figure><p>Using these concepts, all the product groupings that we offer can be converted to different types of signals or detections. All else remains the same. And if we are able to run and generate our signals on all traffic separately from the rule system, therefore generating all the metadata, we get what we call <a href="https://developers.cloudflare.com/waf/detections/"><b><u>always-on detections</u></b></a>, another vital benefit of a single platform approach. Also note that <a href="https://blog.cloudflare.com/traffic-sequence-which-product-runs-first/"><u>the order</u></a> in which we generate the signals becomes irrelevant.</p><p>In diagram form:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5TgbZHUYCkztCPfpbk8rYQ/d2ec02dddb61b8b708019aade73b9623/image12.png" />
          </figure><p>The benefits are twofold. First, problem spaces (such as account takeover or web attacks) become signal groupings, and therefore metadata that can be queried to answer questions about your environment.</p><p>For example, let’s take our Bot Management signal, the <a href="https://developers.cloudflare.com/bots/concepts/bot-score/"><u>bot score</u></a>, and our <a href="https://developers.cloudflare.com/waf/detections/attack-score/"><u>WAF Attack Score</u></a> signal, the attack score. These already run as always-on detections at Cloudflare. By combining these two signals and filtering your traffic against them, you can gain powerful insights on who is accessing your application<b>*</b>:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7xcSJtpZdY8L5svEob6dRW/f779872d453551b8d5ca11845a246fc5/image11.png" />
          </figure><p>Second, as everything is just a signal, the mitigation layer, driven by the optional rules, becomes detection agnostic. By providing the same signals as fields in a unified rule system, writing high level policies becomes a breeze. And as we said earlier, given the detection is <b>always-on </b>and fully separated from the mitigation rule system, exploring the data can be thought of as a powerful rule match preview engine. No need to deploy a rule in LOG mode to see what it matches!</p><p>We can now design a unified user experience that reflects Application Security as a single product.</p><p><sup><b><i>* note:</i></b></sup><sup><i> the example here is simplistic, and the use cases become a lot more powerful once you expand to the full set of potential signals that the platform can generate. Take, for example, our ability to detect file uploads. If you run a job application site, you may want to let crawlers access your site, but you may *</i></sup><sup><b><i>not</i></b></sup><sup><i>* want crawlers to submit applications on behalf of applicants. By combining the bot score signal with the file upload signal, you can ensure that rule is enforced.</i></sup></p>
    <div>
      <h2>Introducing a unified Application Security experience</h2>
      <a href="#introducing-a-unified-application-security-experience">
        
      </a>
    </div>
    <p>As signals are always-on, the user journey can now start from our <a href="https://blog.cloudflare.com/cloudflare-security-posture-management/#:~:text=protect%20what%20matters.-,Posture%20overview,-from%20attacks%20to"><u>new overview page</u></a> where we highlight security suggestions based on your traffic profile and configurations. Alternatively, you can jump straight into analytics where you can investigate your traffic using a combination of all available signals.</p><p>When a specific traffic pattern seems malicious, you can jump into the rule system to implement a security policy. As part of our new design, given the simplicity of the navigation, we also took advantage of the opportunity to introduce a <a href="https://blog.cloudflare.com/cloudflare-security-posture-management/#:~:text=Discovery%20of%20web%20assets"><u>new web assets page</u></a>, where we highlight discovery and attack surface management details.</p><p>Of course, reaching the final design required multiple iterations and feedback sessions. To best understand the balance of maintaining flexibility in the UI whilst reducing complexity, we focused on customer tasks to be done and documenting their processes while trying to achieve their intended actions in the dashboard. Reducing navigation items and using clear naming was one element, but we quickly learned that the changes needed to support ease of use for tasks across the platform.</p><p>Here is the end result:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2IFfm5Q1D6sfGzqhasl2Pb/e2f078c281a4067f5bb624b0ca37509e/image8.png" />
          </figure><p>To recap, our new dashboard now includes:</p><ul><li><p>One overview page where misconfigurations, risks, and suggestions are aggregated</p></li><li><p>Simplified and redesigned security analytics that surfaces security signals from all Application Security capabilities, so you can easily identify and act on any suspicious activity</p></li><li><p>A new web assets page, where you can manage your attack surfaces, helping improve detection relevance</p></li><li><p>A single Security Rules page that provides a unified interface to manage, prioritise, and customise all mitigation rules in your zone, significantly streamlining your security configuration</p></li><li><p>A new settings page where advanced control is based on security needs, not individual products</p></li></ul><p>Let’s dive into each one.</p>
    <div>
      <h3>Overview</h3>
      <a href="#overview">
        
      </a>
    </div>
    <p>With the unified security approach, the new overview page aggregates and prioritizes security suggestions across all your web assets, helping you <a href="https://blog.cloudflare.com/cloudflare-security-posture-management/"><u>maintain a healthy security posture</u></a>. The suggestions span from detected (ongoing) attacks if there are any, to risks and misconfigurations to further solidify your protection. This becomes the daily starting point to manage your security posture.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/19dZ0olpyIjEjywnd5zRrh/32bd0b872ab3c00f411e5287a8e2b6ae/image6.png" />
          </figure>
    <div>
      <h3>Analytics</h3>
      <a href="#analytics">
        
      </a>
    </div>
    <p>Security Analytics and Events have been redesigned to make it easier to analyze your traffic. Suspicious activity detected by Cloudflare is surfaced at the top of the page, allowing you to easily filter and review related traffic. From the Traffic Analytics Sampled Log view, further below in the page, new workflows enable you to take quick action to craft a custom rule or review related security events in context.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/16cUGVu3gqAD8sm9OaAs6x/2ef0474f3d193d95f062ed33abae2d80/image3.png" />
          </figure>
    <div>
      <h3>Web assets</h3>
      <a href="#web-assets">
        
      </a>
    </div>
    <p>Web assets is a new concept introduced to bridge your business goals with threat detection capabilities. A web asset is any endpoint, file, document, or other related entity that we normally would act on from a security perspective. Within our new web asset page, you will be able to explore all relevant discovered assets by our system.</p><p>With our unified security platform, we are able to rapidly build new <a href="https://blog.cloudflare.com/cloudflare-security-posture-management/#securing-your-web-applications:~:text=Use%2Dcase%20driven%20threat%20detection"><u>use-case driven threat detections</u></a>. For example, to block automated actions across your e-commerce website, you can instruct Cloudflare’s system to block any fraudulent signup attempts, while allowing verified crawlers to index your product pages. This is made possible by labelling your web assets, which, where possible, is automated by Cloudflare, and then using those labels to power threat detections to protect your assets.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/nKFhkuUboScRORcWHgYJR/17d23bb52e532910da6b1cc868bf702e/image9.png" />
          </figure>
    <div>
      <h3>Security rules</h3>
      <a href="#security-rules">
        
      </a>
    </div>
    <p>The unified Security rules interface brings all mitigation rule types — including WAF custom rules, rate limiting rules, API sequence rules, and client side rules — together in one centralized location, eliminating the need to navigate multiple dashboards.</p><p>The new page gives you visibility into how Cloudflare mitigates both incoming traffic and blocks potentially malicious client side resources from loading, making it easier to understand your security posture at a glance. The page allows you to create customised mitigation rules by combining any detection signals, such as Bot Score, Attack Score, or signals from Leaked Credential Checks, enabling precise control over how Cloudflare responds to potential threats.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/63A8aBq9400mKEyHAJGAuk/447447977592218fbaa418b3735754c7/image10.png" />
          </figure>
    <div>
      <h3>Settings</h3>
      <a href="#settings">
        
      </a>
    </div>
    <p>Balancing guidance and flexibility was the key driver for designing the new Settings page. As much as Cloudflare <i>guides</i> you towards the optimal security posture through recommendations and alerts, customers that want the <i>flexibility</i> to proactively adjust these settings can find all of them here.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/pz3N1v2EOCj3V9sKF009F/a106b34e0039bebf6eecdfc5c1244f41/image7.png" />
          </figure>
    <div>
      <h2>Experience it today</h2>
      <a href="#experience-it-today">
        
      </a>
    </div>
    <p>This is the first of many enhancements we plan to make to the Application Security experience in the coming months. To check out the new navigation, log in to the <a href="https://dash.cloudflare.com/"><u>Cloudflare dashboard</u></a>, click on “Security” and choose “Check it out” when you see the message below. You will still have the option of opting out, if you so prefer.</p><div>
  
</div>
<p></p><p>Let us know what you think either by sharing feedback in our <a href="https://community.cloudflare.com/"><u>community forum</u></a> or by providing feedback directly in the dashboard (you will be prompted if you revert to the old design).</p>
    <div>
      <h2>Watch on Cloudflare TV</h2>
      <a href="#watch-on-cloudflare-tv">
        
      </a>
    </div>
    <div>
  
</div><p></p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Application Security]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Bot Management]]></category>
            <guid isPermaLink="false">ktsrG1vJGggZ2JlL4cHxS</guid>
            <dc:creator>Michael Tremante</dc:creator>
            <dc:creator>Pete Thomas</dc:creator>
            <dc:creator>Jessica Tarasoff</dc:creator>
        </item>
        <item>
            <title><![CDATA[Re-introducing the Cloudflare Workers Playground]]></title>
            <link>https://blog.cloudflare.com/workers-playground/</link>
            <pubDate>Thu, 28 Sep 2023 13:00:43 GMT</pubDate>
            <description><![CDATA[ Today, we’re excited to announce an updated Cloudflare Workers playground, where users can develop and test Workers before sharing or deploying them ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Since the very <a href="/introducing-cloudflare-workers/">initial announcement</a> of Cloudflare Workers, we’ve provided a playground. The motivation behind that being a belief that users should have a convenient, low-commitment way to play around with and learn more about Workers.</p><p>Over the last few years, while <a href="https://www.cloudflare.com/developer-platform/workers/">Cloudflare Workers</a> and our <a href="https://www.cloudflare.com/developer-platform/products/">Developer Platform</a> have changed and grown, the original playground has not. Today, we’re proud to announce a revamp of the playground that demonstrates the power of Workers, along with new development tooling, and the ability to share your playground code and deploy instantly to Cloudflare’s global network.</p>
    <div>
      <h3>A focus on origin Workers</h3>
      <a href="#a-focus-on-origin-workers">
        
      </a>
    </div>
    <p>When Workers was first introduced, many of the examples and use-cases centered around middleware, where a Worker intercepts a request to an origin and does something before returning a response. This includes things like: modifying headers, redirecting traffic, helping with A/B testing, or caching. Ultimately the Worker isn’t acting as an origin in these cases, it sits between the user and the destination.</p><p>While Workers are still great for these types of tasks, for the updated playground, we decided to focus on the Worker-as-origin use-case. This is where the Worker receives a request and is responsible for returning the full response. In this case, the Worker is the destination, not middle-ware. This is a great way for you to develop more complex use-cases like user interfaces or APIs.</p>
    <div>
      <h3>A new editor experience</h3>
      <a href="#a-new-editor-experience">
        
      </a>
    </div>
    <p>During Developer Week in May, we <a href="/improved-quick-edit/">announced</a> a new, authenticated dashboard editor experience powered by VSCode. Now, this same experience is available to users in the playground.</p><p>Users now have a more robust IDE experience that supports: multi-module Workers, type-checking via JSDoc comments and the <a href="https://www.npmjs.com/package/@cloudflare/workers-types">`workers-types` package</a>, pretty error pages, and real previews that update as you edit code. The new editor only supports <a href="/workers-javascript-modules/">Module syntax</a>, which is the preferred way for users to develop new Workers.</p><p>When the playground first loads, it looks like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6mfWVX3KmQjEM1YQ7W0sjN/2d0cc6ec11fd81a59ef151a912aa5a2a/image4-18.png" />
            
            </figure><p>The content you see on the right is coming from the code on the left. You can modify this just as you would in a code editor. Once you make an edit, it will be updated shortly on the right as demonstrated below:</p><div>
  
</div>
<p></p><p>You’re not limited to the starter demo. Feel free to edit and remove those files to create APIs, user interfaces, or any other application that you come up with.</p>
    <div>
      <h3>Updated developer tooling</h3>
      <a href="#updated-developer-tooling">
        
      </a>
    </div>
    <p>Along with the updated editor, the new playground also contains numerous developer tools to help give you visibility into the Worker.</p><p>Playground users have access to the same Chrome DevTools technology that we use in the Wrangler CLI and the Dashboard. Within this view, you can: view logs, view network requests, and profile your Worker among other things.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5nlF1OQyvv1NhGcf6cNKZI/c51f5a2d0980f545cc8519d59ae51c03/Screenshot-2023-09-12-at-4.12.10-PM.png" />
            
            </figure><p>At the top of the playground, you’ll also see an “HTTP” tab which you can use to test your Worker against various HTTP methods.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4wjS7nrqnVdcfqVSk7DI0w/9d7b5ad7a29c027ab1b68cb665b073a7/Screenshot-2023-09-12-at-4.08.49-PM.png" />
            
            </figure>
    <div>
      <h3>Share what you create</h3>
      <a href="#share-what-you-create">
        
      </a>
    </div>
    <p>With all these improvements, we haven’t forgotten the core use of a playground—to share Workers with other people! Whatever your use-case; whether you’re building a demo to showcase the power of Workers or sending someone an example of how to fix a specific issue, all you need to do is click “Copy Link” in the top right of the Playground then paste the URL in any URL bar.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6LpxCAHIMkHpuc3UDMcHAJ/019a198ee37f89ab9eb9d3eb0c19a355/Screenshot-2023-09-28-at-13.35.41.png" />
            
            </figure><p>The unique URL will be shareable and deployable as long as you have it. This means that you could create quick demos by creating various Workers in the Playground, and bookmark them to share later. They won’t expire.</p>
    <div>
      <h3>Deploying to the Supercloud</h3>
      <a href="#deploying-to-the-supercloud">
        
      </a>
    </div>
    <p>We also wanted to make it easier to go from writing a Worker in the Playground to deploying that Worker to Cloudflare’s global network. We’ve included a “Deploy” button that will help you quickly deploy the Worker you’ve just created.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6PxsN7ji6lsDeLmbG6fZmV/00ce6d09999333fe2f7321cb61f3d5c9/image5-10.png" />
            
            </figure><p>If you don’t already have a Cloudflare account, you will also be guided through the onboarding process.</p>
    <div>
      <h3>Try it out</h3>
      <a href="#try-it-out">
        
      </a>
    </div>
    <p>This is now available to all users in Region:Earth. Go to <a href="https://workers.cloudflare.com/playground">https://workers.cloudflare.com/playground</a> and give it a go!</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <guid isPermaLink="false">7GiFEdoyaqaiVfqZzzyF6g</guid>
            <dc:creator>Adam Murray</dc:creator>
            <dc:creator>Samuel Macleod</dc:creator>
        </item>
        <item>
            <title><![CDATA[Star your favorite websites in the dashboard]]></title>
            <link>https://blog.cloudflare.com/star-your-favorite-websites-in-the-dashboard/</link>
            <pubDate>Thu, 24 Aug 2023 13:00:37 GMT</pubDate>
            <description><![CDATA[ You can now “star” up to 10 of the websites and applications you have on Cloudflare for quicker access ]]></description>
            <content:encoded><![CDATA[ <p></p><p>We’re excited to introduce <i>starring</i>, a new dashboard feature built to speed up your workflow. You can now “star” up to 10 of the websites and applications you have on Cloudflare for quicker access.</p>
    <div>
      <h2>Star your websites or applications for more efficiency</h2>
      <a href="#star-your-websites-or-applications-for-more-efficiency">
        
      </a>
    </div>
    <p>We have heard from many of our users, particularly ones with tens to hundreds of websites and applications running on Cloudflare, about the need to “favorite” the ones they monitor or configure most often. For example, domains or subdomains that our users designate for development or staging may be accessed in the Cloudflare dashboard daily during a build, migration or a first-time configuration, but then rarely touched for months at a time; yet <i>every</i> time logging in, these users have had to go through multiple steps—searching and paging through results—to navigate to where they need to go. These users seek a more efficient workflow to get to their destination faster. Now, by starring your websites or applications, you can have easier access.</p>
    <div>
      <h2>How to get started</h2>
      <a href="#how-to-get-started">
        
      </a>
    </div>
    
    <div>
      <h3>Star a website or application</h3>
      <a href="#star-a-website-or-application">
        
      </a>
    </div>
    <p>Today, you can star up to 10 items per account. Simply star a website or application you have added to Cloudflare from its Overview page. Once you have starred at least one item, you will then see these marked as “starred” in most places across the dashboard. Just look for the yellow star icon. You can always remove from starred by toggling the button.</p>
    <div>
      <h3>Filter by starred</h3>
      <a href="#filter-by-starred">
        
      </a>
    </div>
    <p>By starring a website or application, you can then filter your lists down to display starred items only. To do so, simply select the “starred” filter from the Home page or the site switcher from the sidebar navigation.</p><div>
  
</div><p>Try it out for yourself—<a href="https://dash.cloudflare.com/?to=/:account/:zone/">log into your account</a> to get started today.</p>
    <div>
      <h2>What’s next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We're very excited to offer this new functionality for better organization of your Cloudflare experience, and about the many possibilities to mature this feature. After trying it out, give us a shout in the <a href="https://community.cloudflare.com/t/community-update-introducing-starred-zones/534673">Cloudflare Community</a> to let us know what improvements you’d like to see come next.</p> ]]></content:encoded>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">7aPSUh1oyTnLF1xuQF28Wc</guid>
            <dc:creator>Emily Flannery</dc:creator>
        </item>
        <item>
            <title><![CDATA[Integrate Cloudflare Zero Trust with Datadog Cloud SIEM]]></title>
            <link>https://blog.cloudflare.com/integrate-cloudflare-zero-trust-with-datadog-cloud-siem/</link>
            <pubDate>Thu, 03 Aug 2023 13:00:33 GMT</pubDate>
            <description><![CDATA[ Today, we are very excited to announce the general availability of Cloudflare Zero Trust Integration with Datadog ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/SCp5IxwJUMOJ6irbWPYHf/4117714bfa2e10409c307dbf48d9e7d2/image5-1.png" />
            
            </figure><p>Cloudflare's Zero Trust platform helps organizations map and adopt a strong security posture. This ranges from Zero Trust Network Access, a Secure Web Gateway to help filter traffic, to Cloud Access Security Broker and Data Loss Prevention to protect data in transit and in the cloud. Customers use Cloudflare to verify, isolate, and inspect all devices managed by IT. Our composable, in-line solutions offer a simplified approach to security and a comprehensive set of logs.</p><p>We’ve heard from many of our customers that they aggregate these logs into Datadog’s Cloud SIEM product. Datadog Cloud SIEM provides threat detection, investigation, and automated response for dynamic, cloud-scale environments. Cloud SIEM analyzes operational and security logs in real time – regardless of volume – while utilizing out-of-the-box integrations and rules to detect threats and investigate them. It also automates response and remediation through out-of-the-box workflow blueprints. Developers, security, and operations teams can also leverage detailed <a href="https://www.cloudflare.com/learning/performance/what-is-observability/">observability</a> data and efficiently collaborate to <a href="https://www.cloudflare.com/learning/security/what-is-siem/">accelerate security investigations</a> in a single, unified platform. We previously had an out-of-the-box dashboard for Cloudflare CDN available on Datadog. These help our customers gain valuable insights into product usage and performance metrics for response times, HTTP status codes, cache hit rate. Customers can collect, visualize, and alert on key Cloudflare metrics.</p><p>Today, we are very excited to announce the general availability of Cloudflare Zero Trust Integration with Datadog. This deeper integration offers the Cloudflare Content Pack within Cloud SIEM which includes out-of-the-box dashboard and detection rules that will help our customers ingesting Zero Trust logs into Datadog, gaining greatly improved security insights over their <a href="https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/">Zero Trust landscape</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1RYHT6tKmiMbXX3IbZ0jff/f507f8781513f3913b5bb73fd044f818/image4.png" />
            
            </figure><blockquote><p>“<i>Our Datadog SIEM integration with Cloudflare delivers a holistic view of activity across Cloudflare Zero Trust integrations–helping security and dev teams quickly identify and respond to anomalous activity across app, device, and users within the Cloudflare Zero Trust ecosystem. The integration offers detection rules that automatically generate signals based on CASB (cloud access security broker) findings, and impossible travel scenarios, a revamped dashboard for easy spotting of anomalies, and accelerates response and remediation to quickly contain an attacker’s activity through an out-of-the-box workflow automation blueprints.</i>”- <b>Yash Kumar,</b> Senior Director of Product, Datadog</p></blockquote>
    <div>
      <h2>How to get started</h2>
      <a href="#how-to-get-started">
        
      </a>
    </div>
    
    <div>
      <h3>Set up Logpush jobs to your Datadog destination</h3>
      <a href="#set-up-logpush-jobs-to-your-datadog-destination">
        
      </a>
    </div>
    <p>Use the Cloudflare dashboard or API to <a href="https://developers.cloudflare.com/logs/get-started/enable-destinations/datadog/">create a Logpush job</a> with all fields enabled for each dataset you’d like to ingest on Datadog. We have eight account-scoped datasets available to use today (Access Requests, Audit logs, CASB findings, Gateway logs including DNS, Network, HTTP; Zero Trust Session Logs) that can be ingested into Datadog.</p>
    <div>
      <h3>Install the Cloudflare Tile in Datadog</h3>
      <a href="#install-the-cloudflare-tile-in-datadog">
        
      </a>
    </div>
    <p>In your Datadog dashboard, locate and install the Cloudflare Tile within the Datadog Integration catalog. At this stage, Datadog’s out-of-the-box log processing <a href="https://docs.datadoghq.com/logs/log_configuration/pipelines/?tab=source">pipeline</a> will automatically parse and normalize your Cloudflare Zero Trust logs.</p>
    <div>
      <h3>Analyze and correlate your Zero Trust logs with Datadog Cloud SIEM's out-of-the-box content</h3>
      <a href="#analyze-and-correlate-your-zero-trust-logs-with-datadog-cloud-siems-out-of-the-box-content">
        
      </a>
    </div>
    <p>Our new and improved integration with Datadog enables security teams to quickly and easily monitor their Zero Trust components with the Cloudflare Content Pack. This includes the out-of-the-box dashboard that now features a Zero Trust section highlighting various widgets about activity across the applications, devices, and users in your Cloudflare Zero Trust ecosystem. This section gives you a holistic view, helping you spot and respond to anomalies quickly.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4ufPwaIiXySgUYcLsvXbiz/131481c545a01474ea1f26f50308ccf3/image1-2.png" />
            
            </figure>
    <div>
      <h3>Security detections built for CASB</h3>
      <a href="#security-detections-built-for-casb">
        
      </a>
    </div>
    <p>As Enterprises use more SaaS applications, it becomes more critical to have insights and control for data at-rest. Cloudflare CASB findings do just that by providing security risk insights for all integrated SaaS applications.</p><p>With this new integration, Datadog now offers an out-of-the-box detection rule that detects any CASB findings. The alert is triggered at different severity levels for any CASB security finding that could indicate suspicious activity within an integrated SaaS app, like Microsoft 365 and Google Workspace. In the example below, the CASB finding points to an asset whose Google Workspace Domain Record is missing.</p><p>This detection is helpful in identifying and remedying misconfigurations or any security issues saving time and reducing the possibility of security breaches.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5NlUJLmZa43B1LqkTKmdMc/75e15e8a2d66ce46093e5198a6450d94/image2.png" />
            
            </figure>
    <div>
      <h3>Security detections for Impossible Travel</h3>
      <a href="#security-detections-for-impossible-travel">
        
      </a>
    </div>
    <p>One of the most common security issues can show up in surprisingly simple ways. For example, could be a user that seemingly logs in from one location only to login shortly after from a location physically too far away. Datadog’s new detection rule addresses exactly this scenario with their <a href="https://docs.datadoghq.com/security/default_rules/cloudflare-impossible-travel">Impossible Travel detection rule</a>. If Datadog Cloud SIEM determines that two consecutive loglines for a user indicate impossible travel of more than 500 km at over 1,000 km/h, the security alert is triggered. An admin can then determine if it is a security breach and take actions accordingly.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/56UXWQZRCjTg0y0PThuDf9/b033359bf8872fc79a8eb0015fbb8416/image3.png" />
            
            </figure>
    <div>
      <h2>What’s next</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Customers of Cloudflare and Datadog can now gain a more comprehensive view of their products and security posture with the enhanced dashboards and the new detection rules. We are excited to work on adding more value for our customers and develop unique detection rules.</p><p>If you are a Cloudflare customer using Datadog, explore the new integration starting <a href="https://docs.datadoghq.com/integrations/cloudflare/">today</a>.</p> ]]></content:encoded>
            <category><![CDATA[Logs]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Connectivity Cloud]]></category>
            <guid isPermaLink="false">45DTnvaKqyVXbmubrmQxLM</guid>
            <dc:creator>Mythili Prabhu</dc:creator>
            <dc:creator>Nimisha Saxena (Guest Author)</dc:creator>
        </item>
        <item>
            <title><![CDATA[Benchmarking dashboard performance]]></title>
            <link>https://blog.cloudflare.com/benchmarking-dashboard-performance/</link>
            <pubDate>Thu, 22 Jun 2023 13:00:14 GMT</pubDate>
            <description><![CDATA[ The Cloudflare dashboard is a single page application that houses all of the UI for our wide portfolio of existing products, as well as the new features we're releasing every day ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/44ansoGqDDwcfM1mZ3ro8g/e92d6a3a59b76677639aff889a4316d6/image3-23.png" />
            
            </figure><p>In preparation of Cloudflare Speed Week 2023, we spent the last few weeks benchmarking the performance of a Cloudflare product that has gone through many transformations throughout the years: the Cloudflare dashboard itself!</p>
    <div>
      <h2>Limitations and scope</h2>
      <a href="#limitations-and-scope">
        
      </a>
    </div>
    <p>Optimizing for user-experience is vital to the long-term success of both Cloudflare and our customers. Reliability and availability of the dashboard are also important, since millions of customers depend on our <a href="https://www.cloudflare.com/application-services/">services</a> every day. To avoid any potential service interruptions while we made changes to the application’s architecture, we decided to gradually roll out the improvements, starting with the login page.</p><p>As a global company, we strive to deliver the best experience to all of our customers around the world. While we were aware that performance was regional, with regions furthest from our core data centers experiencing up to 10 times longer loading speeds, we wanted to focus on improvements that would benefit all of our users, no matter where they geographically connect to the Dashboard.</p><p>Finally, throughout this exercise, it was important to keep in mind that our overall goal was to improve the user experience of the dashboard, with regards to loading performance. We chose to use a Lighthouse Performance score as a metric to measure performance, but we were careful to not set a target score. <i>Once a measure becomes a target, it ceases to be a good measure.</i></p>
    <div>
      <h2>Initial Benchmarks</h2>
      <a href="#initial-benchmarks">
        
      </a>
    </div>
    <p>Using a combination of open-source tools offered by Google (Lighthouse and PageSpeed Insights) and our own homegrown solution (<a href="https://developers.cloudflare.com/fundamentals/speed/speed-test/run-speed-test/">Cloudflare Speed Test</a>), we benchmarked our Lighthouse performance scores starting in Q1 2023. We found the results were… somewhat disappointing:</p><ul><li><p>Although the site’s initial render occurred quickly (200ms), it took more than two seconds for the site to finish loading and be fully interactive.</p></li><li><p>In that time, the page was blocked for more than 500ms while the browser executed long JavaScript tasks.</p></li><li><p>Over half of the JavaScript served for the login page was not necessary to render the login page itself.</p></li></ul>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/UM5Rox5ylKtIS65PrMMZS/74445bc25635e7a59159802addebb55d/image4-20.png" />
            
            </figure>
    <div>
      <h2>Improving what we've measured</h2>
      <a href="#improving-what-weve-measured">
        
      </a>
    </div>
    <p>The Cloudflare dashboard is a single page application that houses all of the UI for our wide portfolio of existing products, as well as the new features we're releasing every day. However, a less-than-performant experience is not acceptable to us; we owe it to our customers to deliver the best performance possible.</p><p>So what did we do?</p>
    <div>
      <h3>Shipped less JavaScript</h3>
      <a href="#shipped-less-javascript">
        
      </a>
    </div>
    <p>As obvious as it sounds, shipping less code to the user means they have to download fewer resources to load the application. In practice however, accomplishing this was harder than expected, especially for a five year old monolithic application.</p><p>We identified some of our largest dependencies with multiple versions, like <a href="https://lodash.com/">lodash</a> and our icon library, and deduped them. Bloated packages like the datacenter colo catalogs were refactored and drastically slimmed down. Packages containing unused code like development-only components, deprecated translations, and old Cloudflare Access UI components were removed entirely.</p><p>The result was a reduction in total assets being served to the user, going from 10MB (2.7MB gzipped) to 6.5MB (1.7MB gzipped). Lighthouse performance score improved to about 70. This was a good first step, but we could do better.</p>
    <div>
      <h3>Identified and code split top-level boundaries</h3>
      <a href="#identified-and-code-split-top-level-boundaries">
        
      </a>
    </div>
    <p>Code splitting is the process in which the application code is split into multiple bundles to be loaded on demand, reducing the initial amount of JavaScript a user downloads on page load. After logging in, as users navigate from account-level products like Workers and Pages, and then into specific zone-level products, like Page Shield for their domain, only the code necessary to render that particular page gets loaded dynamically.</p><p>Although most of the account-level and zone-level pages of the dashboard were properly code-split, the root application that imported these pages was not. It contained all of the code to bootstrap the application for both authenticated and unauthenticated users. This wasn’t a great experience for users who weren't even logged in yet, and we wanted to allow them to get into the main dashboard as quickly as possible.</p><p>So we split our monolithic application into two sub-applications: an authenticated and unauthenticated application. At a high level, on entrypoint initialization, we simply make an API request to check the user’s authentication state and dynamically load one sub-application or the other.</p>
            <pre><code>import React from 'react';
import { useAuth } from './useAuth';
const AuthenticatedAppLoadable = React.lazy(
  () =&gt; import('./AuthenticatedApp')
);
const UnauthenticatedAppLoadable = React.lazy(
  () =&gt; import('./UnauthenticatedApp')
);

// Fetch user auth state here and return user if logged in
// Render AuthenticatedApp or UnauthenticatedApp based on user
const Root: React.FC = () =&gt; {
  const { user } = useAuth();
  return user ? &lt;AuthenticatedAppLoadable /&gt; : &lt;UnauthenticatedAppLoadable /&gt;;
};</code></pre>
            <p>That’s it! If a user is not logged in, we ship them a small bundle that only contains code necessary to render parts of the application related to login and signup, as well as a few global components. Code related to billing, account-level and zone-level products, sidebar navigation, and user profile settings are all bundled into a separate sub-application that only gets loaded once a user logs in.</p><p>Again, we saw significant improvements, especially to Largest Contentful Paint, pushing our performance scores to about 80. However, we ran a Chrome performance profile, and on closer inspection of the longest blocking task we noticed that there was still unnecessary code being parsed and evaluated, even though we never used it. For example, code for sidebar navigation was still loaded for unauthenticated users who never actually saw that component.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3HnLb91LW1xlCO1kOru7qW/7dbef6daea7ec7931c5e0fb2a4280315/image5-14.png" />
            
            </figure>
    <div>
      <h3>Optimized dead-code elimination</h3>
      <a href="#optimized-dead-code-elimination">
        
      </a>
    </div>
    <p>It turned out that our configuration for dead-code elimination was not optimized. Dead-code elimination, or “tree-shaking”, is the process in which your JavaScript transpiler automatically removes unused module imports from the final bundle. Although most modern transpilers have that setting on by default today, optimizing dead-code elimination for an existing application as old as the Cloudflare dashboard is not as straightforward.</p><p>We had to go through each individual JavaScript import to identify modules that didn’t produce side-effects so they could be marked by the transpiler to be removed. We were able to optimize “tree-shaking” for the majority of the modules, but this will be an ongoing process as we make more performance improvements.</p>
    <div>
      <h2>Key results</h2>
      <a href="#key-results">
        
      </a>
    </div>
    <p>Although the performance of the dashboard is not yet where we want it to be, we were still able to roll out significant improvements for the majority of our users. The table below shows the performance benchmarks for US users hitting the login page for the first time before and after the performance improvements.</p><p><b>Desktop</b></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5Cap3HZTG2U3dIoVetsjfy/5d0ae42ee1d6f99176baece5d75a5d0c/image1-33.png" />
            
            </figure><p><b>Mobile</b></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/64faYhLqXkTM7PGUxYbRi/05e975135092163f8a5ee3a685731d01/image2-31.png" />
            
            </figure>
    <div>
      <h2>What’s next</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Overall, we were able to get some quick wins, but we’re still not done! This is just the first step in our mission to continually improve performance for all of our dashboard users. Here’s a look at some next steps that we will be experimenting with and testing in the coming months: decoupling signup pages from the main application, redesigning SSO login experience, exploring microfrontends and edge-side rendering.</p><p>In the meantime, check out <a href="https://developers.cloudflare.com/fundamentals/speed/speed-test/run-speed-test/">Cloudflare Speed Test</a> to generate a performance report and receive recommendations on how to improve the performance of your site <a href="/cloudflare-observatory-generally-available">today</a>.</p> ]]></content:encoded>
            <category><![CDATA[Speed Week]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Speed]]></category>
            <guid isPermaLink="false">3lIqDgis5xDxQZyNPv6ejX</guid>
            <dc:creator>Richard Nguyen</dc:creator>
            <dc:creator>Zac Arellano</dc:creator>
        </item>
        <item>
            <title><![CDATA[Protect your domain with Zone Holds]]></title>
            <link>https://blog.cloudflare.com/protect-your-domain-with-zone-holds/</link>
            <pubDate>Thu, 06 Apr 2023 16:00:00 GMT</pubDate>
            <description><![CDATA[ Protect against accidental additions of your domain, subdomain, or custom hostnames in other accounts with Zone Holds. Available by default for all enterprise customers ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/473c1btS6iVaePEPi8kIwW/a409b87106e4a2d6d2143704514c221c/Protect-your-domain-with-Zone-Holds-1.png" />
            
            </figure><p>Today, we are announcing Zone Holds, a new capability for enterprise customers that gives them control of if and when someone else can add the same zone to another Cloudflare account. When multiple teams at a company want to use Cloudflare, one team might accidentally step on another’s toes and try to manage the same zone in two accounts. Zone Holds ensure that this cannot happen by enforcing that only one account can contain a given domain, optionally inclusive of subdomains or custom hostnames, unless explicit permission is granted by the account owner of the zone.</p>
    <div>
      <h3>What can go wrong today</h3>
      <a href="#what-can-go-wrong-today">
        
      </a>
    </div>
    <p>Cloudflare already requires zones to be authenticated via DNS before traffic is proxied through our global network. This ensures that only domain owners can authorize traffic to be sent through and controlled with Cloudflare. However, many of our customers are large organizations with many teams all trying to protect and accelerate their web properties. In these cases, one team may not realize that a given domain is already being <a href="https://www.cloudflare.com/application-services/solutions/domain-protection-services/">protected with Cloudflare</a>. If they activate a second instance of the same domain in Cloudflare, they end up replacing the original zone that another team was already managing with Cloudflare. This can create downtime or security issues until the original zone can be re-activated. If these two teams had only known about each other and communicated, then in most cases any issue could be avoided via one of many options - subdomains, custom hostnames, etc. How can we ensure that these teams are aware of potential risk before making these mistakes?</p>
    <div>
      <h3>How Zone Holds protect customers</h3>
      <a href="#how-zone-holds-protect-customers">
        
      </a>
    </div>
    <p>With Zone Holds, any attempt to add a domain that is being held will return an error letting the person know that they need to contact the domain owner first. Zone Holds are enabled by default for all enterprise zones. The holds can be managed from the Zone Overview screen. Optionally, the hold can be extended to apply to subdomains and custom hostnames. When disabling a hold, you can set the hold to re-enable after a set amount of time. This ensures you don’t accidentally leave a hold perpetually disabled. Let’s dig into an example to understand how Zone Holds help customers.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/53LWcBYYwA88TNpSzqAsrp/125314c04d1e876edf2e6d3530b4b8ef/image2-5.png" />
            
            </figure><p>An active zone hold not including protection of subdomains</p>
    <div>
      <h3>Example Corp - before Zone Holds</h3>
      <a href="#example-corp-before-zone-holds">
        
      </a>
    </div>
    <p>Example Corp is a large Cloudflare customer. Specifically, their infrastructure team uses Cloudflare to protect all traffic at example.com. This includes their marketing site at <a href="http://www.example.com">www.example.com</a> and their customer facing API at api.example.com. When they onboarded to Cloudflare they had their IT department, who manages all DNS at the company, setup DNS records at their <a href="https://www.cloudflare.com/learning/dns/glossary/what-is-a-domain-name-registrar/">registrar</a> such that all traffic for example.com routed through Cloudflare.</p><p>Fast forward a year later, their marketing department wants to adopt Cloudflare’s <a href="https://developers.cloudflare.com/bots/">Bot Management solution</a> for traffic on <a href="http://www.example.com">www.example.com</a>. They sign up example.com and reach out to their IT department to set the provided NS records at the registrar. The IT department does not realize that Cloudflare is already in use so they do not catch that this will impact the existing zone managed by the infrastructure team. The new zone is activated and an incident occurs because traffic to not only <a href="http://www.example.com">www.example.com</a> but also api.example.com is impacted. With Zone Holds this incident would have been avoided. Let’s see how.</p>
    <div>
      <h3>Example Corp - now with Zone Holds</h3>
      <a href="#example-corp-now-with-zone-holds">
        
      </a>
    </div>
    <p>Example Corp signs up for Cloudflare and adds example.com to their account as an ENT zone. Automatically a Zone Hold is enabled on the domain which will prevent any other Cloudflare account from adding example.com. They also enable a hold on any subdomains or custom hostnames under the domain of example.com.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5vOx5b4qJtcGshW7ZuLVOk/c3bf36c35bde72044367a3a484f448e2/image3-3.png" />
            
            </figure><p>Later ACME’s marketing department wants to start using Cloudflare for <a href="http://www.example.com">www.example.com</a>. When they attempt to add that domain to Cloudflare they get an error informing them that they need to reach out to the domain owner.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1zs5qEaFPmWuyyXoMQEx1j/0b2d4cac2f0ee8ed6353225bec8b17fb/image4-3.png" />
            
            </figure><p>ACME’s marketing department reaches out internally and learns that the infrastructure team manages this domain and that activating this zone would have caused an incident! Instead, both teams decide that the marketing team should add the subdomain of <a href="http://www.example.com">www.example.com</a> so they can control the marketing site. The infrastructure team lifts the subdomain hold on acme.com and the marketing team adds <a href="http://www.example.com">www.example.com</a> to their own account.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2fWD0fdAJzRFIVWweFvBsb/d999ee91da29e18410bbf04af30034f8/image1-7.png" />
            
            </figure><p>Once set up and activated they can now begin to leverage bot management to protect their marketing site and no unexpected impact occurs.</p>
    <div>
      <h3>Getting started with Zone Holds</h3>
      <a href="#getting-started-with-zone-holds">
        
      </a>
    </div>
    <p>Zone Holds are now available to all enterprise zones and are enabled by default at the domain level. You can manage Zone Holds from the Zone Overview screen of any enterprise zone. Optionally, the hold can be extended to apply to subdomains and custom hostnames. When disabling a hold, you can set the hold to re-enable after a set amount of time. This ensures you don’t accidentally leave a hold perpetually disabled.</p> ]]></content:encoded>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">41MXsIADru3HtjvPvsqN0i</guid>
            <dc:creator>Garrett Galow</dc:creator>
        </item>
        <item>
            <title><![CDATA[Account Security Analytics and Events: better visibility over all domains]]></title>
            <link>https://blog.cloudflare.com/account-security-analytics-and-events/</link>
            <pubDate>Sat, 18 Mar 2023 17:00:00 GMT</pubDate>
            <description><![CDATA[ Revealing Account Security Analytics and Events, new eyes on your account in Cloudflare dashboard to give holistic visibility. No matter how many zones you manage, they are all there! ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/hkEsUWDVJmPQ7DAieHQCS/6571ab358294597bd14e95b5f1feb5ed/Account-level-Security-Analytics-and-Security-Events_-better-visibility-and-control-over-all-account-zones-at-once.png" />
            
            </figure><p>Cloudflare offers many security features like <a href="https://developers.cloudflare.com/waf/">WAF</a>, <a href="https://developers.cloudflare.com/bots/">Bot management</a>, <a href="https://developers.cloudflare.com/ddos-protection/">DDoS</a>, <a href="https://developers.cloudflare.com/cloudflare-one/">Zero Trust</a>, and more! This suite of products are offered in the form of rules to give basic protection against common vulnerability attacks. These rules are usually configured and monitored per domain, which is very simple when we talk about one, two, maybe three domains (or what we call in Cloudflare’s terms, “zones”).</p>
    <div>
      <h3>The zone-level overview sometimes is not time efficient</h3>
      <a href="#the-zone-level-overview-sometimes-is-not-time-efficient">
        
      </a>
    </div>
    <p>If you’re a Cloudflare customer with tens, hundreds, or even thousands of domains under your control, you’d spend hours going through these domains one by one, monitoring and configuring all security features. We know that’s a pain, especially for our Enterprise customers. That’s why last September we announced the <a href="/account-waf/">Account WAF</a>, where you can create one security rule and have it applied to the configuration of all your zones at once!</p><p>Account WAF makes it easy to deploy security configurations. Following the same philosophy, we want to empower our customers by providing visibility over these configurations, or even better, visibility on all HTTP traffic.</p><p>Today, Cloudflare is offering holistic views on the security suite by launching Account Security Analytics and Account Security Events. Now, across all your domains, you can monitor traffic, get insights quicker, and save hours of your time.</p>
    <div>
      <h3>How do customers get visibility over security traffic today?</h3>
      <a href="#how-do-customers-get-visibility-over-security-traffic-today">
        
      </a>
    </div>
    <p>Before today, to view account analytics or events, customers either used to access each zone individually to check the events and analytics dashboards, or used zone <a href="https://developers.cloudflare.com/analytics/graphql-api/">GraphQL Analytics API</a> or logs to collect data and send them to their preferred storage provider where they could collect, aggregate, and plot graphs to get insights for all zones under their account — in case ready-made dashboards were not provided.</p>
    <div>
      <h3>Introducing Account Security Analytics and Events</h3>
      <a href="#introducing-account-security-analytics-and-events">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6gWJhl65y6sUNRHNaZjwqt/d2a107ab79c0a3da65c4721a1b48fa74/Screenshot-2023-03-17-at-9.57.13-AM.png" />
            
            </figure><p>The new views are security focused, data-driven dashboards — similar to zone-level views, both have  similar data like: sampled logs and the top filters over many source dimensions (for example, IP addresses, Host, Country, ASN, etc.).</p><p>The main difference between them is that Account Security Events focuses on the current configurations on every zone you have, which makes reviewing mitigated requests (rule matches) easy. This step is essential in distinguishing between actual threats from false positives, along with maintaining optimal security configuration.</p><p>Part of the Security Events power is showing Events “by service” listing the security-related activity per security feature (for example, <a href="https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/">WAF</a>, Firewall Rules, API Shield) and Events “by Action” (for example, allow, block, challenge).</p><p>On the other hand, Account Security Analytics view shows a wider angle with all HTTP traffic on all zones under the account, whether this traffic is mitigated, i.e., the security configurations took an action to prevent the request from reaching your zone, or not mitigated. This is essential in fine-tuning your security configuration, finding possible false negatives, or onboarding new zones.</p><p>The view also provides quick filters or insights of what we think are interesting cases worth exploring for ease of use. Many of the view components are similar to zone level <a href="/security-analytics/">Security Analytics</a> that we introduced recently.</p><p>To get to know the components and how they interact, let’s have a look at an actual example.</p>
    <div>
      <h3>Analytics walk-through when investigating a spike in traffic</h3>
      <a href="#analytics-walk-through-when-investigating-a-spike-in-traffic">
        
      </a>
    </div>
    <p>Traffic spikes happen to many customers’ accounts; to investigate the reason behind them, and check what’s missing from the configurations, we recommend starting from Analytics as it shows mitigated and non-mitigated traffic, and to revise the mitigated requests to double check any false positives then Security Events is the go to place. That’s what we’ll do in this walk-through starting with the Analytics, finding a spike, and checking if we need further mitigation action.</p><p><b>Step 1:</b> To navigate to the new views, sign into the Cloudflare dashboard and select the account you want to monitor. You will find <b>Security Analytics</b> and <b>Security Events</b> in the sidebar under <b>Security Center.</b></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6GQ2Z3yAa1OehelJegPHZU/ffc7db3bde4a6976ed94e6eab597458c/pasted-image-0--8--2.png" />
            
            </figure><p><b>Step 2:</b> In the Analytics dashboard, if you had a big spike in the traffic compared to the usual, there’s a big chance it's a layer 7 DDoS attack. Once you spot one, zoom into the time interval in the graph.</p><div></div>
<i>Zooming into a traffic spike on the timeseries scale</i><br /><p>By Expanding the top-Ns on top of the analytics page we can see here many observations:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5XDngTA5PHz7hc0O8f7RJ8/5bfe5659e3eafa42689d998f2de886a3/pasted-image-0--9--1.png" />
            
            </figure><p>We can confirm it’s a DDoS attack as the peak of traffic does not come from one single IP address, It’s distributed over multiple source IPs. The “edge status code” indicates that there’s a rate limiting rule applied on this attack and it’s a GET method over HTTP/2.</p><p>Looking at the right hand side of the analytics we can see “Attack Analysis” indicating that these requests were clean from <a href="https://www.cloudflare.com/learning/security/how-to-prevent-xss-attacks/">XSS</a>, SQLi, and common RCE attacks. The Bot Analysis indicates it’s an automated traffic in the Bot Scores distribution; these two products add another layer of intelligence to the investigation process. We can easily deduce here that the attacker is sending clean requests through high volumetric attack from multiple IPs to take the web application down.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3mBN0yDIQo4aK0HAXCO5Yb/98fe973514f449147b3171e579c2dbce/pasted-image-0--10--1.png" />
            
            </figure><p><b>Step 3:</b> For this attack we can see we have rules in place to mitigate it, with the visibility we get the freedom to fine tune our configurations to have better security posture, if needed. we can filter on this attack fingerprint, for instance: add a filter on the referer `<a href="http://www.example.com`">www.example.com`</a> which is receiving big bulk of the attack requests, add filter on path equals `/`, HTTP method, query string, and a filter on the automated traffic with Bot score, we will see the following:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6bI1AAaTSFbA7nPxvx4lZn/2f8197708c7dc3ac8d842ff2c003b4eb/pasted-image-0--11-.png" />
            
            </figure><p><b>Step 4:</b> Jumping to Security Events to zoom in on our mitigation actions in this case, spike fingerprint is mitigated using two actions: Managed Challenge and Block.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6JuvFbzYoI01oHDIrCh7ze/3e21d9d444699434a28e25eea8422423/pasted-image-0--12-.png" />
            
            </figure><p>The mitigation happened on: Firewall rules and DDoS configurations, the exact rules are shown in the top events.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/20ANCsBgB0TowOniXpMl0E/1e4445f96e05af157c3174314422513b/pasted-image-0--13-.png" />
            
            </figure>
    <div>
      <h3>Who gets the new views?</h3>
      <a href="#who-gets-the-new-views">
        
      </a>
    </div>
    <p>Starting this week all our customers on Enterprise plans will have access to Account Security Analytics and Security Events. We recommend having Account Bot Management, WAF Attack Score, and Account WAF to have access to the full visibility and actions.</p>
    <div>
      <h3>What’s next?</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>The new Account Security Analytics and Events encompass metadata generated by the Cloudflare network for all domains in one place. In the upcoming period we will be providing a better experience to save our customers' time in a simple way. We're currently in beta, log into the dashboard, check out the views, and let us know your feedback.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Analytics]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">7lBffZk4kfTbrZ48l1NMo8</guid>
            <dc:creator>Radwa Radwan</dc:creator>
            <dc:creator>Zhiyuan Zheng</dc:creator>
            <dc:creator>Nick Downie</dc:creator>
        </item>
        <item>
            <title><![CDATA[Adding Zero Trust signals to Sumo Logic for better security insights]]></title>
            <link>https://blog.cloudflare.com/zero-trust-signals-to-sumo-logic/</link>
            <pubDate>Tue, 14 Mar 2023 13:00:00 GMT</pubDate>
            <description><![CDATA[ The Cloudflare App for Sumo Logic now supports Zero Trust logs for out of the box, ready-made security dashboards ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3hVaAd6pJq09fsIs5GU53e/9b7d0ab2abdc7dcb528072566797c9ab/Dashboard_-Quick-Navigation-1.png" />
            
            </figure><p>A picture is worth a thousand words and the same is true when it comes to getting visualizations, trends, and data in the form of a ready-made security dashboard.</p><p>Today we’re excited to announce the expansion of support for automated normalization and correlation of Zero Trust logs for <a href="https://developers.cloudflare.com/logs/about/">Logpush</a> in Sumo Logic’s <a href="https://www.sumologic.com/solutions/cloud-siem-enterprise/">Cloud SIEM</a>. As a Cloudflare <a href="https://www.cloudflare.com/partners/technology-partners/sumo-logic/">technology partner</a>, Sumo Logic is the pioneer in continuous intelligence, a new category of software which enables organizations of all sizes to address the data challenges and opportunities presented by digital transformation, modern applications, and cloud computing.</p><p>The updated content in Sumo Logic Cloud SIEM helps joint Cloudflare customers reduce alert fatigue tied to Zero Trust logs and accelerates the triage process for security analysts by converging security and network data into high-fidelity insights. This new functionality complements the existing <a href="https://www.sumologic.com/application/cloudflare/">Cloudflare App for Sumo Logic</a> designed to help IT and security teams gain insights, understand anomalous activity, and better trend security and network performance data over time.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4v27Z4MHNSnxP9M0Rs8F75/f0ebc2440edf9807d87a0081777f9463/Cloud-SIEM-HUD.png" />
            
            </figure>
    <div>
      <h3>Deeper integration to deliver Zero Trust insights</h3>
      <a href="#deeper-integration-to-deliver-zero-trust-insights">
        
      </a>
    </div>
    <p>Using Cloudflare Zero Trust helps protect users, devices, and data, and in the process can create a large volume of logs. These logs are helpful and important because they provide the who, what, when, and where for activity happening within and across an organization. They contain <a href="https://www.cloudflare.com/learning/security/what-is-siem/">information</a> such as what website was accessed, who signed in to an application, or what data may have been shared from a SaaS service.</p><p>Up until now, our integrations with Sumo Logic only allowed automated correlation of security signals for Cloudflare only included core services. While it’s critical to ensure collection of <a href="https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/">WAF</a> and bot detection events across your fabric, extended visibility into <a href="https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/">Zero Trust components</a> has now become more important than ever with the explosion of distributed work and adoption of hybrid and multi-cloud infrastructure architectures.</p><p>With the expanded Zero Trust logs now available in Sumo Logic Cloud SIEM, customers can now get deeper context into security insights thanks to the broad set of network and security logs produced by Cloudflare products:</p><ul><li><p><a href="https://www.cloudflare.com/products/zero-trust/gateway/">Cloudflare Gateway</a> (Network, DNS, HTTP)</p></li><li><p><a href="https://www.cloudflare.com/products/zero-trust/browser-isolation/">Cloudflare Remote Browser Isolation</a> (included with Gateway logs)</p></li><li><p><a href="https://www.cloudflare.com/products/zero-trust/dlp/">Cloudflare Data Loss Prevention</a> (included with Gateway logs)</p></li><li><p><a href="https://www.cloudflare.com/products/zero-trust/access/">Cloudflare Access</a> (Access audit logs)</p></li><li><p><a href="https://www.cloudflare.com/products/zero-trust/casb/">Cloudflare Cloud Access Security Broker</a> (Findings logs)</p></li></ul><blockquote><p>“As a long time Cloudflare partner, we’ve worked together to help joint customers analyze events and trends from their websites and applications to provide end-to-end visibility and improve digital experiences. We’re excited to expand this partnership to provide real-time insights into the Zero Trust security posture of mutual customers in Sumo Logic’s Cloud SIEM.”- <b>John Coyle</b> - Vice President of Business Development, Sumo Logic</p></blockquote>
    <div>
      <h3>How to get started</h3>
      <a href="#how-to-get-started">
        
      </a>
    </div>
    <p>To take advantage of the suite of integrations available for Sumo Logic and Cloudflare logs available via Logpush, first enable Logpush to Sumo Logic, which will ship logs directly to Sumo Logic’s cloud-native platform. Then, install the Cloudflare App and (for Cloud SIEM customers) enable forwarding of these logs to Cloud SIEM for automated normalization and correlation of security insights.</p><p>Note that Cloudflare’s Logpush service is only available to Enterprise customers. If you are interested in upgrading, <a href="https://www.cloudflare.com/lp/cio-week-2023-cloudflare-one-contact-us/">please contact us here</a>.</p><ol><li><p><a href="https://developers.cloudflare.com/logs/get-started/enable-destinations/sumo-logic/"><b>Enable Logpush to Sumo Logic</b></a>Cloudflare Logpush supports pushing logs directly to Sumo Logic via the Cloudflare dashboard or via API.</p></li><li><p><b>Install the </b><a href="https://www.sumologic.com/application/cloudflare/"><b>Cloudflare App for Sumo Logic</b></a>Locate and install the Cloudflare app from the App Catalog, linked above. If you want to see a preview of the dashboards included with the app before installing, click Preview Dashboards. Once installed, you can now view key information in the Cloudflare Dashboards for all core services.</p></li><li><p><b>(Cloud SIEM Customers) Forward logs to Cloud SIEM</b>After the steps above, enable the updated parser for Cloudflare logs by <a href="https://help.sumologic.com/docs/integrations/saas-cloud/cloudflare/#prerequisites">adding the _parser field</a> to your S3 source created when installing the Cloudflare App.</p></li></ol>
    <div>
      <h3>What’s next</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>As more organizations move towards a Zero Trust model for security, it's increasingly important to have visibility into every aspect of the network with logs playing a crucial role in this effort.</p><p>If your organization is just getting started and not already using a tool like Sumo Logic, <a href="/announcing-logs-engine/">Cloudflare R2 for log storage</a> is worth considering. <a href="#">Cloudflare R2</a> offers a scalable, cost-effective solution for log storage.</p><p>We’re excited to continue closely working with technology partners to expand existing and create new integrations that help customers on their Zero Trust journey.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Logs]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Sumo Logic]]></category>
            <category><![CDATA[Guest Post]]></category>
            <guid isPermaLink="false">1LqRHHF3LAkWnMU7gmt639</guid>
            <dc:creator>Corey Mahan</dc:creator>
            <dc:creator>Drew Horn (Guest Author)</dc:creator>
        </item>
        <item>
            <title><![CDATA[New Zero Trust navigation coming soon (and we need your feedback)]]></title>
            <link>https://blog.cloudflare.com/zero-trust-navigation/</link>
            <pubDate>Tue, 07 Mar 2023 17:33:02 GMT</pubDate>
            <description><![CDATA[ The Zero Trust dashboard navigation will be getting a visual refresh on March 20, 2023.
 ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4AKiRUBdyzAeGHX05C0rG9/8851eae62bd0d95c0548bdca162cc533/pasted-image-0.png" />
            
            </figure>
    <div>
      <h2>We’re updating the Zero Trust navigation</h2>
      <a href="#were-updating-the-zero-trust-navigation">
        
      </a>
    </div>
    <p>On March 20, 2023, we will be launching an updated navigation in the Zero Trust dashboard, offering all of our Zero Trust users a more seamless experience across Cloudflare as a whole. This change will allow you to more easily manage your <a href="https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/">Zero Trust organization</a> alongside your application and network services, developer tools, and more.</p><p>As part of this upcoming release, you will see three key changes:</p>
    <div>
      <h3>Quicker navigation</h3>
      <a href="#quicker-navigation">
        
      </a>
    </div>
    <p>Instead of opening another window or typing in a URL, you can go back to the Cloudflare dashboard in one click.</p><div></div>
<p></p>
    <div>
      <h3>Switch accounts with ease</h3>
      <a href="#switch-accounts-with-ease">
        
      </a>
    </div>
    <p>View and switch accounts at the top of your sidebar.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/13iG3vX7nTkKdEzYa30WrT/231fd3162903b52b9eb69890daae6d7e/Screenshot-2023-03-06-at-3.49.53-PM.png" />
            
            </figure>
    <div>
      <h3>Resources and support</h3>
      <a href="#resources-and-support">
        
      </a>
    </div>
    <p>Find helpful links to our Community, developer documentation, and support team at the top of your navigation bar.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ysqKoX5yuL9gw3yGuVjGN/beeb360a966b35e5061ba0f04ff3f90f/Screenshot-2023-03-06-at-3.52.10-PM.png" />
            
            </figure>
    <div>
      <h2>Why we’re updating the Zero Trust navigation</h2>
      <a href="#why-were-updating-the-zero-trust-navigation">
        
      </a>
    </div>
    <p>In 2020, Gateway was broadly released as the first Cloudflare product that didn’t require a site hosted on Cloudflare’s infrastructure. In other words, Gateway was unconstrained by the site-specific model most other Cloudflare products relied on at the time, while also used in close conjunction with Access. And so, the <i>Cloudflare for Teams</i> dashboard was built on a new model, designed from scratch, to give our customers a designated home—consolidated under a single roof—to manage their Teams products and accounts.</p><p>Fast forward to today and Zero Trust has grown tremendously, both in capability and reach. Many of our customers are using multiple Cloudflare products together, including Cloudflare One and Zero Trust products. Our home has grown, and this navigation change is one step toward expanding our roof to cover Cloudflare’s rapidly expanding footprint.</p>
    <div>
      <h3>A focus on user experience</h3>
      <a href="#a-focus-on-user-experience">
        
      </a>
    </div>
    <p>We have heard from many of you about the pains you experience when using multiple Cloudflare products, including Zero Trust. Your voice matters to us, and we’re invested in building a world-class user experience to make your time with Cloudflare an easy and enjoyable one. Our user experience improvements are based on three core principles: Consistency, Interconnectivity, and Discoverability.</p><p>We aim to offer a consistent and predictable user experience across the entire Cloudflare ecosystem so you never have to think twice about where you are in your journey, whether performing your familiar daily tasks or discovering our new ground-breaking products and features.</p>
    <div>
      <h2>What else?</h2>
      <a href="#what-else">
        
      </a>
    </div>
    <p>This navigation change we’re announcing today isn’t the only user experience improvement we’ve built! You may have noticed a few more optimizations recently:</p>
    <div>
      <h3>User authorization and loading experience</h3>
      <a href="#user-authorization-and-loading-experience">
        
      </a>
    </div>
    <p>Remember the days of the recurrent loading screen? Or perhaps when your Zero Trust account didn’t match the one you had logged in with to manage, say, your DNS? Those days are over! Our team has built a smarter, faster, and more seamless user and account authorization experience.</p>
    <div>
      <h3>New tables</h3>
      <a href="#new-tables">
        
      </a>
    </div>
    <p>Tables are table stakes when it comes to presenting large quantities of data and information. (Yes, pun intended.) Tables are a common UI element across Cloudflare, and now Zero Trust uses the same tables UI as you will see when managing other products and features.</p>
    <div>
      <h3>UI consistency</h3>
      <a href="#ui-consistency">
        
      </a>
    </div>
    <p>A slight change in color scheme and page layout brings the Zero Trust dashboard into the same visual family as the broader Cloudflare experience. Now, when you navigate to Zero Trust, we want you to know that you’re still under our one single Cloudflare roof.</p><p>We’re as excited about these improvements as you are! And we hope the upcoming navigation and page improvements come as a welcome addition to the changes noted above.</p>
    <div>
      <h2>What’s next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>The user experience changes we’ve covered today go a long way toward creating a more consistent, seamless and user-friendly interface to make your work on Cloudflare as easy and efficient as possible. We know there’s always room for further improvement (we already have quite a few big improvements on our radar!).</p><p>To ensure we’re solving <i>your</i> biggest problems, we’d like to hear from you. Please consider filling out a <a href="https://forms.gle/yQxqfyXKCdUKHYep6">short survey</a> to share the most pressing user experience improvements you’d like to see next.</p> ]]></content:encoded>
            <category><![CDATA[Cloudflare Zero Trust]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">2AkgqXaL0e5ri9xMIQk1ho</guid>
            <dc:creator>Emily Flannery</dc:creator>
        </item>
        <item>
            <title><![CDATA[One of our most requested features is here: DNS record comments and tags]]></title>
            <link>https://blog.cloudflare.com/dns-record-comments/</link>
            <pubDate>Wed, 21 Dec 2022 14:00:00 GMT</pubDate>
            <description><![CDATA[ Today, we’re releasing DNS record comments and tags, making it easier to keep track of and manage DNS records of your domain ]]></description>
            <content:encoded><![CDATA[ <p><i></i></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6qRYZGuZrkdXAlyRw1MFJE/09d6b996e575d6be50422735b8674d00/image5-8.png" />
            
            </figure><p>Starting today, we’re adding support on all zone plans to add custom comments on your DNS records. Users on the Pro, Business and Enterprise plan will also be able to tag DNS records.</p>
    <div>
      <h3>DNS records are important</h3>
      <a href="#dns-records-are-important">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/dns/dns-records/">DNS records</a> play an essential role when it comes to operating a website or a web application. In general, they are used to mapping human-readable hostnames to machine-readable information, most commonly IP addresses. Besides mapping hostnames to IP addresses they also fulfill many other use cases like:</p><ul><li><p>Ensuring emails can reach your inbox, by setting up MX records.</p></li><li><p><a href="/tackling-email-spoofing/">Avoiding email spoofing and phishing</a> by configuring <a href="https://www.cloudflare.com/learning/dns/dns-records/dns-spf-record/">SPF</a>, <a href="https://www.cloudflare.com/learning/dns/dns-records/dns-dmarc-record/">DMARC</a> and <a href="https://www.cloudflare.com/learning/dns/dns-records/dns-dkim-record/">DKIM</a> policies as TXT records.</p></li><li><p>Validating a <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificate</a> by adding a TXT (or CNAME) record.</p></li><li><p>Specifying allowed certificate authorities that can issue certificates on behalf of your domain by creating a CAA record.</p></li><li><p>Validating ownership of your domain for other web services (website hosting, email hosting, web storage, etc.) - usually by creating a TXT record.</p></li><li><p>And many more.</p></li></ul><p>With all these different use cases, it is easy to forget what a particular DNS record is for, and it is not always possible to derive the purpose from the name, type and content of a record. Validation TXT records tend to be on seemingly arbitrary names with rather cryptic content. When you then also throw multiple people or teams into the mix who have access to the same domain, all creating and updating DNS records, it can quickly happen that someone modifies or even deletes a record causing the on-call person to get paged in the middle of the night.</p>
    <div>
      <h3>Enter: DNS record comments &amp; tags</h3>
      <a href="#enter-dns-record-comments-tags">
        
      </a>
    </div>
    <p>Starting today, everyone with a zone on Cloudflare can add custom comments on each of their DNS records <a href="https://developers.cloudflare.com/api/operations/dns-records-for-a-zone-create-dns-record">via the API</a> and through the Cloudflare dashboard.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/43He05MR7LGRHOAIRF7ICQ/684badcdf95d8115924a81af1490c4ca/image3-26.png" />
            
            </figure><p>To add a comment, just click on the Edit action of the respective DNS record and fill out the Comment field. Once you hit Save, a small icon will appear next to the record name to remind you that this record has a comment. Hovering over the icon will allow you to take a quick glance at it without having to open the edit panel.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1Sal8wIsnLOY9ybSucN9YR/fd5345ec63152feb5b93924c1d755b88/unnamed-2.png" />
            
            </figure><p>What you also can see in the screenshot above is the new Tags field. All users on the Pro, Business, or Enterprise plans now have the option to add custom tags to their records. These tags can be just a key like “important” or a key-value pair like “team:DNS” which is separated by a colon. Neither comments nor tags have any impact on the resolution or propagation of the particular DNS record, and they’re only visible to people with access to the zone.</p><p>Now we know that some of our users love automation by using our API. So if you want to create a number of zones and populate all their DNS records by uploading a zone file as part of your script, you can also directly include the DNS record comments and tags in that zone file. And when you export a zone file, either to back up all records of your zone or to easily move your zone to another account on Cloudflare, it will also contain comments and tags. Learn more about importing and exporting comments and tags on our <a href="https://developers.cloudflare.com/dns/manage-dns-records/how-to/import-and-export/#dns-record-attributes">developer documentation</a>.</p>
            <pre><code>;; A Records
*.mycoolwebpage.xyz.     1      IN  A    192.0.2.3
mycoolwebpage.xyz.       1      IN  A    203.0.113.1 ; Contact Hannes for details.
sub1.mycoolwebpage.xyz.  1      IN  A    192.0.2.2 ; Test origin server. Can be deleted eventually. cf_tags=testing
sub1.mycoolwebpage.xyz.  1      IN  A    192.0.2.1 ; Production origin server. cf_tags=important,prod,team:DNS

;; MX Records
mycoolwebpage.xyz.       1      IN  MX   1 mailserver1.example.
mycoolwebpage.xyz.       1      IN  MX   2 mailserver2.example.

;; TXT Records
mycoolwebpage.xyz.       86400	IN  TXT  "v=spf1 ip4:192.0.2.0/24 -all" ; cf_tags=important,team:EMAIL
sub1.mycoolwebpage.xyz.  86400  IN  TXT  "hBeFxN3qZT40" ; Verification record for service XYZ. cf_tags=team:API</code></pre>
            
    <div>
      <h3>New filters</h3>
      <a href="#new-filters">
        
      </a>
    </div>
    <p>It might be that your zone has hundreds or thousands of DNS records, so how on earth would you find all the records that belong to the same team or that are needed for one particular application?</p><p>For this we created a new filter option in the dashboard. This allows you to not only filter for comments or tags but also for other record data like name, type, content, or proxy status. The general search bar for a quick and broader search will still be available, but it cannot (yet) be used in conjunction with the new filters.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6z9nMLjRXXLwPtdUVAyzdj/1ee693bd6693089f51738fbe7f3ba79a/image1-55.png" />
            
            </figure><p>By clicking on the “Add filter” button, you can select individual filters that are connected with a logical AND. So if I wanted to only look at TXT records that are tagged as important, I would add these filters:</p><div></div>
    <div>
      <h3>One more thing (or two)</h3>
      <a href="#one-more-thing-or-two">
        
      </a>
    </div>
    <p>Another change we made is to replace the Advanced button with two individual actions: Import and Export, and Dashboard Display Settings.</p><p>You can find them in the top right corner under DNS management. When you click on Import and Export you have the option to either export all existing DNS records (including their comments and tags) into a zone file or import new DNS records to your zone by uploading a zone file.</p><div></div><p>The action Dashboard Display Settings allows you to select which special record types are shown in the UI. And there is an option to toggle showing the record tags inline under the respective DNS record or just showing an icon if there are tags present on the record.</p><p>And last but not least, we increased the width of the DNS record table as part of this release. The new table makes better use of the existing horizontal space and allows you to see more details of your DNS records, especially if you have longer subdomain names or content.</p>
    <div>
      <h3>Try it now</h3>
      <a href="#try-it-now">
        
      </a>
    </div>
    <p>DNS record comments and tags are available today. Just navigate to the <a href="https://dash.cloudflare.com/?to=/:account/:zone/dns">DNS tab</a> of your zone in the Cloudflare dashboard and create your first comment or tag. If you are not yet using Cloudflare DNS, <a href="https://dash.cloudflare.com/sign-up">sign up for free</a> in just a few minutes.</p><p>Learn more about DNS record comments and tags on our <a href="https://developers.cloudflare.com/dns/manage-dns-records/reference/record-attributes/">developer documentation</a>.</p> ]]></content:encoded>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[DNS]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">3RWPucQrnIbxDORsioOANS</guid>
            <dc:creator>Hannes Gerhart</dc:creator>
        </item>
        <item>
            <title><![CDATA[Project A11Y: how we upgraded Cloudflare’s dashboard to adhere to industry accessibility standards]]></title>
            <link>https://blog.cloudflare.com/project-a11y/</link>
            <pubDate>Fri, 30 Sep 2022 13:00:00 GMT</pubDate>
            <description><![CDATA[ At Cloudflare, we believe the Internet should be accessible to everyone. And today, we’re happy to announce a more inclusive Cloudflare dashboard experience: adherence to the industry accessibility standards, including WCAG 2.1 AA and section 508 compliance. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>At Cloudflare, we believe the Internet should be accessible to <b>everyone</b>. And today, we’re happy to announce a more inclusive Cloudflare dashboard experience for our users with disabilities. Recent improvements mean our dashboard now adheres to industry accessibility standards, including <a href="https://www.w3.org/TR/WCAG21/">Web Content Accessibility Guidelines (WCAG) 2.1</a> AA and Section 508 of the Rehabilitation Act.</p><p>Over the past several months, the Cloudflare team and our partners have been hard at work to make the Cloudflare dashboard<sup>1</sup> as accessible as possible for every single one of our current and potential customers. This means incorporating accessibility features that comply with the latest Web Content Accessibility Guidelines (WCAG) and Section 508 of the US’s federal Rehabilitation Act. We are invested in working to meet or exceed these standards; to demonstrate that commitment and share openly about the state of accessibility on the Cloudflare dashboard, we have completed the Voluntary Product Accessibility Template (VPAT), a document used to evaluate our level of conformance today.</p><p>Conformance with a technical and legal spec is a bit abstract–but for us, accessibility simply means that as many people as possible can be successful users of the Cloudflare dashboard. This is important because each day, more and more individuals and businesses rely upon Cloudflare to administer and protect their websites.</p><p>For individuals with disabilities who work on technology, we believe that an accessible Cloudflare dashboard could mean improved economic and technical opportunities, safer websites, and equal access to tools that are shaping how we work and build on the Internet.</p><p>For designers and developers at Cloudflare, our accessibility remediation project has resulted in an overhaul of our component library. Our newly WCAG-compliant components expedite and simplify our work building accessible products. They make it possible for us to deliver on our commitment to an accessible dashboard going forward.</p>
    <div>
      <h2>Our Journey to an Accessible Cloudflare Dashboard</h2>
      <a href="#our-journey-to-an-accessible-cloudflare-dashboard">
        
      </a>
    </div>
    <p>In 2021, we initiated an audit with third party experts to identify accessibility challenges in the Cloudflare dashboard. This audit came back with a daunting 213-page document—a very, very long list of compliance gaps.</p><p>We learned from the audit that there were many users we had unintentionally failed to design and build for in Cloudflare dashboard user interfaces. Most especially, we had not done well accommodating keyboard users and screen reader users, who often rely upon these technologies because of a physical impairment. Those impairments include low vision or blindness, motor disabilities (examples include tremors and repetitive strain injury), or cognitive disabilities (examples include dyslexia and dyscalculia).</p><p>As a product and engineering organization, we had spent more than a decade in cycles of rapid growth and product development. While we're proud of what we have built, the audit made clear to us that there was a great need to address the design and technical debt we had accrued along the way.</p><p>One year, four hundred Jira tickets, and over 25 new, accessible web components later, we’re ready to celebrate our progress with you. Major categories of work included:</p><ol><li><p><b>Forms:</b> We re-wrote our internal form components with accessibility and developer experience top of mind. We improved form validation and error handling, labels, required field annotations, and made use of persistent input descriptions instead of placeholders. Then, we deployed those component upgrades across the dashboard.</p></li><li><p><b>Data visualizations:</b> After conducting a rigorous re-evaluation of their design, we re-engineered charts and graphs to be accessible to keyboard and screen reader users. See below for a brief case study.</p></li><li><p><b>Heading tags:</b> We corrected page structure throughout the dashboard by replacing all our heading tags (, , etc.) with a <a href="https://medium.com/@Heydon/managing-heading-levels-in-design-systems-18be9a746fa3">technique we borrowed from Heydon Pickering</a>. This technique is an approach to heading level management that uses React Context and basic arithmetic.</p></li><li><p><b>SVGs:</b> We reworked how we create SVGs (Scalable Vector Graphics), so that they are labeled properly and only exposed to assistive technology when useful.</p></li><li><p><b>Node modules:</b> We jumped several major versions of old, inaccessible node modules that our UI components depend upon (and we broke many things along the way).</p></li><li><p><b>Color:</b> We overhauled our use of color, and contributed a new volume of accessible sequential colors to our design system.</p></li><li><p><b>Bugs:</b> We squashed <i>a lot</i> of bugs that had made their way into the dashboard over the years. The most common type of bug we encountered related to incorrect or unsemantic use of HTML elements—for example, using a  where we should have used a  (table data) or  (table row) element within a table.</p></li></ol>
    <div>
      <h3>Case Study: Accessibility Work On Cloudflare Dashboard Data &amp; Analytics</h3>
      <a href="#case-study-accessibility-work-on-cloudflare-dashboard-data-analytics">
        
      </a>
    </div>
    <p>The Cloudflare dashboard is replete with analytics and data visualizations designed to offer deep insight into users' websites’ performance, traffic, security, and more. Making those data visualizations accessible proved to be among the most complex and interdisciplinary issues we faced in the remediation work.</p><p>An example of a problem we needed to solve related to <a href="https://www.w3.org/WAI/WCAG21/Understanding/use-of-color.html">WCAG success criterion 1.4.1</a>, which pertains to the use of color. 1.4.1 specifies that color cannot be the only means by which to convey information, such as the differentiation between two items compared in a chart or graph.</p><p>Our charts were clearly nonconforming with this standard, using color alone to represent different data being compared. For example, a typical graph might have used the color blue to show the number of requests to a website that were 200 OK, and the color orange to show 403 Forbidden, but failed to offer users another way to discern between the two status codes.</p><p>Our UI team went to work on the problem, and chose to focus our effort first on the Cloudflare dashboard time series graphs.</p><p>Interestingly, we found that design patterns recommended even by accessibility experts created wholly unusable visualizations when placed into the context of real world data. Examples of such recommended patterns include using different line weights, patterns (dashed, dotted or other line styles), and terminal glyphs (symbols set at the beginning and end of the lines) to differentiate items being compared.</p><p>We tried, and failed, to apply a number of these patterns; you can see the evolution of this work on our time series graph component in the three different images below.</p><p>v.1</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5RFcd4v1fPOkjzD5YESBx6/67be00f54b4e9a43ee29a4a2b9ac2177/image4-28.png" />
            
            </figure><p>Here is an early attempt at using both terminal glyphs and patterns to differentiate data in a time series graph. You can see that the terminal glyphs pile up and become indistinguishable; the differences among the line patterns are very hard to discern. This code never made it into production.</p><p>v.2</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/418yb2nLowvaTahPv6HmyD/c46df76dbad97af783ea0e15eda71b8f/image2-66.png" />
            
            </figure><p>In this version, we eliminated terminal glyphs but kept line patterns. Additionally, we faded the unfocused items in the graph to help bring highlighted data to the forefront. This latter technique made it into our final solution.</p><p>v.3</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4wQbZ5YxrrIyY56Ury2811/9316357feeb9fabca8d5316ddacf05ee/image3-50.png" />
            
            </figure><p>Here we eliminated patterns altogether, simplified the user interface to only use the fading technique on unfocused items, and put our new, sequentially accessible colors to use. Finally, a visual design solution approved by accessibility and data visualization experts, as well as our design and engineering teams.</p><p>After arriving at our design solution, we had some engineering work to do.</p><p>In order to meet WCAG success criterion <a href="https://www.w3.org/WAI/WCAG21/Understanding/keyboard.html">2.1.1</a>, we rewrote our time series graphs to be fully keyboard accessible by adding focus handling to every data point, and enabling the traversal of data using arrow keys.</p><div></div><p><i>Navigating time series data points by keyboard on the Cloudflare dashboard.</i></p><p>We did some fine-tuning, specifically to support screen readers: we eliminated auditory “<a href="https://en.wikipedia.org/wiki/Chartjunk">chartjunk</a>” (unnecessary clutter or information in a chart or graph) and cleaned up decontextualized data (a scenario in which numbers are exposed to and read by a screen reader, but contextualizing information, like x- and y-axis labels, is not).</p><p>And lastly, to meet WCAG <a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/text-equiv-all.html">1.1.1</a>, we engineered new UI component wrappers to make chart and graph data downloadable in CSV format. We deployed this part of the solution across all charts and graphs, not just the time series charts like those shown above. No matter how you browse and interact with the web, we hope you'll notice this functionality around the Cloudflare dashboard and find value in it.</p><p>Making all of this data available to low vision, keyboard, and assistive technology users was an interesting challenge for us, and a true team effort. It necessitated a separate data visualization report conducted by another, more specialized team of third party experts, deep collaboration between engineering and design, and many weeks of development.</p><p>Applying this thorough treatment to all data visualizations on the Cloudflare dashboard is our goal, but still work in progress. Please stay tuned for more accessible updates to our chart and graph components.</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>There's a lot of nuance to accessibility work, and we were novices at the beginning: researching and learning as we were doing. We also broke a lot of things in the process, which (as any engineering team knows!) can be stressful.</p><p>Overall, our team’s biggest challenge was figuring out how to complete a high volume of cross-functional work in the shortest time possible, while also setting a foundation for these improvements to persist over time.</p><p>As a frontend engineering and design team, we are very grateful for having had the opportunity to focus on this problem space and to learn from truly world-class accessibility experts along the way.</p><p>Accessibility matters to us, and we know it does to you. We’re proud of our progress, and there’s always more to do to make Cloudflare more usable for all of our customers. This is a critical piece of our foundation at Cloudflare, where we are building the most secure, performant and reliable solutions for the Internet. Stay tuned for what’s next!</p><p>Not using Cloudflare yet? <a href="https://dash.cloudflare.com/sign-up">Get started today</a> and join us on our mission to build a better Internet.</p><p><sup>1</sup>All references to “dashboard” in this post are specific to the primary user authenticated Cloudflare web platform. This does not include Cloudflare’s product-specific dashboards, marketing, support, educational materials, or third party integrations.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Better Internet]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[User Research]]></category>
            <guid isPermaLink="false">2IHwz5c2gqwBa3B0zR3Gko</guid>
            <dc:creator>Rachel Jenkins</dc:creator>
            <dc:creator>Emily Flannery</dc:creator>
        </item>
        <item>
            <title><![CDATA[Now all customers can share access to their Cloudflare account with Role Based Access Controls]]></title>
            <link>https://blog.cloudflare.com/rbac-for-everyone/</link>
            <pubDate>Thu, 29 Sep 2022 13:00:00 GMT</pubDate>
            <description><![CDATA[ Role Based Access Controls are now available for every plan! ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Cloudflare’s mission is to help build a better Internet. Pair that with our core belief that security is something that should be accessible to everyone and the outcome is a better and safer Internet for all. Previously, our FREE and PAYGO customers didn’t have the flexibility to give someone control of just part of their account, they had to give access to everything.</p><p>Starting today, <a href="https://www.cloudflare.com/learning/access-management/role-based-access-control-rbac/">role based access controls (RBAC)</a>, and all of our additional roles will be rolled out to users on every plan! Whether you are a small business or even a single user, you can ensure that you can add users only to parts of Cloudflare you deem appropriate.</p>
    <div>
      <h3>Why should I limit access?</h3>
      <a href="#why-should-i-limit-access">
        
      </a>
    </div>
    <p>It is good practice with security in general to <a href="https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/">limit access</a> to what a team member needs to do a job. Restricting access limits the overall threat surface if a given user was compromised, and ensures that you limit the surface that mistakes can be made.</p><p>If a malicious user was able to gain access to an account, but it only had read access, you’ll find yourself with less of a headache than someone who had administrative access, and could change how your site operates. Likewise, you can prevent users outside their role from accidentally making changes to critical features like firewall or DNS configuration.</p>
    <div>
      <h3>What are roles?</h3>
      <a href="#what-are-roles">
        
      </a>
    </div>
    <p>Roles are a grouping of permissions that make sense together. At Cloudflare, this means grouping permissions together by access to a product suite.</p><p>Cloudflare is a critical piece of infrastructure for customers, and roles ensure that you can give your team the access they need, scoped to what they’ll do, and which products they interact with.</p><p>Once enabled for Role Based Access Controls, by going to “Manage Account” and “Members” in the left sidebar, you’ll have the following list of roles available, which each grant access to disparate subsets of the Cloudflare offering.</p><table>
<thead>
  <tr>
    <th>Role Name</th>
    <th>Role Description</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>Administrator</td>
    <td>Can access the full account, except for membership management and billing.</td>
  </tr>
  <tr>
    <td>Administrator Read Only</td>
    <td>Can access the full account in read-only mode.</td>
  </tr>
  <tr>
    <td>Analytics</td>
    <td>Can read Analytics.</td>
  </tr>
  <tr>
    <td>Audit Logs Viewer</td>
    <td>Can view Audit Logs.</td>
  </tr>
  <tr>
    <td>Billing</td>
    <td>Can edit the account’s billing profile and subscriptions.</td>
  </tr>
  <tr>
    <td>Cache Purge</td>
    <td>Can purge the edge cache.</td>
  </tr>
  <tr>
    <td>Cloudflare Access</td>
    <td>Can edit Cloudflare Access policies.</td>
  </tr>
  <tr>
    <td>Cloudflare Gateway</td>
    <td>Can edit Cloudflare Gateway and read Access.</td>
  </tr>
  <tr>
    <td>Cloudflare Images</td>
    <td>Can edit Cloudflare Images assets</td>
  </tr>
  <tr>
    <td>Cloudflare Stream</td>
    <td>Can edit Cloudflare Stream media.</td>
  </tr>
  <tr>
    <td>Cloudflare Workers Admin</td>
    <td>Can edit Cloudflare Workers.</td>
  </tr>
  <tr>
    <td>Cloudflare Zero Trust</td>
    <td>Can edit Cloudflare Zero Trust.</td>
  </tr>
  <tr>
    <td>Cloudflare Zero Trust PII</td>
    <td>Can access Cloudflare Zero Trust PII.</td>
  </tr>
  <tr>
    <td>Cloudflare Zero Trust Read Only</td>
    <td>Can access Cloudflare for Zero Trust read only mode.</td>
  </tr>
  <tr>
    <td>Cloudflare Zero Trust Reporting</td>
    <td>Can access Cloudflare for Zero Trust reporting data.</td>
  </tr>
  <tr>
    <td>DNS</td>
    <td>Can edit DNS records.</td>
  </tr>
  <tr>
    <td>Firewall</td>
    <td>Can edit WAF, IP Firewall, and Zone Lockdown settings.</td>
  </tr>
  <tr>
    <td>HTTP Applications</td>
    <td>Can view and edit HTTP Applications</td>
  </tr>
  <tr>
    <td>HTTP Applications Read</td>
    <td>Can view HTTP Applications</td>
  </tr>
  <tr>
    <td>Load Balancer</td>
    <td>Can edit Load Balancers, Pools, Origins, and Health Checks.</td>
  </tr>
  <tr>
    <td>Log Share</td>
    <td>Can edit Log Share configuration.</td>
  </tr>
  <tr>
    <td>Log Share Reader</td>
    <td>Can read Enterprise Log Share.</td>
  </tr>
  <tr>
    <td>Magic Network Monitoring</td>
    <td>Can view and edit MNM configuration</td>
  </tr>
  <tr>
    <td>Magic Network Monitoring Admin</td>
    <td>Can view, edit, create, and delete MNM configuration</td>
  </tr>
  <tr>
    <td>Magic Network Monitoring Read-Only</td>
    <td>Can view MNM configuration</td>
  </tr>
  <tr>
    <td>Network Services Read (Magic)</td>
    <td>Grants read access to network configurations for Magic services.</td>
  </tr>
  <tr>
    <td>Network Services Write (Magic)</td>
    <td>Grants write access to network configurations for Magic services.</td>
  </tr>
  <tr>
    <td>SSL/TLS, Caching, Performance, Page Rules, and Customization</td>
    <td>Can edit most Cloudflare settings except for DNS and Firewall.</td>
  </tr>
  <tr>
    <td>Trust and Safety</td>
    <td>Can view and request reviews for blocks</td>
  </tr>
  <tr>
    <td>Zaraz Admin</td>
    <td>Can edit Zaraz configuration.</td>
  </tr>
  <tr>
    <td>Zaraz Readonly</td>
    <td>Can read Zaraz configuration.</td>
  </tr>
</tbody>
</table><p>If you find yourself on a team that is growing, you may want to grant firewall and DNS access to a delegated network admin, billing access to your bookkeeper, and Workers access to your developer.</p><p>Each of these roles provides specific access to a portion of your Cloudflare account, scoping them to the appropriate set of products. Even Super Administrator is now available, allowing you to provide this access to somebody without handing over your password and 2FA.</p>
    <div>
      <h3>How to use our roles</h3>
      <a href="#how-to-use-our-roles">
        
      </a>
    </div>
    <p>The first step to using RBAC is an analysis and review of the duties and tasks of your team. When a team member primarily interacts with a specific part of the Cloudflare offering, start off by giving them only access to that part(s). Our roles are built in a way that allows multiple to be assigned to a single user, such that when they require more access, you can grant them an additional role.</p>
    <div>
      <h3>Rollout</h3>
      <a href="#rollout">
        
      </a>
    </div>
    <p>At this point in time, we will be rolling out RBAC over the next few weeks. When the roles become available in your account, head over to our <a href="https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/">documentation</a> to learn about each of the roles in detail.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">5uzqiEawaf1Xm83PMjj6py</guid>
            <dc:creator>Joseph So</dc:creator>
        </item>
        <item>
            <title><![CDATA[We've shipped so many products the Cloudflare dashboard needed its own search engine]]></title>
            <link>https://blog.cloudflare.com/quick-search-beta/</link>
            <pubDate>Wed, 28 Sep 2022 13:00:00 GMT</pubDate>
            <description><![CDATA[ Today we’re proud to announce our beta release of quick search for the Cloudflare dashboard, our first ever cross-dashboard search tool to help you navigate our products and features. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Today we’re proud to announce our first release of <i>quick search</i> for the Cloudflare dashboard, a beta version of our first ever cross-dashboard search tool to help you navigate our products and features. This first release is now available to a small percentage of our customers. Want to request early access? Let us know by filling out <a href="https://forms.gle/wFXsvNCCPpTDPKNw5">this form</a>.</p>
    <div>
      <h2>What we’re launching</h2>
      <a href="#what-were-launching">
        
      </a>
    </div>
    <p>We’re launching <i>quick search</i> to speed up common interactions with the Cloudflare dashboard. Our dashboard allows you to configure Cloudflare’s full suite of products and features, and <i>quick search</i> gives you a shortcut.</p><p>To get started, you can access the <i>quick search</i> tool from anywhere within the Cloudflare dashboard by clicking the magnifying glass button in the top navigation, or hitting <i>Ctrl + K</i> on Linux and Windows or <i>⌘ + K</i> on Mac. (If you find yourself forgetting which key combination it is just remember that it’s <i>⌘</i> or <i>Ctrl-K</i>-wik.) From there, enter a search term and then select from the results shown below.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/18FxLXGhxaDifpdwrbLL6g/c194908339f7305be8d06577a550d98a/image7-8.png" />
            
            </figure><p><i>Access</i> quick search <i>from the top navigation bar, or use keyboard shortcuts Ctrl + K on Linux and Windows or ⌘ + K on Mac.</i></p>
    <div>
      <h2>Current supported functionality</h2>
      <a href="#current-supported-functionality">
        
      </a>
    </div>
    <p>What functionality will you have access to? Below you’ll learn about the three core capabilities of <i>quick search</i> that are included in this release, as well as helpful tips for using the tool.</p>
    <div>
      <h3>Search for a page in the dashboard</h3>
      <a href="#search-for-a-page-in-the-dashboard">
        
      </a>
    </div>
    <p>Start typing in the name of the product you’re looking for, and we’ll load matching terms after each key press. You will see results for any dashboard page that currently exists in your sidebar navigation. Then, just click the desired result to navigate directly there.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/30Se7KvpQxKKecPW54rr8n/67388a8a37af76a11d50d86f633378d1/image6-12.png" />
            
            </figure><p><i>Search for “page” and you’ll see results categorized into “website-only products” and “account-wide products.”</i></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3UHBkxlq39FejydkUsLJoK/cbf57b82071ce11613ae87d7fef36bd1/image3-42.png" />
            
            </figure><p><i>Search for “ddos” and you’ll see results categorized into “websites,” “website-only products” and “account-wide products.”</i></p>
    <div>
      <h3>Search for website-only products</h3>
      <a href="#search-for-website-only-products">
        
      </a>
    </div>
    <p>For our customers who manage a website or domain in Cloudflare, you have access to a multitude of Cloudflare products and features to enhance your website’s security, performance and reliability. <i>Quick search</i> can be used to easily find those products and features, regardless of where you currently are in the dashboard (even from within another website!).</p><p>You may easily search for your website by name to navigate to your website’s Overview page:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/EegwomFl43gRGdZbD4ecI/e5a2cd35d1ac65a7836856889220ac54/image9-5.png" />
            
            </figure><p>You may also navigate to the products and feature pages <i>within</i> your specific website(s). Note that you can perform a website-specific search from anywhere in your core dashboard using one of two different approaches, which are explained below.</p><p>First, you may search first for your website by name, then navigate search results from there:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/11Bi07CtVIWCh5YdIb8E93/de0b72d5d8b5aa8f923719a5cc934682/image2-61.png" />
            
            </figure><p>Alternatively, you may search first for the product or feature you’re looking for, then filter down by your website:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6raMp2ha9o8ZSIuHUkvafb/cdcc066b01ae3066d7d438963e5d3045/image5-22.png" />
            
            </figure>
    <div>
      <h3>Search for account-wide products</h3>
      <a href="#search-for-account-wide-products">
        
      </a>
    </div>
    <p>Many Cloudflare products and features are <i>not</i> tied directly to a website or domain that you have set up in Cloudflare, like Workers, <a href="https://www.cloudflare.com/developer-platform/r2/">R2</a>, Magic Transit—not to mention their related sub-pages. Now, you may use <i>quick search</i> to more easily navigate to those sections of the dashboard.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4TgFfEpQ9ewvfU90knvhEe/58f5a2aaecfdf38528eee04bc19c6aa2/image8-6.png" />
            
            </figure>
    <div>
      <h2>What’s next for quick search</h2>
      <a href="#whats-next-for-quick-search">
        
      </a>
    </div>
    <p>Here’s an overview of what’s next on our <i>quick search</i> roadmap (and not yet supported today):</p><ul><li><p>Search results do not currently return results of product- and feature-specific names or configurations, such as Worker names, specific DNS records, IP addresses, Firewall Rules.</p></li><li><p>Search results do not currently return results from <i>within</i> the Zero Trust dashboard.</p></li><li><p>Search results do not currently return results for Cloudflare content living outside the dashboard, like Support or Developer documentation.</p></li></ul><p>We’d love to hear what you think. What would you like to see added next? Let us know using the feedback link found at the bottom of the search window.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/CBp4LkpNA6x8V8Q1uWt0l/02da171b53c08df91c8609b160626c91/image4-23.png" />
            
            </figure>
    <div>
      <h2>Our vision for the future of the dashboard</h2>
      <a href="#our-vision-for-the-future-of-the-dashboard">
        
      </a>
    </div>
    <p>We’re excited to launch <i>quick search</i> and to continue improving our dashboard experience for all customers. Over time, we’ll mature our search functionality to index any and all content you might be looking for — including search results for all product content, Support and Developer docs, extending search across accounts, caching your recent searches, and more.</p><p><i>Quick search</i> is one of many important user experience improvements we are planning to tackle over the coming weeks, months and years. The dashboard is central to your Cloudflare experience, and we’re fully committed to making your experience delightful, useful, and easy. Stay tuned for an upcoming blog post outlining the vision for the Cloudflare dashboard, from our in-app home experience to our global navigation and beyond.</p><p>For now, keep your eye out for the little search icon that will help you in your day-to-day responsibilities in Cloudflare, and if you don’t see it yet, don’t worry—we can’t wait to ship it to you soon.</p><p>If you don’t yet see <i>quick search</i> in your Cloudflare dashboard, you can request early access by filling out <a href="https://forms.gle/wFXsvNCCPpTDPKNw5">this form</a>.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[User Research]]></category>
            <category><![CDATA[Beta]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">1pMicOaM3g9qNkIWyiAHMP</guid>
            <dc:creator>Emily Flannery</dc:creator>
            <dc:creator>Harley Turan</dc:creator>
        </item>
        <item>
            <title><![CDATA[Internship Experience: Software Development Intern]]></title>
            <link>https://blog.cloudflare.com/internship-experience-software-development-intern/</link>
            <pubDate>Wed, 18 May 2022 12:59:16 GMT</pubDate>
            <description><![CDATA[ Back in December 2021, I joined Cloudflare as a Software Development Intern on the Partnerships team to help improve the experience that Partners have when using the platform ]]></description>
            <content:encoded><![CDATA[ <p>Before we dive into my experience interning at Cloudflare, let me quickly introduce myself. I am currently a master’s student at the National University of Singapore (NUS) studying Computer Science. I am passionate about building software that improves people’s lives and making the Internet a better place for everyone. Back in December 2021, I joined Cloudflare as a Software Development Intern on the Partnerships team to help improve the experience that Partners have when using the platform. I was extremely excited about this opportunity and jumped at the prospect of working on serverless technology to build viable tools for our partners and customers. In this blog post, I detail my experience working at Cloudflare and the many highlights of my internship.</p>
    <div>
      <h3>Interview Experience</h3>
      <a href="#interview-experience">
        
      </a>
    </div>
    <p>The process began for me back when I was taking a software engineering module at NUS where one of my classmates had shared a job post for an internship at Cloudflare. I had known about Cloudflare’s DNS service prior and was really excited to learn more about the internship opportunity because I really resonated with the company's mission to help build a better Internet.</p><p>I knew right away that this would be a great opportunity and submitted my application. Soon after, I heard back from the recruiting team and went through the interview process – the entire interview process was extremely accommodating and is definitely the most enjoyable interview experience I have had. Throughout the process, I was constantly asked about the kind of things I would like to work on and the relevance of the work that I would be doing. I felt that this thorough communication carried on throughout the internship and really was a cornerstone of my experience interning at Cloudflare.</p>
    <div>
      <h3>My Internship</h3>
      <a href="#my-internship">
        
      </a>
    </div>
    <p>My internship began with onboarding and training, and then after, I had discussions with my mentor, Ayush Verma, on the projects we aimed to complete during the internship and the order of objectives. The main issues we wanted to address was the current manual process that our internal teams and partners go through when they want to duplicate the configuration settings on a zone, or when they want to compare one zone to other zones to ensure that there are no misconfigurations. As you can imagine, with the number of different configurations offered on the Cloudflare dashboard for customers, it could take significant time to copy over every setting and rule manually from one zone to another. Additionally, this process, when done manually, poses a potential threat for misconfigurations due to human error. Furthermore, as more and more customers onboard different zones onto Cloudflare, there needs to be a more automated and improved way for them to make these configuration setups.</p><p>Initially, we discussed using Terraform as Cloudflare already supports terraform automation. However, this approach would only cater towards customers and users that have more technical resources and, in true Cloudflare spirit, we wanted to keep it simple such that it could be used by any and everyone. Therefore, we decided to leverage the publicly available Cloudflare APIs and create a browser-based application that interacts with these APIs to display configurations and make changes easily from a simple UI.</p><p>With the end goal of simplifying the experience for our partners and customers in duplicating zone configurations, we decided to build a Zone Copier web application solely built on Cloudflare Workers. This tool would, in a click of a button, automatically copy over every setting that can be copied from one zone to another, significantly reducing the amount of time and effort required to make the changes.</p><p>Alongside the Zone Copier, we would have some auxiliary tools such as a Zone Viewer, and Zone Comparison, where a customer can easily have a full view of their configurations on a single webpage and be able to compare different zones that they use respectively. These other applications improve upon the existing methods through which Cloudflare users can view their zone configurations, and allow for the direct comparison between different zones.</p><p>Importantly, these applications are not to replace the Cloudflare Dashboard, but to complement it instead – for deeper dives into a single particular configuration setting, the Cloudflare Dashboard remains the way to go.</p><p>To begin building the web application, I spent the first few weeks diving into the publicly available APIs offered by Cloudflare as part of the v4 API to verify the outputs of each endpoint, and the type of data that would be sent as a response from a request. This took much longer than expected as certain endpoints provided different default responses for a zone that has either an empty setting – for example, not having any Firewall Rules created – or uses a nested structure for its relevant response. These different potential responses have to be examined so that when the web application calls the respective API endpoint, the responses are handled appropriately. This process was quite manual as each endpoint had to be verified individually to ensure the output would work seamlessly with the application.</p><p>Once I completed my research, I was able to start designing the web application. Building the web application was a very interesting experience as the stack rested solely on Workers, a serverless application platform. My prior experiences building web applications used servers that require the deployment of a server built using Express and Node.js, whereas for my internship project, I completely relied on a backend built using the <i>itty-router</i> library on Workers to interface with the publicly available Cloudflare APIs. I found this extremely exciting as building a serverless application required less overhead compared to setting up a server and deploying it, and using Workers itself has many other added benefits such as zero cold starts. This introduction to serverless technology and my experience deep-diving into the capabilities of Workers has really opened my eyes to the possibilities that Workers as a platform can offer. With Workers, you can deploy any application on Cloudflare’s global network like I did!</p><p>For the frontend of the web application, I used React and the Chakra-UI library to build the user interface for which the Zone Viewer, Zone Comparison, and Zone Copier, is based on. The routing between different pages was done using React Router and the application is deployed directly through Workers.</p><p>Here is a screenshot of the application:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/16b1r6p12eWbtss72II7Qp/179b2d8d5e6f019927fb14f42d2fe8b9/unnamed--1--1.png" />
            
            </figure>
    <div>
      <h3>Presenting the prototype application</h3>
      <a href="#presenting-the-prototype-application">
        
      </a>
    </div>
    <p>As developers will know, the best way to obtain feedback for the tool that you’re building is to directly have your customers use them and let you know what they think of your application and the kind of features they want to have built on top of it. Therefore, once we had a prototype version of the web application for the Zone Viewer and Zone Comparison complete, we presented the application to the Solutions Engineering team to hear their thoughts on the impact the tool would have on their work and additional features they would like to see built on the application. I found this process very enriching as they collectively mentioned how impactful the application would be for their work and the value add this project provides to them.</p><p>Some interesting feedback and feature requests I received were:</p><ol><li><p>The Zone Copier would definitely be very useful for our partners who have to replicate the configuration of one zone to another regularly, and it's definitely going to help make sure there are less human errors in the process of configuring the setups.</p></li><li><p>Besides duplicating configurations from zone-to-zone, could we use this to replicate the configurations from a best-in-class setup for different use cases and allow partners to deploy this with a few clicks?</p></li><li><p>Can we use this tool to generate quarterly reports?</p></li><li><p>The Zone Viewer would be very helpful for us when we produce documentation on a particular zone's configuration as part of a POC report.</p></li><li><p>The Zone Viewer will also give us much deeper insight to better understand the current zone configurations and provide recommendations to improve it.</p></li></ol><p>It was also a very cool experience speaking to the broad Solutions Engineering team as I found that many were very technically inclined and had many valid suggestions for improving the architecture and development of the applications. A special thanks to Edwin Wong for setting up the sharing session with the internal team, and many thanks to Xin Meng, AQ Jiao, Yonggil Choi, Steve Molloy, Kyouhei Hayama, Claire Lim and Jamal Boutkabout for their great insight and suggestions!</p>
    <div>
      <h3>Impact of Cloudflare outside of work</h3>
      <a href="#impact-of-cloudflare-outside-of-work">
        
      </a>
    </div>
    <p>While Cloudflare is known for its impeccable transparency throughout the company, and the stellar products it provides in helping make the Internet better, I wanted to take this opportunity to talk about the other endeavors that the company has too.</p><p>Cloudflare is part of the <i>Pledge 1%</i>, where the company dedicates 1% of products and 1% of our time to give back to the local communities as well as all the communities we support online around the world.</p><p>I took part in one of these activities, where we spent a morning cleaning up parts of the East Coast Park beach, by picking up trash and litter that had been left behind by other park users. Here’s a picture of us from that morning:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/nWGrYqbAAsLJPc3WZJeY4/0d6307697440567dcc2c5bd721d9e1de/image1-50.png" />
            
            </figure><p>From day one, I have been thoroughly impressed by Cloudflare’s commitment to its culture and the effort everyone at Cloudflare puts in to make the company a great place to work and have a positive impact on the surrounding community.</p><p>In addition to giving back to the community, other aspects of company culture include having a good team spirit and safe working environment where you feel appreciated and taken care of. At Cloudflare, I have found that everyone is very understanding of work commitments. I faced a few challenges during the internship where I had to spend additional time on university related projects and work, and my manager has always been very supportive and understanding if I required additional time to complete parts of the internship project.</p>
    <div>
      <h3>Concluding takeaways</h3>
      <a href="#concluding-takeaways">
        
      </a>
    </div>
    <p>My experience interning at Cloudflare has been extremely positive, and I have seen first hand how transparent the company is with not only its employees but also its customers, and it truly is a great place to work. Cloudflare’s collaborative culture allowed me to access members from different teams, to obtain their thoughts and assistance with certain issues that I faced from time to time. I would not have been able to produce an impactful project without the help of the different brilliant, and motivated, people I worked with across the span of the internship, and I am truly grateful for such a rewarding experience.</p><p>We are getting ready to open intern roles for this coming Fall, so we encourage you to visit our <a href="https://www.cloudflare.com/careers/jobs/">careers page</a> frequently, to be up-to-date on all the opportunities we have within our teams.</p> ]]></content:encoded>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Internship Experience]]></category>
            <category><![CDATA[Careers]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <guid isPermaLink="false">cdNWCBRsKMUBhHTzG5xer</guid>
            <dc:creator>Ulysses Kee</dc:creator>
        </item>
        <item>
            <title><![CDATA[Dark Mode for the Cloudflare Dashboard]]></title>
            <link>https://blog.cloudflare.com/dark-mode/</link>
            <pubDate>Wed, 29 Sep 2021 12:59:34 GMT</pubDate>
            <description><![CDATA[ Dark mode is now available for the Cloudflare Dashboard in beta! From your user profile, you can configure the Cloudflare Dashboard in light mode, dark mode, or match it to your system settings. ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/61QiOeplrC8eEpodCYr3Vm/db254c79029a092fa9e18903825f65f1/image1-42.png" />
            
            </figure><p>Today, dark mode is available for the Cloudflare Dashboard in beta! From your <a href="https://dash.cloudflare.com/profile">user profile</a>, you can configure the Cloudflare Dashboard in light mode, dark mode, or match it to your system settings.</p><p>For those unfamiliar, dark mode, or light on dark color schemes, uses light text on dark backgrounds instead of the typical dark text on light (usually white) backgrounds. In low-light environments, this can help reduce eyestrain and actually reduce power consumption on OLED screens. For many though, dark mode is simply a preference supported widely by applications and devices.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/58dMu82Wo7DpdqOHsoh66s/15cc1b33d43d29b2d5579751676b81a6/image13-6.png" />
            
            </figure><p>Side by side comparing the Cloudflare dashboard in dark mode and in light mode</p>
    <div>
      <h3>How to enable dark mode</h3>
      <a href="#how-to-enable-dark-mode">
        
      </a>
    </div>
    <ol><li><p>Log into Cloudflare.</p></li><li><p>Go to your <a href="https://dash.cloudflare.com/profile">user profile</a>.</p></li><li><p>Under <b>Appearance</b>, select an option: <i>Light</i>, <i>Dark</i>, or <i>Use system setting</i>. For the time being, your choice is saved into local storage.</p></li></ol>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1k9oNOhJL3UoE6f9bBgilf/04cbb0f7e715ad2fd5d21f659f839c55/image11-6.png" />
            
            </figure><p>The appearance card in the dashboard for modifying color themes</p><p>There are many primers and how-tos on implementing dark mode, and you can find articles talking about the general complications of implementing a dark mode including <a href="https://www.reddit.com/r/explainlikeimfive/comments/hq2s0z/eli5_why_did_it_take_so_much_time_to_introduce/">this straightforward explanation</a>. Instead, we will talk about what enabled us to be able to implement dark mode in only a matter of weeks.</p>
    <div>
      <h3>Cloudflare’s Design System - Our Secret Weapon</h3>
      <a href="#cloudflares-design-system-our-secret-weapon">
        
      </a>
    </div>
    <p>Before getting into the specifics of how we implemented dark mode, it helps to understand the system that underpins all product design and UI work at Cloudflare - the Cloudflare Design System.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2o0p4aO6GndFww4DkORffk/ff5c862d0f14a57b2c8e33d6e7ab8022/image6-22.png" />
            
            </figure><p>The six pillars of the design system: logo, typography, color, layout, icons, videos</p><p>Cloudflare’s Design System defines and documents the interface elements and patterns used to build products at Cloudflare. The system can be used to efficiently build consistent experiences for Cloudflare customers. In practice, the Design System defines primitives like typography, color, layout, and icons in a clear and standard fashion. What this means is that anytime a new interface is designed, or new UI code is written, an easily referenceable, highly detailed set of documentation is available to ensure that the work matches previous work. This increases productivity, especially for new employees, and prevents repetitious discussions about style choices and interaction design.</p><p>Built on top of these design primitives, we also have our own component library. This is a set of ready to use components that designers and engineers can combine to form the products our customers use every day. They adhere to the design system, are battle tested in terms of code quality, and enhance the user experience by providing consistent implementations of common UI components. Any button, table, or chart you see looks and works the same because it <i>is</i> the same underlying code with the relevant data changed for the specific use case.</p><p>So, what does all of this have to do with dark mode? Everything, it turns out. Due to the widespread adoption of the design system across the dashboard, changing a set of variables like background color and text color in a specific way and seeing the change applied nearly everywhere at once becomes much easier. Let’s take a closer look at how we did that.</p>
    <div>
      <h3>Turning Out the Lights</h3>
      <a href="#turning-out-the-lights">
        
      </a>
    </div>
    <p>The use of color at Cloudflare has a well documented history. When we originally set out to build our color system, the <a href="https://color.cloudflare.design">tools we built</a> and the extensive <a href="/thinking-about-color/">research we performed</a> resulted in a ten-hue, ten-luminosity set of colors that can be used to build digital products. These colors were built to be accessible — not just in terms of internal use, but for our customers. Take our blue hue scale, for example.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3PGzm1z3tMdVi7DymNP7uP/1e38bb546fd274bc4349d946466e7e77/image10-6.png" />
            
            </figure><p>Our blue color scale, as used on the Cloudflare Dashboard. This shows color-contrast accessible text and background pairings for each step in the scale.</p><p>Each hue in our color scale contains ten colors, ordered by luminosity in ten increasing increments from low luminosity to high luminosity. This color scale allows us to filter down the choice of color from the 16,777,216 hex codes available on the web to a much simpler choice of just hue and brightness. As a result, we now have a methodology where designers know the first five steps in a scale have sufficient color contrast with white or lighter text, and the last five steps in a scale have sufficient contrast with black or darker text.</p><p>Color scales also allow us to make changes while designing in a far more fluid fashion. If a piece of text is too bright relative to its surroundings, drop down a step on the scale. If an element is too visually heavy, take a step-up. With the Design System and these color scales in place, we’ve been able to design and ship products at a rapid rate.</p><p>So, with this color system in place, how do we begin to ship a dark mode? It turns out there’s a simple solution to this, and it’s built into the JS standard library. We call <code>reverse()</code> and flip the luminosity scales.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/GUZ9MW5PKQYsaTCDWrL8n/d893975cdc0d3783366ae5ec8cc1f7ae/image12-8.png" />
            
            </figure><p>Our blue color scale after calling reverse on it. High luminosity colors are now at the start of the scale, making them contrast accessible with darker backgrounds (and vice-versa).</p><p>By performing this small change within our dashboard’s React codebase and shipping a production preview deploy, we were able to see the Cloudflare Dashboard in dark mode with a whole new set of colors in a matter of minutes.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3n0vUwjdzCS1IWjvK0487K/83aae923cb84ec67ce50ef45779e2c20/image7-9.png" />
            
            </figure><p>An early preview of the Cloudflare Dashboard after flipping our color scales.</p><p>While not perfect, this brief prototype gave us an incredibly solid baseline and validated the approach with a number of benefits.</p><p>Every product built using the Cloudflare Design System now had a dark mode theme built in for free, with no additional work required by teams.</p><p>Our color contrast principles remain sound — just as the first five colors in a scale would be accessible with light text, when flipped, the first five colors in the scale are accessible with dark text. Our scales aren’t perfectly symmetrical, but when using white and black, the principle still holds.</p><p>In a traditional approach of “inverting” colors, we face the issue of a color’s hue being changed too. When a color is broken down into its constituent hue, saturation, and luminosity values, inverting it would mean a vibrant light blue would become a dull dark orange. Our approach of just inverting the luminosity of a color means that we retain the saturation and hue of a color, meaning we retain Cloudflare’s brand aesthetic and the associated meaning of each hue (blue buttons as calls-to-action, and so on).</p><p>Of course, shipping a dark mode for a product as complex as the Cloudflare Dashboard can’t just be done in a matter of minutes.</p>
    <div>
      <h3>Not Quite Just Turning the Lights Off</h3>
      <a href="#not-quite-just-turning-the-lights-off">
        
      </a>
    </div>
    <p>Although our prototype did meet our initial requirements of facilitating the dashboard in a dark theme, some details just weren’t quite right. The data visualization and mapping libraries we use, our icons, text, and various button and link states all had to be audited and required further iterations. One of the most obvious and prominent examples was the page background color. Our prototype had simply changed the background color from white (#FFFFFF) to black (#000000). It quickly became apparent that black wasn’t appropriate. We received feedback that it was “too intense” and “harsh.” We instead opted for off black, specifically what we refer to as “gray.0” or #1D1D1D. The difference may not seem noticeable, but at larger dimensions, the gray background is much less distracting.</p><p>Here is what it looks like in our design system:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/53o6OTIT1cBmThMDNR0aXP/43f973ef4ab2ebbe615ec3e86b0bc7f0/image9-7.png" />
            
            </figure><p>Black background color contrast for white text</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3083uB7mi7KPoGzbGldGJY/ba3a68d98618794e1117428f2c9aee7d/image8-8.png" />
            
            </figure><p>Gray background color contrast for white text</p><p>And here is a more realistic example:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/S5q4EXp6VFsU65wupcmwG/ba61887437a4a331b18d3a7a7afb6df7/image4-27.png" />
            
            </figure><p>lorem ipsum sample text on black background and on gray background</p><p>The numbers at the end of each row represent the contrast of the text color on the background. According to the Web Content Accessibility Guidelines (<a href="https://www.w3.org/WAI/standards-guidelines/wcag/">WCAG</a>), the <a href="https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html">standard contrast ratio for text</a> should be at least 4.5:1. In our case, while both of the above examples exceed the standard, the gray background ends up being less harsh to use across an entire application. This is not the case with light mode as dark text on white (#FFFFFF) background works well.</p><p>Our technique during the prototyping stage involved flipping our color scale; however, we additionally created a tool to let us replace any color within the scale arbitrarily. As the dashboard is made up of charts, icons, links, shadows, buttons and certainly other components, we needed to be able to see how they reacted in their various possible states. Importantly, we also wanted to improve the accessibility of these components and pay particular attention to color contrast.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7DN7Nzw7yW5WKtQXWpfej9/fabb6d2b18a3ac4aa438a5048a765b75/image5-24.png" />
            
            </figure><p>Color picker tool screenshot showing a color scale</p><p>For example, a button is made up of four distinct states:</p><ol><li><p>Default</p></li><li><p>Focus</p></li><li><p>Hover</p></li><li><p>Active</p></li></ol>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3JApmRD2XeF5fhAzjaGCdn/ef0764d345c51fbfea035f637317eb02/image2-44.png" />
            
            </figure><p>Example showing the various colors for states of buttons in light and dark mode</p><p>We wanted to ensure that each of these states would be at least compliant with the AA accessibility standards according to the WCAG. Using a combination of our design systems documentation and a prioritized list of components and pages based on occurrence and visits, we meticulously reviewed each state of our components to ensure their compliance.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1SoATB16O1z2em0u7nfoUq/94a29e459c22bf049d53dfb370a7f730/image3-34.png" />
            
            </figure><p>Side by side comparison of the navbar in light and dark modes</p><p>The navigation bar used to select between the different applications was a component we wanted to treat differently compared to light mode. In light mode, the app icons are a solid blue with an outline of the icon; it’s a distinct look and certainly one that grabs your attention. However, for dark mode, the consensus was that it was too bright and distracting for the overall desired experience. We wanted the overall aesthetic of dark mode to be subtle, but it’s important to not conflate aesthetic with poor usability. With that in mind, we made the decision for the navigation bar to use outlines around each icon, instead of being filled in. Only the selected application has a filled state. By using outlines, we are able to create sufficient contrast between the current active application and the rest. Additionally, this provided a visually distinct way to present hover states, by displaying a filled state.</p><p>After applying the same methodology as described to other components like charts, icons, and links, we end up with a nicely tailored experience without requiring a substantial overhaul of our codebase. For any new UI that teams at Cloudflare build going forward, they will not have to worry about extra work to support dark mode. This means we get an improved customer experience without any impact to our long term ability to keep delivering amazing new capabilities — that’s a win-win!</p>
    <div>
      <h3>Welcome to the Dark Side</h3>
      <a href="#welcome-to-the-dark-side">
        
      </a>
    </div>
    <p>We know many of you have been asking for this, and we are excited to bring dark mode to all. Without the investment into our design system by many folks at Cloudflare, dark mode would not have seen the light of day. You can enable dark mode on the <b>Appearance</b> card in your <a href="https://dash.cloudflare.com/profile">user profile</a>. You can give feedback to shape the future of the dark theme with the feedback form in the card.</p><p>If you find these types of problems interesting, come help us tackle them! We are hiring across <a href="https://boards.greenhouse.io/cloudflare/jobs/3120477?gh_jid=3120477">product</a>, <a href="https://boards.greenhouse.io/cloudflare/jobs/3421232?gh_jid=3421232`">design</a>, and <a href="https://boards.greenhouse.io/cloudflare/jobs/3192227?gh_jid=3192227">engineering</a>!</p> ]]></content:encoded>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Dashboard]]></category>
            <guid isPermaLink="false">4uk8qSO6sWdJa2f9qzpwki</guid>
            <dc:creator>Garrett Galow</dc:creator>
            <dc:creator>Syeef Karim</dc:creator>
            <dc:creator>Harley Turan</dc:creator>
        </item>
        <item>
            <title><![CDATA[Introducing logs from the dashboard for Cloudflare Workers]]></title>
            <link>https://blog.cloudflare.com/introducing-workers-dashboard-logs/</link>
            <pubDate>Tue, 24 Aug 2021 14:00:00 GMT</pubDate>
            <description><![CDATA[ Many developers know the feeling: “It worked in the local testing suite, it worked in our staging environment, but… it’s broken in production?” Testing can reduce mistakes and debugging can help find them, but logs give us the tools to understand and improve what we are creating. ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2Mixl8Zirzu4SzNfiqgXgm/a7c1855d9797cf5d815d61d4cf53e735/Workers-Observability-Shim-Github-Header.png" />
            
            </figure><p>If you’re writing code: what can go wrong, will go wrong.</p><p>Many developers know the feeling: “It worked in the local testing suite, it worked in our staging environment, but… it’s broken in production?” Testing can reduce mistakes and debugging can help find them, but logs give us the tools to understand and improve what we are creating.</p>
            <pre><code>if (this === undefined) {
  console.log("there’s no way… right?") // Narrator: there was.
}</code></pre>
            <p>While logging can help you understand when the seemingly impossible is actually possible, it’s something that no developer really wants to set up or maintain on their own. That’s why we’re excited to launch a new addition to the Cloudflare Workers platform: logs and exceptions from the dashboard.</p><p>Starting today, you can view and filter the <code>console.log</code> output and exceptions from a Worker… at no additional cost with no configuration needed!</p>
    <div>
      <h3>View logs, just a click away</h3>
      <a href="#view-logs-just-a-click-away">
        
      </a>
    </div>
    <p>When you view a Worker in the dashboard, you’ll now see a “Logs” tab which you can click on to view a detailed stream of logs and exceptions. Here’s what it looks like in action:</p><div></div>
<p></p><p>Each log entry contains an event with a list of logs, exceptions, and request headers if it was triggered by an HTTP request. We also automatically redact sensitive URLs and headers such as Authorization, Cookie, or anything else that appears to have a sensitive name.</p><p>If you are in the Durable Objects <a href="/durable-objects-open-beta/">open beta</a>, you will also be able to view the logs and requests sent to <i>each</i> Durable Object. This is a great tool to help you understand and debug the interactions between your Worker and a Durable Object.</p><p>For now, we support filtering by event status and type. Though, you can expect more filters to be added to the dashboard very soon! Today, we support advanced filtering with the wrangler CLI, which will be discussed later in this blog.</p>
    <div>
      <h3>console.log(), and you’re all set</h3>
      <a href="#console-log-and-youre-all-set">
        
      </a>
    </div>
    <p>It’s really simple to get started with logging for Workers. Simply invoke one of the standard <a href="https://developer.mozilla.org/en-US/docs/Web/API/console">console</a> APIs, such as <code>console.log()</code>, and we handle the rest. That’s it! There’s no extra setup, no configuration needed, and no hidden logging fees.</p>
            <pre><code>function logRequest (request) {
  const { cf, headers } = request
  const { city, region, country, colo, clientTcpRtt  } = cf
  
  console.log("Detected location:", [city, region, country].filter(Boolean).join(", "))
  if (clientTcpRtt) {
     console.debug("Round-trip time from client to", colo, "is", clientTcpRtt, "ms")
  }

  // You can also pass an object, which will be interpreted as JSON.
  // This is great if you want to define your own structured log schema.
  console.log({ headers })
}</code></pre>
            <p>In fact, you don’t even need to use <code>console.log</code> to view an event from the dashboard. If your Worker doesn’t generate any logs or exceptions, you will still be able to see the request headers from the event.</p>
    <div>
      <h3>Advanced filters, from your terminal</h3>
      <a href="#advanced-filters-from-your-terminal">
        
      </a>
    </div>
    <p>If you need more advanced filters you can use <a href="https://github.com/cloudflare/wrangler">wrangler</a>, our command-line tool for deploying Workers. We’ve updated the <code>wrangler tail</code> command to support sampling and a new set of advanced filters. You also no longer need to install or configure <code>cloudflared</code> to use the command. Not to mention it’s <i>much</i> faster, no more waiting around for logs to appear. Here are a few examples:</p>
            <pre><code># Filter by your own IP address, and if there was an uncaught exception.
wrangler tail --format=pretty --ip-address=self --status=error

# Filter by HTTP method, then apply a 10% sampling rate.
wrangler tail --format=pretty --method=GET --sampling-rate=0.1

# Filter using a generic search query.
wrangler tail --format=pretty --search="TypeError"</code></pre>
            <p>We recommend using the “pretty” format, since wrangler will output your logs in a colored, human-readable format. (We’re also working on a similar display for the dashboard.)</p><div></div>
<p></p><p>However, if you want to access structured logs, you can use the “json” format. This is great if you want to pipe your logs to another tool, such as <a href="https://stedolan.github.io/jq/tutorial/">jq</a>, or save them to a file. Here are a few more examples:</p>
            <pre><code># Parses each log event, but only outputs the url.
wrangler tail --format=json | jq .event.request?.url

# You can also specify --once to disconnect the tail after receiving the first log.
# This is useful if you want to run tests in a CI/CD environment.
wrangler tail --format=json --once &gt; event.json</code></pre>
            
    <div>
      <h3>Try it out!</h3>
      <a href="#try-it-out">
        
      </a>
    </div>
    <p>Both logs from the dashboard and <code>wrangler tail</code> are available and free for existing Workers customers. If you would like more information or a step-by-step guide, check out any of the resources below.</p><ul><li><p>Go to the <a href="https://dash.cloudflare.com?to=/:account/workers/overview">dashboard</a> and look at some logs!</p></li><li><p>Read the <a href="https://developers.cloudflare.com/workers/learning/logging-workers">getting started</a> guide for logging.</p></li><li><p>Look at the tail logs API <a href="https://api.cloudflare.com/#worker-tail-logs-properties">reference</a>.</p></li></ul> ]]></content:encoded>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Logs]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Wrangler]]></category>
            <guid isPermaLink="false">4YuFI6zhgNP0dnoJv7d0NH</guid>
            <dc:creator>Ashcon Partovi</dc:creator>
        </item>
        <item>
            <title><![CDATA[ClickHouse Capacity Estimation Framework]]></title>
            <link>https://blog.cloudflare.com/clickhouse-capacity-estimation-framework/</link>
            <pubDate>Thu, 05 Nov 2020 14:12:48 GMT</pubDate>
            <description><![CDATA[ We use ClickHouse widely at Cloudflare. It helps us with our internal analytics workload, bot management, customer dashboards, and many other systems.  ]]></description>
            <content:encoded><![CDATA[ <p>We use ClickHouse widely at Cloudflare. It helps us with our internal analytics workload, bot management, customer dashboards, and many other systems. For instance, before <a href="/cloudflare-bot-management-machine-learning-and-more/">Bot Management</a> can analyze and classify our traffic, we need to collect logs. The <a href="/updates-to-firewall-analytics/">Firewall Analytics tool</a> needs to store and query data somewhere too. The same goes for our new <a href="/introducing-cloudflare-radar/">Cloudflare Radar project</a>. We are using ClickHouse for this purpose. It is a big database that can store <a href="https://www.cloudflare.com/learning/ai/big-data/">huge amounts of data</a> and return it on demand. This is not the first time we have talked about ClickHouse, there is a <a href="/http-analytics-for-6m-requests-per-second-using-clickhouse/">dedicated blogpost</a> on how we introduced ClickHouse for HTTP analytics.</p><p>Our biggest cluster has more than 100 nodes, another one about half that number. Besides that, we have over 20 clusters that have at least three nodes and the replication factor of three. Our current insertion rate is about 90M rows per second.</p><p>We use the standard approach in ClickHouse schema design. At the top level we have clusters, which hold shards, a group of nodes, and a node is a physical machine. You can find technical characteristics of the nodes <a href="/http-analytics-for-6m-requests-per-second-using-clickhouse/">here</a>. Stored data is replicated between clusters. Different shards hold different parts of the data, but inside of each shard replicas are equal.</p><p>Schema of one cluster:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/23qnFNyui1KHob8huAzcyz/fc936b0a27e145859e37e9e6a762d57d/image1-1.jpg" />
            
            </figure>
    <div>
      <h3>Capacity planning</h3>
      <a href="#capacity-planning">
        
      </a>
    </div>
    <p>As engineers, we periodically face the question of how many additional nodes we have to order to support the growing demand for the next X months, with disk space as our prime concern.</p><p>ClickHouse stores extensive information in system tables about the operating processes, which is helpful. From the early days of using ClickHouse we added <a href="https://github.com/f1yegor/clickhouse_exporter">clickhouse_exporter</a> as part of our monitoring stack. One of the metrics we are interested in is exposed from the <a href="https://clickhouse.tech/docs/en/operations/system-tables/parts/">system.parts</a> table. Roughly speaking, clickhouse_exporter runs <a href="https://github.com/f1yegor/clickhouse_exporter/blob/master/exporter/exporter.go#L53">SQL queries</a> asking how many bytes are used by each table. After that, these metrics are sent from Prometheus to <a href="https://thanos.io/">Thanos</a> and stored for at least a year.</p><p>Every time we wanted to make a forecast of disk usage we queried Thanos for historical data using this expression:</p><p><code>sum by (table) (clickhouse_table_parts_bytes{cluster="{cluster}"})</code></p><p>After that, we uploaded data in <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html">dataframes</a> to a <a href="https://jupyter.org/">Jupyter notebook</a>.</p><p>There were a few problems with this approach. Only a few people knew where the notebooks were and how to get them running. It wasn't trivial to download historical data. And most importantly, it was hard to look at past predictions and assess whether or not they were correct since results were not stored anywhere except internal blog posts. Also, as the number and size of clusters and products grew it became impossible for a single team to work on capacity planning and we needed to get engineers building products involved as they have the most context on how the growth will change in the future.</p><p>We wanted to automate this process and made calculations more transparent for our colleagues, including those who use ClickHouse for their services. Honestly, at the beginning we weren’t sure if it was even possible and what we would get out of it.</p>
    <div>
      <h3>Finding the right metrics</h3>
      <a href="#finding-the-right-metrics">
        
      </a>
    </div>
    <p>The crucial moment of adding new nodes for us is a disk space, so this was a place to start. We decided to use <i>system.parts,</i> as we used it before with the manual approach.</p><p>Luckily, we started doing it for the cluster that had recently changed its topology. That cluster had <i>two shards with four and five nodes in every shard</i>. After the topology change, it was replaced <i>with three shards and three nodes in every shard</i>, but the number of machines and unreplicated data on the disks remained the same. However, it had an impact on our metrics: we previously had four replicated nodes in one shard and five replicated in another, we took one node off from the first shard and two nodes from the second and created a new one based on these three nodes. The new shard was empty, so we just added it, but the total amount of data in the first and the second shards was less as the count of the remaining nodes.</p><p>You can see on the graph below in April we had this sharp decrease caused by topology changes. We got ~550T instead of ~850T among all shards and replicas.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/51i2Mc9wdPJHZp3EggeTOg/c8d87927bd4426424f8930b4493077cc/image3-1.png" />
            
            </figure><p>When we tried to train our model based on the real data due to the April drop it thought we had a downward trend. Which was incorrect as we only dropped replicated data. The trend for unreplicated data hadn’t changed. So we decided to take into account only unreplicated data. It saved us from the topology change and node replacement in case of problems with hardware.</p><p>The rule that we use for metrics now is:</p>
            <pre><code>sum by(cluster) (
max by (cluster, shardgroup) (
node_clickhouse_shardgroupinfo{} *
on (instance) group_right (cluster, shardgroup) sum(table_parts_bytes{cluster="%s"}) by (instance)
))</code></pre>
            <p>We continue using <i>system.parts</i> from clickhouse_exporter, but instead of counting the whole amount of data we use the maximum of unreplicated data from every shard.</p><p>In the image below there is the same cluster as in the image above but instead of counting the whole amount of data we look at unreplicated data from all shards. You can clearly see that we continued to grow and didn’t have any drop in data.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2G1I3E5f1VWtIcqVmSCABV/12bc544b71ff7c8ba12ac9466b68303a/image2-1.png" />
            
            </figure><p>Another problem we faced was that we migrated some tables from one cluster to another because we were running out of space and it required immediate action. However, our model didn’t know that part of the tables didn’t live there anymore, and we didn’t want them to be a part of the prediction. To solve this problem we queried Prometheus to get the list of the tables that existed at the prediction time, then filtered historical data to include only these tables and used them as the input for training a model.</p>
    <div>
      <h3>Load of metrics</h3>
      <a href="#load-of-metrics">
        
      </a>
    </div>
    <p>After determining the correct metrics, we needed to obtain them for our forecasting procedure. Our long-term metrics solution, Thanos, stores billions of data points. Querying it for a cluster with over one hundred nodes even for one day takes a huge amount of time, and we needed these data points for a year.</p><p>As we planned to use Python we wrote a small client using <a href="https://docs.aiohttp.org/">aiohttp</a> that concurrently sends HTTP requests to Thanos. The requests are sent in chunks, and every request has start/end dates with a difference of one hour. We needed to get the data for the whole year once and then append new ones day by day. We got csv files: one file for one cluster. The client became a part of the project, and it runs once a day, queries Thanos for new metrics (previous day) and appends data to the files.</p>
    <div>
      <h3>Forecasting procedure</h3>
      <a href="#forecasting-procedure">
        
      </a>
    </div>
    <p>At this point, we have collected metrics in files, now it’s time to make a forecast. We needed something for time-series metrics, so we chose <a href="https://facebook.github.io/prophet/">Prophet</a> from Facebook. It’s very simple to use, you can follow the documentation and get good results even with the default parameters.</p><p>One challenge we faced using Prophet was the need to feed it one data point for a day. In the metric files we have thousands of those for every day. It looks logical to take the point at the end of every day, but it’s not really true. All tables have a retention period, the time for how long we store data in ClickHouse. We don’t know when the data is cleared, it happens gradually throughout the day. So, we decided to take the maximum number for a day.</p>
    <div>
      <h3>Drawing Graphs</h3>
      <a href="#drawing-graphs">
        
      </a>
    </div>
    <p>We chose <a href="https://grafana.com/">Grafana</a> to present results, though we needed to store predicted data points somewhere. The first thought was to use Prometheus, but because of high cardinality, we had about 300,000 points in summary for clusters and tables, so we passed. We decided to use ClickHouse itself. We wanted to have both graphs, real and predicted, on the same dashboard. We had real data points in Prometheus and with <a href="https://grafana.com/docs/grafana/latest/features/datasources/">mixed data source</a> could do this. However, the problem was the same as the loading of metrics into files, for some clusters it’s impossible to obtain metrics for a long period of time. We added functionality to upload real metrics in ClickHouse as well, now both real and predicted metrics are displayed in Grafana, taken from ClickHouse.</p>
    <div>
      <h3>Summary</h3>
      <a href="#summary">
        
      </a>
    </div>
    <p>This is what we have in Grafana:</p><ul><li><p>The yellow line shows the real data;</p></li><li><p>The green line was created based on Prophet output;</p></li><li><p>The red line - the maximum disk capacity. We already increased it twice.</p></li></ul>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6ehYaDioxFUKBtEAAlexZ3/5b35969d2b1edb125ddb75997f197847/image4-1.png" />
            
            </figure><p>We have a service running in Kubernetes that does all the toil, and we created an environment for other metrics. We have the place where we collect metrics from Thanos and expose them in the required format to Grafana. If we find the right metrics for accounting other resources like IO, CPU or other systems like Kafka we can easily add them to our framework. We can easily replace Prophet with another algorithm, and we can go back months and evaluate how close we were in our prediction according to the real data.</p><p>With this automation we were able to spot we were going out of disk space for a couple of clusters which we didn’t expect. We have over 20 clusters and have updates for all of them every day. This dashboard is used not only by our colleagues who are direct customers of ClickHouse but by the team who makes a plan for buying servers. It is easy to read and costs none of developers time.</p><p>This project was carried out by the Core SRE team to improve our daily work. If you are interested in this project, check out our <a href="https://www.cloudflare.com/careers/jobs/">job openings</a>.</p><p>We didn’t know what we would get at the end, we discussed, looked for solutions and tried different approaches. Huge thanks for this to Nicolae Vartolomei, Alex Semiglazov and John Skopis.</p> ]]></content:encoded>
            <category><![CDATA[Analytics]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[ClickHouse]]></category>
            <guid isPermaLink="false">6nEOTtbnBBKfaHL4eViiRQ</guid>
            <dc:creator>Oxana Kharitonova</dc:creator>
        </item>
        <item>
            <title><![CDATA[Internationalizing the Cloudflare Dashboard]]></title>
            <link>https://blog.cloudflare.com/internationalizing-the-cloudflare-dashboard/</link>
            <pubDate>Thu, 23 Jul 2020 11:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare’s dashboard now supports four new language: Spanish (with country-specific locales: Chile, Ecuador, Mexico, Peru, and Spain), Brazilian Portuguese, Korean, and Traditional Chinese.  ]]></description>
            <content:encoded><![CDATA[ <p><a href="https://dash.cloudflare.com/sign-up">Cloudflare’s dashboard</a> now supports four new languages (and multiple locales): Spanish (with country-specific locales: Chile, Ecuador, Mexico, Peru, and Spain), Brazilian Portuguese, Korean, and Traditional Chinese. Our customers are global and diverse, so in helping build a better Internet for everyone, it is imperative that we bring our products and services to customers in their native language.</p><p>Since last year Cloudflare has been hard at work internationalizing our dashboard. At the end of 2019, we launched our first language other than US English: German. At the end of March 2020, we released three additional languages: French, Japanese, and Simplified Chinese. If you want to start using the dashboard in any of these languages, you can change your language preference in the top right of the Cloudflare dashboard. The preference selected will be saved and used across all sessions.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6bPkaBuSElf3KVstMxueBb/96fe21b0b376c22d3ebdaa8395bf4e5e/image1-13.png" />
            
            </figure><p>In this blog post, I want to help those unfamiliar with internationalization and localization to better understand how it works. I also would like to tell the story of how we made internationalizing and localizing our application a standard and repeatable process along with sharing a few tips that may help you as you do the same.</p>
    <div>
      <h3>Beginning the journey</h3>
      <a href="#beginning-the-journey">
        
      </a>
    </div>
    <p>The first step in internationalization is externalizing all the strings in your application. In concrete terms this means taking any text that could be read by a user and extracting it from your application code into separate, stand-alone files. This needs to be done for a few reasons:</p><ul><li><p>It enables translation teams to work on translating these strings without needing to view or change any application code.</p></li><li><p>Most translators typically use Translation Management applications which automate aspects of the workflow and provide them with useful utilities (like translation memory, change tracking, and a number of useful parsing and formatting tools). These applications expect standardized text formats (such as JSON, XML, MD, or CSV files).</p></li></ul><p>From an engineering perspective, separating application code from translations allows for making changes to strings without re-compiling and/or re-deploying code. In our React based application, externalizing most of our strings boiled down to changing blocks of code like this:</p>
            <pre><code>&lt;Button&gt;Cancel&lt;/Button&gt;
&lt;Button&gt;Next&lt;/Button&gt;</code></pre>
            <p>Into this:</p>
            <pre><code>&lt;Button&gt;&lt;Trans id="signup.cancel" /&gt;&lt;/Button&gt;
&lt;Button&gt;&lt;Trans id="signup.next" /&gt;&lt;/Button&gt;
 
// And in a separate catalog.json file for en_US:
{
 "signup.cancel": "Cancel",
 "signup.next": "Next",
 // ...many more keys
}</code></pre>
            <p>The <code>&lt;Trans&gt;</code> component shown above is the fundamental i18n building block in our application. In this scheme, translated strings are kept in large dictionaries keyed by a translation ID. We call these dictionaries “translation catalogs”, and there are a set of translation catalogs for each language that we support.</p><p>At runtime, the <code>&lt;Trans&gt;</code> component looks up the translation in the correct catalog for the provided key and then inserts this translation into the page (via the DOM). All of an application's static text can be externalized with simple transformations like these.</p><p>However, when dynamic data needs to be intermixed with static text, the solution becomes a little more complicated. Consider the following seemingly straightforward example which is riddled with i18n landmines:</p>
            <pre><code>&lt;span&gt;You've selected { totalSelected } Page Rules.&lt;/span&gt;</code></pre>
            <p>It may be tempting to externalize this sentence by chopping it up into a few parts, like so:</p>
            <pre><code>&lt;span&gt;
 &lt;Trans id="selected.prefix" /&gt; {totalSelected } &lt;Trans id="pageRules" /&gt;
&lt;/span&gt;
 
// English catalog.json
{
 "selected.prefix": "You've selected",
 "pageRules": "Page Rules",
 // ...
}
 
// Japanese catalog.json
{
 "selected.prefix": "選択しました",
 "pageRules": "ページ ルール",
 // ...
}
 
// German catalog.json
{
 "selected.prefix": "Sie haben ausgewählt",
 "pageRules": "Page Rules",
 // ...
}
 
// Portuguese (Brazil) catalog.json
{
 "selected.prefix": "Você selecionou",
 "pageRules": "Page Rules",
 // ...
}
</code></pre>
            <p>This gets the job done and may even seem like an elegant solution. After all, both the <code>selected.prefix</code> and <code>pageRules.suffix</code> strings seem like they are destined to be reused. Unfortunately, chopping sentences up and then concatenating translated bits back together like this turns out to be the single largest pitfall when externalizing strings for internationalization.</p><p>The problem is that when translated, the various words that make up a sentence can be <a href="https://en.wikipedia.org/wiki/Inflection">morphed in different ways</a> based on context (singular vs plural contexts, due to word gender, subject/verb agreement, etc). This varies significantly from language to language, as does <a href="https://en.wikipedia.org/wiki/Word_order">word order</a>. For example in English, the sentence “We like them” follows a subject-verb-object order, while other languages might follow subject-object-verb (We them like), verb-subject-object (Like we them), or even other orderings. Because of these nuanced differences between languages, concatenating translated phrases into a sentence will almost always lead to localization errors.</p><p>The code example above contains actual translations we got back from our translation teams when we supplied them with “You’ve selected” and “Page Rules” as separate strings. Here’s how this sentence would look when rendered in the different languages:</p><table><tr><td><p><b>Language</b></p></td><td><p><b>Translation</b></p></td></tr><tr><td><p>Japanese</p></td><td><p>選択しました { totalSelected } ページ ルール。</p></td></tr><tr><td><p>German</p></td><td><p>Sie haben ausgewählt { totalSelected } Page Rules</p></td></tr><tr><td><p>Portuguese (Brazil)</p></td><td><p>Você selecionou { totalSelected } Page Rules.</p></td></tr></table><p>To compare, we also gave them the sentence as a single string using a placeholder for the variable, and here’s the result:</p><table><tr><td><p><b>Language</b></p></td><td><p><b>Translation</b></p></td></tr><tr><td><p>Japanese</p></td><td><p>%{ totalSelected } 件のページ ルールを選択しました。</p></td></tr><tr><td><p>German</p></td><td><p>Sie haben %{ totalSelected } Page Rules ausgewählt.</p></td></tr><tr><td><p>Portuguese (Brazil)</p></td><td><p>Você selecionou %{ totalSelected } Page Rules.</p></td></tr></table><p>As you can see, the translations differ for Japanese and German. We’ve got a localization bug on our hands.</p><p>So, In order to guarantee that translators will be able to convey the true meaning of your text with fidelity, it's important to keep each sentence intact as a single externalized string. Our <code>&lt;Trans&gt;</code> component allows for easy injection of values into template strings which allows us to do exactly that:</p>
            <pre><code>&lt;span&gt;
  &lt;Trans id="pageRules.selectedForDeletion" values={{ count: totalSelected }} /&gt;
&lt;/span&gt;

// English catalog.json
{
  "pageRules.selected": "You've selected %{ count } Page Rules.",
  // ...
}

// Japanese catalog.json
{
  "pageRules.selected": "%{ count } 件のページ ルールを選択しました。",
  // ...
}

// German catalog.json
{
  "pageRules.selected": "Sie haben %{ count } Page Rules ausgewählt.",
  // ...
}

// Portuguese(Brazil) catalog.json
{
  "pageRules.selected": "Você selecionou %{ count } Page Rules.",
  // ...
}</code></pre>
            <p>This allows translators to have the full context of the sentence, ensuring that all words will be translated with the correct inflection.</p><p>You may have noticed another potential issue. What happens in this example when <code>totalSelected</code> is just 1? With the above code, the user would see “You've selected 1-Page Rules for deletion”. We need to conditionally pluralize the sentence based on the value of our dynamic data. This turns out to be a fairly common use case, and our <code>&lt;Trans&gt;</code> component handles this automatically via the <code>smart_count</code> feature:</p>
            <pre><code>&lt;span&gt;
  &lt;Trans id="pageRules.selectedForDeletion" values={{ smart_count: totalSelected }} /&gt;
&lt;/span&gt;

// English catalog.json
{
  "pageRules.selected": "You've selected %{ smart_count } Page Rule. |||| You've selected %{ smart_count } Page Rules.",
}

// Japanese catalog.json
{
  "pageRules.selected": "%{ smart_count } 件のページ ルールを選択しました。 |||| %{ smart_count } 件のページ ルールを選択しました。",
}

// German catalog.json
{
  "pageRules.selected": "Sie haben %{ smart_count } Page Rule ausgewählt. |||| Sie haben %{ smart_count } Page Rules ausgewählt.",
}

// Portuguese (Brazil) catalog.json
{
  "pageRules.selected": "Você selecionou %{ smart_count } Page Rule. |||| Você selecionou %{ smart_count } Page Rules.",
}</code></pre>
            <p>Here, the singular and plural versions are delimited by <code>||||</code>. <code>&lt;Trans&gt;</code> will automatically select the right translation to use depending on the value of the passed in <code>totalSelected</code> variable.</p><p>Yet another stumbling block occurs when markup is mixed in with a block of text we'd like to externalize as a single string. For example, what if you need some phrase in your sentence to be a link to another page?</p>
            <pre><code>&lt;VerificationReminder&gt;
  Don't forget to &lt;Link&gt;verify your email address.&lt;/Link&gt;
&lt;/VerificationReminder&gt;</code></pre>
            <p>To solve for this use case, the <code>&lt;Trans&gt;</code> component allows for arbitrary elements to be injected into placeholders in a translation string, like so:</p>
            <pre><code>&lt;VerificationReminder&gt;
  &lt;Trans id="notification.email_verification" Components={[Link]} componentProps={[{ to: '/profile' }]} /&gt;
&lt;/VerificationReminder&gt;

// catalog.json
{
  "notification.email_verification": "Don't forget to &lt;0&gt;verify your email address.&lt;/0&gt;",
  // ...
}</code></pre>
            <p>In this example, the <code>&lt;Trans&gt;</code> component will replace placeholder elements (&lt;0&gt;, &lt;1&gt;, etc.) with instances of the component type located at that index in the <code>Components</code> array. It also passes along any data specified in <code>componentProps</code> to that instance. The example above would boil down to the following in React:</p>
            <pre><code>// en-US
&lt;VerificationReminder&gt;
  Don't forget to &lt;Link to="/profile"&gt;verify your email address.&lt;/Link&gt;
&lt;/VerificationReminder&gt;

// es-ES
&lt;VerificationReminder&gt;
  No olvide &lt;Link to="/profile"&gt;verificar la dirección de correo electrónico.&lt;/Link&gt;
&lt;/VerificationReminder&gt;</code></pre>
            
    <div>
      <h3>Safety third!</h3>
      <a href="#safety-third">
        
      </a>
    </div>
    <p>The functionality outlined above was enough for us to externalize our strings. However, it did at times result in bulky, repetitive code that was easy to mess up. A couple of pitfalls quickly became apparent.</p><p>The first was that small hard-coded strings were now easier to hide in plain sight, and because they weren't glaringly obvious to a developer until the rest of the page had been translated, the feedback loop in finding these was often days or weeks. A common solution to surfacing these issues is introducing a pseudo-localization mode into your application during development which will transform all properly internationalized strings by replacing each character with a similar looking unicode character.</p><p>For example <code>You've selected 3 Page Rules.</code> might be transformed to <code>Ýôú'Ʋè ƨèℓèçƭèδ 3 Þáϱè Rúℓèƨ</code>.</p><p>Another handy feature at your disposal in a pseudolocalization mode is the ability to shrink or lengthen all strings by a fixed amount in order to plan for content width differences. Here's the same pseudo-localized sentence increased in length by 50%: <code>Ýôú'Ʋè ƨèℓèçƭèδ 3 Þáϱè Rúℓèƨ. ℓôřè₥ ïƥƨú₥ δô.</code> This is useful in helping both engineers and designers spot places where content length could potentially be an issue. We first recognized this problem when rolling out support for German, which at times tends to have somewhat longer words than English.</p><p>This meant that in a lot of places the text in page elements would overflow, such as in this "Add" button:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2DcZK0IiIXGAW4naCbxqCr/b60a50a967f9eec972dc0bb9da72e181/image4-7.png" />
            
            </figure><p>There aren't a lot of easy fixes for these types of problems that don't compromise the user experience.</p><p>For best results, variable content width needs to be baked into the design itself. Since fixing these bugs often means sending it back upstream to request a new design, the process tends to be time-consuming. If you haven't given much thought to content design in general, an internationalization effort can be a good time to start. Having standards and consistency around the copy used for various elements in your app can not only cut down on the number of words that need translating, but also eliminate the need to think through the content length pitfalls of using a novel phrase.</p><p>The other pitfall we ran into was that the translation IDs — especially long and repetitive ones — are highly susceptible to typos.</p><p>Pop quiz, which of these translation keys will break our app: <code>traffic.load_balancing.analytics.filters.origin_health_title</code> or <code>traffic.load_balancing.analytics.filters.origin_heath_title</code>?</p><p>Nestled among hundreds of other lines of changes, these are hard to spot in code review. Most apps have a fallback so missing translations don't result in a page breaking error. As a result a bug like this might go unnoticed entirely if it's hidden well enough (in say, a help text fly out).</p><p>Fortunately, with a growing percentage of our codebase in TypeScript, we were able to leverage the type-checker to give developers feedback as they wrote the code. Here’s an example where our code editor is helpfully showing us a red underline to indicate that the ID property is invalid (due to the missing “l”):</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2W5zNv5D1bIaPGPGjiDpE0/a9abde771093fb812573a2c7fb3d58ea/image5-4.png" />
            
            </figure><p>Not only did it make the problems more obvious, but it also meant that violations would cause builds to fail, preventing bad code from entering the codebase.</p>
    <div>
      <h3>Scaling locale files</h3>
      <a href="#scaling-locale-files">
        
      </a>
    </div>
    <p>In the beginning, you'll probably start out with one translation file per locale that you support. In addition, the naming scheme you use for your keys can remain somewhat simple. As your app scales, your translation file will grow too large and need to be broken up into separate files. Files that are too large will overwhelm Translation Management applications, or if left unchecked, your code editor. All of our translation strings (not including keys), when lumped together into a single file, is around 50,000 words. For comparison, that's roughly the same size as a copy of "The Hitchhiker's Guide to the Galaxy" or "Slaughterhouse Five".</p><p>We break up our translations into a number of "catalog" files roughly corresponding to feature verticals (like Firewall or Cloudflare Workers). This works out well for our developers since it provides a predictable place to find strings, and keeps the line count of a translation catalog down to a manageable length. It also works out well for the outside translation teams since a single feature vertical is a good unit of work for a translator (or small team).</p><p>In addition to per-feature catalogs, we have a common catalog file to hold strings that are re-used throughout the application. It allows us to keep IDs short (<code>common.delete</code> vs <code>some_page.some_tab.some_feature.thing.delete</code>) and lowers the likelihood of duplication since developers habitually check the common catalog before adding new strings.</p>
    <div>
      <h3>Libraries</h3>
      <a href="#libraries">
        
      </a>
    </div>
    <p>So far we've talked at length about our <code>&lt;Trans&gt;</code> component and what it can do. Now, let's talk about how it's built.</p><p>Perhaps unsurprisingly, we didn't want to reinvent the wheel and come up with a base i18n library from scratch. Due to prior efforts to internationalize the legacy parts of our application written in Backbone, we were already using Airbnb's <a href="https://airbnb.io/polyglot.js/">Polyglot library</a>, a "tiny I18n helper library written in JavaScript" which, among other things, "provides a simple solution for interpolation and pluralization, based off of Airbnb’s experience adding I18n functionality to its Backbone.js and Node apps".</p><p>We took a look at a few of the most popular libraries that had been purpose-built for internationalizing React applications, but ultimately decided to stick with Polyglot. We created our <code>&lt;Trans&gt;</code> component to bridge the gap to React. We chose this direction for a few reasons:</p><ul><li><p>We didn't want to re-internationalize the legacy code in our application in order to migrate to a new i18n support library.</p></li><li><p>We also didn't want the combined overhead of supporting 2 different i18n schemes for new vs legacy code.</p></li><li><p>Writing our own trans component gave us the flexibility to write the interface we wanted. Since Trans is used just about everywhere, we wanted to make sure it was as ergonomic as possible to developers.</p></li></ul><p>If you're just getting started with i18n in a new React based web-app, react-intl and i18n-next are 2 popular libraries that supply a component similar to <code>&lt;Trans&gt;</code> described above.</p><p>The biggest pain point of the <code>&lt;Trans&gt;</code> component as outlined is that strings have to be kept in a separate file from your source code. Switching between multiple files as you author new code or modify existing features is just plain annoying. It's even more annoying if the translation files are kept far away in the directory structure, as they often need to be.</p><p>There are some new i18n libraries such as <a href="https://github.com/lingui/js-lingui">jslingui</a> that obviate this problem by taking an extraction based approach to handling translation catalogs. In this scheme, you still use a <code>&lt;Trans&gt;</code>component, but you keep your strings in the component itself, not a separate catalog:</p>
            <pre><code>&lt;span&gt;
  &lt;Trans&gt;Hmm... We couldn't find any matching websites.&lt;/Trans&gt;
&lt;/span&gt;</code></pre>
            <p>A tool that you run at build time then does the work of finding all of these strings and extracting then into catalogs for you. For example, the above would result in the following generated catalogs:</p>
            <pre><code>// locales/en_US.json
{
  "Hmm... We couldn't find any matching websites.": "Hmm... We couldn't find any matching websites.",
}

// locales/de_DE.json
{
  "Hmm... We couldn't find any matching websites.": "Hmm... Wir konnten keine übereinstimmenden Websites finden."
}</code></pre>
            <p>The obvious advantage to this approach is that we no longer have separate files! The other advantage is that there's no longer any need for type checking IDs since typos can't happen anymore.</p><p>However, at least for our use case, there were a few downsides.</p><p>First, human translators sometimes appreciate the context of the translation keys. It helps with organization, and it gives some clues about the string's purpose.</p><p>And although we no longer have to worry about typos in translation IDs, we're just as susceptible to slight copy mismatches (ex. "Verify your email" vs "Verify your e-mail"). This is almost worse, since in this case it would introduce a near duplication which would be hard to detect. We'd also have to pay for it.</p><p>Whichever tech stack you're working with, there are likely a few i18n libraries that can help you out. Which one to pick is highly dependent on technical constraints of your application and the context of your team's goals and culture.</p>
    <div>
      <h3>Numbers, Dates, and Times</h3>
      <a href="#numbers-dates-and-times">
        
      </a>
    </div>
    <p>Earlier when we talked about injecting data translated strings, we glossed over a major issue: the data we're injecting may also need to be formatted to conform to the user's local customs. This is true for dates, times, numbers, currencies and some other types of data.</p><p>Let's take our simple example from earlier:</p>
            <pre><code>&lt;span&gt;You've selected { totalSelected } Page Rules.&lt;/span&gt;</code></pre>
            <p>Without proper formatting, this will appear correct for small numbers, but as soon as things get into the thousands, localization problems will arise, since the way that digits are grouped and separated with symbols <a href="https://en.wikipedia.org/wiki/Decimal_separator">varies by culture</a>. Here's how three-hundred thousand and three hundredths is formatted in a few different locales:</p><table><tr><td><p><b>Language (Country)</b></p></td><td><p><b>Code</b></p></td><td><p><b>Formatted Date</b></p></td></tr><tr><td><p>German (Germany)</p></td><td><p>de-DE</p></td><td><p>300.000,03</p></td></tr><tr><td><p>English (US)</p></td><td><p>en-US</p></td><td><p>300,000.03</p></td></tr><tr><td><p>English (UK)</p></td><td><p>en-GB</p></td><td><p>300,000.03</p></td></tr><tr><td><p>Spanish (Spain)</p></td><td><p>es-ES</p></td><td><p>300.000,03</p></td></tr><tr><td><p>Spanish (Chile)</p></td><td><p>es-CL</p></td><td><p>300.000,03</p></td></tr><tr><td><p>French (France)</p></td><td><p>fr-FR</p></td><td><p>300 000,03</p></td></tr><tr><td><p>Hindi (India)</p></td><td><p>hi-IN</p></td><td><p>3,00,000.03</p></td></tr><tr><td><p>Indonesian (Indonesia)</p></td><td><p>in-ID</p></td><td><p>300.000,03</p></td></tr><tr><td><p>Japanese (Japan)</p></td><td><p>ja-JP</p></td><td><p>300,000.03</p></td></tr><tr><td><p>Korean (South Korea)</p></td><td><p>ko-KR</p></td><td><p>300,000.03</p></td></tr><tr><td><p>Portuguese (Brazil)</p></td><td><p>pt-BR</p></td><td><p>300.000,03</p></td></tr><tr><td><p>Portuguese (Portugal)</p></td><td><p>pt-PT</p></td><td><p>300 000,03</p></td></tr><tr><td><p>Russian (Russia)</p></td><td><p>ru-RU</p></td><td><p>300 000,03</p></td></tr></table><p>The way that dates are formatted <a href="https://en.wikipedia.org/wiki/Date_format_by_country">varies significantly from country to country</a>. If you've developed your UI mainly with a US audience in mind, you're probably displaying dates in a way that will feel foreign and perhaps unintuitive to users from just about any other place in the world. Among other things, date formatting can vary in terms of separator choice, whether single digits are zero padded, and in the way that the day, month, and year portions are ordered. Here's how the March 4th of the current year is formatted in a few different locales:</p><table><tr><td><p><b>Language (Country)</b></p></td><td><p><b>Code</b></p></td><td><p><b>Formatted Date</b></p></td></tr><tr><td><p>German (Germany)</p></td><td><p>de-DE</p></td><td><p>4.3.2020</p></td></tr><tr><td><p>English (US)</p></td><td><p>en-US</p></td><td><p>3/4/2020</p></td></tr><tr><td><p>English (UK)</p></td><td><p>en-GB</p></td><td><p>04/03/2020</p></td></tr><tr><td><p>Spanish (Spain)</p></td><td><p>es-ES</p></td><td><p>4/3/2020</p></td></tr><tr><td><p>Spanish (Chile)</p></td><td><p>es-CL</p></td><td><p>04-03-2020</p></td></tr><tr><td><p>French (France)</p></td><td><p>fr-FR</p></td><td><p>04/03/2020</p></td></tr><tr><td><p>Hindi (India)</p></td><td><p>hi-IN</p></td><td><p>4/3/2020</p></td></tr><tr><td><p>Indonesian (Indonesia)</p></td><td><p>in-ID</p></td><td><p>4/3/2020</p></td></tr><tr><td><p>Japanese (Japan)</p></td><td><p>ja-JP</p></td><td><p>2020/3/4</p></td></tr><tr><td><p>Korean (South Korea)</p></td><td><p>ko-KR</p></td><td><p>2020. 3. 4.</p></td></tr><tr><td><p>Portuguese (Brazil)</p></td><td><p>pt-BR</p></td><td><p>04/03/2020</p></td></tr><tr><td><p>Portuguese (Portugal)</p></td><td><p>pt-PT</p></td><td><p>04/03/2020</p></td></tr><tr><td><p>Russian (Russia)</p></td><td><p>ru-RU</p></td><td><p>04.03.2020</p></td></tr></table><p>Time format varies significantly as well. Here's how time is formatted in a few selected locales:</p><table><tr><td><p><b>Language (Country)</b></p></td><td><p><b>Code</b></p></td><td><p><b>Formatted Date</b></p></td></tr><tr><td><p>German (Germany)</p></td><td><p>de-DE</p></td><td><p>14:02:37</p></td></tr><tr><td><p>English (US)</p></td><td><p>en-US</p></td><td><p>2:02:37 PM</p></td></tr><tr><td><p>English (UK)</p></td><td><p>en-GB</p></td><td><p>14:02:37</p></td></tr><tr><td><p>Spanish (Spain)</p></td><td><p>es-ES</p></td><td><p>14:02:37</p></td></tr><tr><td><p>Spanish (Chile)</p></td><td><p>es-CL</p></td><td><p>14:02:37</p></td></tr><tr><td><p>French (France)</p></td><td><p>fr-FR</p></td><td><p>14:02:37</p></td></tr><tr><td><p>Hindi (India)</p></td><td><p>hi-IN</p></td><td><p>2:02:37 pm</p></td></tr><tr><td><p>Indonesian (Indonesia)</p></td><td><p>in-ID</p></td><td><p>14.02.37</p></td></tr><tr><td><p>Japanese (Japan)</p></td><td><p>ja-JP</p></td><td><p>14:02:37</p></td></tr><tr><td><p>Korean (South Korea)</p></td><td><p>ko-KR</p></td><td><p>오후 2:02:37</p></td></tr><tr><td><p>Portuguese (Brazil)</p></td><td><p>pt-BR</p></td><td><p>14:02:37</p></td></tr><tr><td><p>Portuguese (Portugal)</p></td><td><p>pt-PT</p></td><td><p>14:02:37</p></td></tr><tr><td><p>Russian (Russia)</p></td><td><p>ru-RU</p></td><td><p>14:02:37</p></td></tr></table>
    <div>
      <h3>Libraries for Handling Numbers, Dates, and Times</h3>
      <a href="#libraries-for-handling-numbers-dates-and-times">
        
      </a>
    </div>
    <p>Ensuring the correct format for all these types of data for all supported locales is no easy task. Fortunately, there are a number of mature, battle-tested libraries that can help you out.</p><p>When we kicked off our project, we were using the <a href="https://momentjs.com/">Moment.js</a> library extensively for date and time formatting. This handy library abstracts away the details of formatting dates to different lengths ("Jul 9th 20", "July 9th 2020", vs "Thursday"), displaying relative dates ("2 days ago"), amongst many other things. Since almost all of our dates were already being formatted via Moment.js for readability, and since Moment.js already has i18n support for numerous locales, it meant that we were able to flip a couple of switches and have properly localized dates with very little effort.</p><p>There are some strong criticisms of Moment.js (mainly bloat), but ultimately the benefits realized from switching to a lower footprint alternative when compared to the cost it would take to redo every date and time didn't add up.</p><p>Numbers were a very different story. We had, as you might imagine, thousands of raw, unformatted numbers being displayed throughout the dashboard. Hunting them down was a laborious and often manual process.</p><p>To handle the actual formatting of numbers, we used the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl">Intl API</a> (the Internationalization library defined by the ECMAScript standard):</p>
            <pre><code>var number = 300000.03;
var formatted = number.toLocaleString('hi-IN'); // 3,00,000.03
// This probably works in the browser you're using right now!</code></pre>
            <p>Fortunately, browser support for Intl has come quite a long way in recent years, with all modern browsers having full support.</p><p>Some modern JavaScript engines like V8 have even moved away from self-hosted JavaScript implementations of these libraries in favor of C++ based builtins, <a href="https://v8.dev/blog/intl">resulting in significant speedup</a>.</p><p>Support for older browsers can be somewhat lacking, however. Here's a <a href="https://intl-formatting.jculvey.workers.dev/">simple demo site</a> (<a href="https://github.com/jculvey/intl-formatting-worker">source code</a>) that’s built with <a href="https://workers.cloudflare.com/">Cloudflare Workers</a> that shows how dates, times, and numbers are rendered in a hand-full of locales.</p><p>Some combinations of old browsers and OS's will yield less than ideal results. For example, here's how the same dates and times from above are rendered on Windows 8 with IE 10:</p><table>
<tbody>
<tr>
<td><img src="http://staging.blog.mrk.cfdata.org/content/images/2020/07/image3-10.png" /></td>
<td><img src="http://staging.blog.mrk.cfdata.org/content/images/2020/07/image2-7.png" /></td>
</tr>
</tbody>
</table><p>If you need to support older browsers, this can be solved with a polyfill.</p>
    <div>
      <h3>Translating</h3>
      <a href="#translating">
        
      </a>
    </div>
    <p>With all strings externalized, and all injected data being carefully formatted to locale specific standards, the bulk of the engineering work is complete. At this point, we can now claim that we’ve <b>internationalized</b> our application, since we’ve adapted it in a way that makes it easy to localize.</p><p>Next comes the process of <b>localization</b> where we actually create varying content based on the user’s language and cultural norms.</p><p>This is no small feat. Like we mentioned before, the strings in our application added together are the size of a small novel. It takes a significant amount of coordination and human expertise to create a translated copy that both captures the information with fidelity and speaks to the user in a familiar way.</p><p>There are many ways to handle the translation work: leveraging multilingual staff members, contracting the work-out to individual translators, agencies, or even going all in and hiring teams of in-house translators. Whatever the case may be, there needs to be a smooth process for both workflow signalling and moving assets between the translation and development teams.</p><p>A healthy i18n program will provide developers with black-box interface with the process — they put new strings in a translation catalog file and commit the change, and without any more effort on their part, the feature code they wrote is available in production for all supported locales a few days later. Similarly, in a well run process translators will remain blissfully unaware of the particulars of the development process and application architecture. They receive files that easily load in their tools and clearly indicate what translation work needs to be done.</p><p>So, how does it actually work in practice?</p><p>We have a set of automated scripts that can be run on-demand by the localization team to package up a snapshot of our localization catalogs for all supported languages. During this process, a few things happen:</p><ul><li><p>JSON files are generated from catalog files authored in TypeScript</p></li><li><p>If any new catalog files were added in English, placeholder copies are created for all other supported languages.</p></li><li><p>Placeholder strings are added for all languages when new strings are added to our base catalog</p></li></ul><p>From there, the translation catalogs are uploaded to the Translation Management system via the UI or automated calls to the API. Before handing it off to translators, the files are pre-processed by comparing each new string against a Translation Memory (a cache of previously translated strings and substrings). If a match is found, the existing translation is used. Not only does this save cost by not re-translating strings, but it improves quality by ensuring that previously reviewed and approved translations are used when possible.</p><p>Suppose your locale files end up looking something like this:</p>
            <pre><code>{
 "verify.button": "Verify Email",
 "other.verify.button": "Verify Email",
 "verify.proceed.link": "Verify Email to proceed",
 // ...
}</code></pre>
            <p>Here, we have strings that are duplicated verbatim, as well as sub-strings that are copied. Translation services are billed by the word — you don’t want to pay for something twice and run the risk of a consistency issue arising. To this end, having a well-maintained Translation Memory will ensure that these strings are taken care of in the pre-translation steps before translators even see the file.</p><p>Once the translation job is marked as ready, it can take translation teams anywhere from hours to weeks to complete return translated copies depending on a number of factors such as the size of the job, the availability of translators, and the contract terms. The concerns of this phase could constitute another blog article of similar length: sourcing the right translation team, controlling costs, ensuring quality and consistency, making sure the company’s brand is properly conveyed, etc. Since the focus of this article is largely technical, we’ll gloss over the details here, but make no mistake -- getting this part wrong will tank your entire effort, even if you’ve achieved your technical objectives.</p><p>After translation teams signal that new files are ready for pickup, the assets are pulled from the server and unpacked into their correct locations in the application code. We then run a suite of automated checks to make sure that all files are valid and free of any formatting issues.</p><p>An optional (but highly recommended) step takes place at this stage — in-context review. A team of translation reviewers then look at the translated output in context to make sure everything looks perfect in its finalized state. Having support staff that are both highly proficient with the product and fluent in the target language are especially useful in this effort. Shoutout to all our team members from around the company that have taken the time and effort to do this. To make this possible for outside contractors, we prepare special preview versions of our app that allow them to test with development mode locales enabled.</p><p>And there you have it, everything it takes to deliver a localized version of your application to your users all around the world.</p>
    <div>
      <h3>Continual Localization</h3>
      <a href="#continual-localization">
        
      </a>
    </div>
    <p>It would be great to stop here, but what we’ve discussed up until this point is the effort required to do it once. As we all know, code changes. New strings will be gradually added, modified, and deleted over the course of ti me as new features are launched and tweaked.</p><p>Since translation is a highly human process that often involves effort from people in different corners of the world, there is a lower bound to the timeframe in which turnover is possible. Since our release cadence (daily) is often faster than this turnover rate (2-5 days), it means that developers making changes to features have to make a choice: slow down to match this cadence, or ship slightly ahead of the localization schedule without full coverage.</p><p>In order to ensure that features shipping ahead of translations don’t cause application-breaking errors, we fall back to our base locale (en_US) if a string doesn’t exist for the configured language.</p><p>Some applications have a slightly different fallback behavior: displaying raw translation keys (perhaps you've seen <i>some.funny.dot.delimited.string</i> in an app you're using). There's a tradeoff between velocity and correctness here, and we chose to optimize for velocity and minimal overhead. In some apps correctness is important enough to slow down cadence for i18n. In our case it wasn't.</p>
    <div>
      <h3>Finishing Touches</h3>
      <a href="#finishing-touches">
        
      </a>
    </div>
    <p>There are a few more things we can do to optimize the user experience in our newly localized application.</p><p>First, we want to make sure there isn’t any performance degradation. If our application made the user fetch all of its translated strings before rendering the page, this would surely happen. So, in order to keep everything running smoothly, the translation catalogs are fetched asynchronously and only as the application needs them to render some content on the page. This is easy to accomplish nowadays with the code splitting features available in module bundlers that support dynamic import statements such as <a href="https://parceljs.org/code_splitting.html">Parcel</a> or <a href="https://webpack.js.org/guides/code-splitting/">Webpack</a>.</p><p>We also want to eliminate any friction the user might experience with needing to constantly select their desired language when visiting different Cloudflare properties. To this end, we made sure that any language preference a user selects on our <a href="https://www.cloudflare.com/fr-fr/">marketing site</a> or our <a href="https://support.cloudflare.com/hc/fr-fr">support site</a> persists as they navigate to and from our <a href="https://dash.cloudflare.com/login?lang=fr-fr">dashboard</a> (all links are in French to belabor the point).</p>
    <div>
      <h3>What’s next?</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>It’s been an exciting journey, and we’ve learned a lot from the process. It’s difficult (perhaps impossible) to call an i18n project truly complete.  Expanding into new languages will surface slippery bugs and expose new challenges. Budget pressure will challenge you to find ways of cutting costs and increasing efficiency. In addition, you will discover ways in which you can enhance the localized experience even more for users.</p><p>There’s a long list of things we’d like to improve upon, but here are some of the highlights:</p><ul><li><p>Collation. String comparison is language sensitive, and as such, the code you’ve written to lexicographically sort lists and tables of data in your app is probably doing the wrong thing for some of your users. This is especially apparent in languages that use logo graphic writing systems (such as Chinese or Japanese) as opposed to languages that use alphabets (like English or Spanish).</p></li><li><p>Support for <a href="https://en.wikipedia.org/wiki/Right-to-left">right-to-left languages</a> like Arabic and Hebrew.</p></li><li><p>Localizing API responses is harder than localizing static copy in your user interface, as it takes a coordinated effort between teams. In the age of microservices, finding a solution that works well across the myriad of tech stacks that power each service can be very challenging.</p></li><li><p>Localizing maps. We’ll be working on making sure all content in our map-based visualizations is translated.</p></li><li><p>Machine translation has come a long way in recent years, but not far enough to churn our translations unsupervised. We would however like to experiment more with using machine translation as a first pass that translation reviewers then edit for correctness and tone.</p></li></ul><p>I hope you have enjoyed this overview of how Cloudflare internationalized and localized our dashboard.  Check out <a href="https://www.cloudflare.com/careers/jobs/">our careers page</a> for more information on full-time positions and internship roles across the globe.</p> ]]></content:encoded>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">7MdK7VijKW2yLm60JTPzvN</guid>
            <dc:creator>James Culveyhouse</dc:creator>
        </item>
    </channel>
</rss>