<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Beto Muniz</title>
    <description>The latest articles on DEV Community by Beto Muniz (@obetomuniz).</description>
    <link>https://dev.to/obetomuniz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F254213%2Fdf2caaac-f629-448f-9671-5439a92562f1.png</url>
      <title>DEV Community: Beto Muniz</title>
      <link>https://dev.to/obetomuniz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/obetomuniz"/>
    <language>en</language>
    <item>
      <title>Who Owns the Surface?</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 15 Jun 2026 22:15:29 +0000</pubDate>
      <link>https://dev.to/obetomuniz/who-owns-the-surface-22n9</link>
      <guid>https://dev.to/obetomuniz/who-owns-the-surface-22n9</guid>
      <description>&lt;p&gt;Most people I've talked to think generative UI means letting a model render React components on the fly. That's the worst possible version of the idea, and if that's what you're shipping, you've already lost.&lt;/p&gt;

&lt;p&gt;The actual story is a taxonomy. Three patterns of how an agent and a UI fit together, distributed across a power law, each suited to a different kind of surface. And underneath the taxonomy, a quieter fight worth caring about: who controls the layer between the model and the pixels.&lt;/p&gt;

&lt;p&gt;Let me walk through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Inversion
&lt;/h2&gt;

&lt;p&gt;There's a real difference between "we shipped an AI assistant" and "we built a fullstack agentic application," and it has nothing to do with marketing.&lt;/p&gt;

&lt;p&gt;In the assistant-on-the-side version, the agent doesn't know what's on screen, doesn't know what the user just clicked, and can't do anything except return text into a sidebar. The application underneath couldn't care less. The agent is a sticker.&lt;/p&gt;

&lt;p&gt;In the fullstack version, the agent shares state with the app, drives the UI, and moves next to the user. You can't draw a clean line between where the app ends and the agent begins. The agent isn't a feature parked next to the product; it's part of how the product runs.&lt;/p&gt;

&lt;p&gt;That's the inversion. The agent stops being a feature in the product. The product starts bending around the agent. The UI exists to give the agent surfaces to operate on.&lt;/p&gt;

&lt;p&gt;That flips the design question entirely. It's no longer "how do users prompt for components" It's: how does the agent know what UI to put in front of the user, when to put it there, and how to do it without breaking trust?&lt;/p&gt;

&lt;p&gt;That question splits into three answers, depending on how predictable the surface is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Patterns, One Power Law
&lt;/h2&gt;

&lt;p&gt;The cleanest way I've seen this framed is as a frequency distribution. Most of the surfaces in any real product are predictable. You know what they need to look like and you've already designed them. Some surfaces are shape-roughly-known but variable. A few are genuinely open-ended.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0r9v3m159der0pmgs1gv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0r9v3m159der0pmgs1gv.jpg" alt="A horizontal flow of three connected stages showing the generative UI power law. Catalog (predictable surfaces, ~80% of the product) leads to Vocabulary (shape-known, content-varies, ~15%, the tail), which leads to Sandbox (third-party surfaces, ~5%, the platform edge). The stages move from blue to green to red, signaling increasing flexibility and decreasing predictability left to right." width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll call them the &lt;strong&gt;Catalog&lt;/strong&gt;, the &lt;strong&gt;Vocabulary&lt;/strong&gt;, and the &lt;strong&gt;Sandbox&lt;/strong&gt;, each named after what you actually hand the agent. A catalog of pre-built components. A vocabulary of primitives the agent composes with. A sandbox where third-party surfaces run.&lt;/p&gt;

&lt;p&gt;The choice between them isn't aesthetic. It's a decision about predictability, trust, and how much control you hand to the model versus how much you keep.&lt;/p&gt;

&lt;p&gt;Let me unpack each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 1: The Catalog
&lt;/h2&gt;

&lt;p&gt;This is where most teams should start, and where most agentic apps in production actually live today.&lt;/p&gt;

&lt;p&gt;The shape of it: you declare a fixed catalog of components (bar chart, pie chart, contextual card, button, whatever your design system already contains), each one annotated with what it's called, what it does, and what arguments it needs. A middleware layer translates that catalog into tool definitions the agent can see. The agent runs, decides one of the registered components is the right answer, and calls the corresponding tool. The frontend tool call pauses backend execution, hands control to the client, and the SDK maps the call to the component, fills the props, and mounts it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faabcqav5wiyt0fboznvs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faabcqav5wiyt0fboznvs.jpg" alt="A flow showing how a registered component catalog drives rendering. A User Request goes to the Agent. A Component Catalog (Bar Chart, Pie Chart, Contextual Card, and so on) is registered to the Agent as tools. The Agent makes a tool call to the Frontend SDK, which produces a Rendered Component. The model picks from a predefined menu rather than generating UI." width="798" height="152"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The open protocol forming around this pattern is &lt;strong&gt;AG-UI&lt;/strong&gt;, an MIT-licensed event protocol that originated inside CopilotKit with LangGraph and CrewAI, and now has implementations across Mastra, Microsoft's Agent Framework, AG2, Agno, and LlamaIndex. Framework-agnostic by design.&lt;/p&gt;

&lt;p&gt;The thing to notice here: &lt;strong&gt;the model never generates UI code&lt;/strong&gt;. It picks from a menu you've already designed, tested, and signed off on. The "generative" part is the choice and the data binding. Not the markup, not the layout, not the styling.&lt;/p&gt;

&lt;p&gt;This is what you want for surfaces that are predictable, which is most of your product. The dashboards, the cards, the inline answers, the action buttons. The bar chart isn't going to surprise you with a 3D rotating waveform that mangles your design system. It's &lt;em&gt;your&lt;/em&gt; bar chart. The agent just decided to use it. &lt;strong&gt;Grafana Assistant&lt;/strong&gt; is a clean production example of this: a sidebar chat that responds using Grafana's existing component vocabulary (panels, plots, queries, tables) instead of only free-form text or markup. The components are predefined. The agent's job is to pick the right one for the conversation and wire it to the right data.&lt;/p&gt;

&lt;p&gt;If you build one of these patterns, build this one. It covers the majority of the surface area of any real product, and it's the only one where the runtime risk is genuinely bounded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 2: The Vocabulary
&lt;/h2&gt;

&lt;p&gt;Sometimes you can't pre-register every possible component. The agent needs to compose a layout you didn't anticipate. The data shape is different every time. The surface answers a request that doesn't fit your catalog.&lt;/p&gt;

&lt;p&gt;That's where the declarative approach earns its keep. The open spec here is &lt;strong&gt;A2UI&lt;/strong&gt; (Agent-to-UI), at a2ui.org, open-sourced by Google in collaboration with CopilotKit. The core idea is simple.&lt;/p&gt;

&lt;p&gt;The agent doesn't send code. It doesn't pick from a fixed menu either. It emits a declarative description of intent (structured operations), and a renderer on the client materializes those operations into native UI components from your design system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68meiav8wzfyck772tlk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68meiav8wzfyck772tlk.jpg" alt="A flow showing declarative intent turned into native UI. The Agent describes intent, emitting A2UI Operations (declarative), which pass to a Client Renderer, which materializes them into Native UI built from your own components. The agent never writes markup; the renderer owns the mapping to the design system." width="800" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've worked with React internally, this should feel familiar. It's reconciler-shaped, but with the agent as the source of truth instead of your component tree. The agent says "show a card with this title, this body, these three actions". The renderer maps that to your design system. The model never touches a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, never writes a Tailwind class, never decides spacing.&lt;/p&gt;

&lt;p&gt;Notion AI is a clean in-the-wild example of this: when you ask it to draft a structured page, it composes from Notion's existing block vocabulary (headings, tables, callouts, toggles, databases) rather than generating markup. Notion's renderer handles the actual UI.&lt;/p&gt;

&lt;p&gt;There are two flavors of A2UI that matter more than they look at first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fixed schema&lt;/strong&gt;: you build the layout in advance. The agent populates it with data at runtime. Predictable structure, dynamic content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic schema&lt;/strong&gt;: a second model pass produces the layout itself, adapted to whatever the conversation is actually about. The same spec-level constraints still hold, but the structure is decided in-flight.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fixed schema is the safer default and probably what you want most of the time you reach for this pattern. Dynamic schema is what you reach for when the shape genuinely can't be enumerated in advance. Even then, the spec keeps the model inside a sandbox you defined.&lt;/p&gt;

&lt;p&gt;Either way, the layer between the model and the pixels is &lt;em&gt;yours&lt;/em&gt;. That's the part that matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 3: The Sandbox
&lt;/h2&gt;

&lt;p&gt;The far end of the curve. The thing you reach for when the answer isn't "render a component" or "compose a layout". It's "open this entire other app inside my app".&lt;/p&gt;

&lt;p&gt;The open standard here is &lt;strong&gt;MCP Apps&lt;/strong&gt;, part of the broader Model Context Protocol, consolidating earlier work from MCP-UI and OpenAI into a single specification. Three components, with the boundaries between them doing the heavy lifting.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Worth flagging the spec status: MCP Apps already exists and is in production use, but the upcoming MCP 2026-07-28 spec revision (currently a release candidate, locked May 21, ships final July 28) formalizes it as a first-class extension with a dedicated lifecycle. The pattern is stable; the surrounding surface is consolidating.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Server&lt;/strong&gt; publishes both the tools and the UI surfaces themselves. Each tool carries a URI pointing at the embeddable app. The &lt;strong&gt;Host&lt;/strong&gt; is your front-end app. It mounts the embedded surface inside a sandboxed iframe and brokers messages between the agent and the embedded app. The &lt;strong&gt;View&lt;/strong&gt; is the surface itself, running in the sandboxed iframe. It can't touch your DOM. It can't read your cookies. It can't do anything except talk back through postMessage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uqubc5lz345hlmqbba6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uqubc5lz345hlmqbba6.jpg" alt="A three-zone trust diagram. The Server publishes MCP tools and UI surfaces (ui:// URIs) and sends a tool call to the Host. The Host is your frontend app that mounts the View and brokers messages. It exchanges postMessage and JSON-RPC with the View, a sandboxed iframe with no DOM and no cookie access. Three boundaries, three trust zones, no shared state." width="800" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tool calls between Server and Host. postMessage and JSON-RPC between Host and View. Three boundaries, three trust zones, no shared state across them.&lt;/p&gt;

&lt;p&gt;This is the right pattern when you're building something platform-shaped: a host-of-hosts that orchestrates third-party experiences. The agent picks which embedded surface to open. The developer pre-wired the integration. The user sees a third-party app running right inside the agent's surface, with the agent able to drive it.&lt;/p&gt;

&lt;p&gt;Claude and ChatGPT both ship variations of this pattern in production today: both can host third-party UI surfaces (connected tools, MCP server apps) embedded inside the agent's product, with sandboxed iframes brokering between host and View.&lt;/p&gt;

&lt;p&gt;It's the most powerful pattern and the most dangerous one. You're embedding code you don't own. The iframe sandbox isn't decoration. It's load-bearing. The whole point of the architecture is that the View can't reach in, can't read out, can't do anything except talk through the channel you opened. Take that boundary seriously or don't ship this pattern at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  So Where Does Each Pattern Belong?
&lt;/h2&gt;

&lt;p&gt;Pulling the implicit strategy out into the open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Catalog&lt;/strong&gt; for ~80% of your surface area. The components you'd build anyway. The agent just picks intelligently from your registered set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vocabulary (A2UI)&lt;/strong&gt; for the tail. Surfaces where you know roughly what shape you'll need but can't enumerate every variation in advance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sandbox (MCP Apps)&lt;/strong&gt; for the platform edge. When you're building a host for other people's products, not a product itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most teams will live entirely in Catalog and never need the other two. That's correct, actually. The mistake is jumping straight to "let the model render anything it wants" because it looks more impressive in a demo. That's the path to UI that looks great in screenshots and falls apart in production within a quarter.&lt;/p&gt;

&lt;p&gt;The further right you move on the curve, the more flexibility you get, and the more trust you outsource to the spec, the iframe, the third-party app. Move only as far right as the surface actually demands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same Shape, New Decision-Maker
&lt;/h2&gt;

&lt;p&gt;This three-tier arc isn't unique to generative UI. The same pattern played out in browser plugins, in embeds and iframes, in browser extensions, across thirty years of platform evolution: a curated middle, a declarative layer, and an open sandbox. The architectural shape isn't novel.&lt;/p&gt;

&lt;p&gt;What is novel: the decision-maker choosing between those tiers is now a language model instead of a user with a mouse. The topology stayed the same. The thing in front of the topology, picking which tier to use and when, became something with its own opinions.&lt;/p&gt;

&lt;p&gt;That's the shift worth paying attention to. Not the patterns themselves, but who's choosing between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Concern Nobody Is Saying Out Loud
&lt;/h2&gt;

&lt;p&gt;The interesting tension here isn't technical. It's about &lt;strong&gt;who owns the line&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When the agent decides what UI to show, even within constraints, the agent is doing product work that used to belong to designers and PMs. The constraints (your registered catalog, the A2UI primitives, the MCP sandbox) are the &lt;em&gt;only&lt;/em&gt; thing standing between your product's design integrity and a runtime that picks whatever feels right to a language model on a given Tuesday.&lt;/p&gt;

&lt;p&gt;Whoever ships the spec, the renderer, and the constraint layer ends up controlling a meaningful slice of what every agentic product is allowed to look like. That's what's actually being decided at ag-ui.com, at a2ui.org, inside the MCP Apps spec, inside every framework racing to ship a generative UI primitive. It's not really a UI standards conversation. It's a control-plane conversation, wearing a UI library's clothes.&lt;/p&gt;

&lt;p&gt;(My guess: the spec layer consolidates around two or three contenders in the next eighteen months, the same way the JS framework wars did. A2UI has the head start, with Google's backing and the open-source ecosystem already shipping around it. AG-UI is locking in the transport layer underneath. MCP Apps is becoming the standard at the platform edge. But the surface is wide open, and whoever wins the constraint layer ends up with the kind of leverage Stripe has over payments. That's the actual prize.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Start
&lt;/h2&gt;

&lt;p&gt;There's a temptation, when a stack like this lands, to split the takeaway across roles. Engineers get one paragraph, PMs another, designers a third. I'm skipping that. The roles are converging anyway: the person making the surface decision, writing the code, and owning the product spec is increasingly one person, or a small group wearing all three hats. (More on that in a future post ☺️)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One synthesis instead:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start with the Catalog. Most surfaces don't need anything else. Build the registered set, expose it as tools, let the agent pick from a menu you designed. The "let the model render anything" demo looks great in screenshots and falls apart in production within a quarter.&lt;/p&gt;

&lt;p&gt;When you genuinely need flexibility, reach for the Vocabulary before open-ended rendering. The constraint layer is what keeps the model from picking what feels right on a given Tuesday.&lt;/p&gt;

&lt;p&gt;Keep the Sandbox for the moment your product becomes a host for other people's products. When you ship that, take the iframe seriously. It isn't decoration.&lt;/p&gt;

&lt;p&gt;And every time you move further right on the gradient, the question is the same: what are you outsourcing trust to, and do you actually trust it?&lt;/p&gt;

&lt;p&gt;The component-library era of "AI features" is ending. The agent-runtime era is starting. Build accordingly.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The three-tier framing borrows its shape from the Controlled/Declarative/Open spectrum laid out in &lt;a href="https://www.deeplearning.ai/courses/build-interactive-agents-with-generative-ui" rel="noopener noreferrer"&gt;Build Interactive Agents with Generative UI&lt;/a&gt;; the Catalog/Vocabulary/Sandbox labels are my simplified own restatement.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>genui</category>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Quiet AI War Inside Your Browser</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 25 May 2026 22:09:47 +0000</pubDate>
      <link>https://dev.to/obetomuniz/the-quiet-ai-war-inside-your-browser-22hd</link>
      <guid>https://dev.to/obetomuniz/the-quiet-ai-war-inside-your-browser-22hd</guid>
      <description>&lt;p&gt;Google shipped the Prompt API in Chrome 148 on May 5, 2026. Mozilla objected. Apple's WebKit team objected. The W3C TAG objected. Microsoft Edge &lt;em&gt;disabled the feature entirely&lt;/em&gt; despite running on the same Chromium engine. It was, by any measure, one of the most contested browser feature launches in recent memory.&lt;/p&gt;

&lt;p&gt;And it doesn't matter. Google has already won this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Happened
&lt;/h2&gt;

&lt;p&gt;Chrome 148 quietly gave every website on earth the ability to run AI inference locally (text generation, summarization, classification, image captioning) by talking to Gemini Nano, a 4GB model that Chrome now ships to users' devices without asking. The API is dead simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;LanguageModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;initialPrompts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your prompt here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No API key. No latency. No server cost. No data leaving the device.&lt;/p&gt;

&lt;p&gt;The opposition's core argument is a legitimate one: unlike &lt;code&gt;fetch()&lt;/code&gt; or &lt;code&gt;addEventListener()&lt;/code&gt;, an AI model isn't a deterministic spec. Two browsers implementing the "same API" with different underlying models could produce wildly different outputs, breaking the foundational promise of web standards: write once, run identically everywhere.&lt;/p&gt;

&lt;p&gt;It's a real concern. It's also, in practice, irrelevant.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Web Has Never Guaranteed Identical Outputs
&lt;/h2&gt;

&lt;p&gt;Font rendering differs across browsers. Canvas pixels vary by GPU driver. Audio processing behaves differently on macOS versus Windows. &lt;code&gt;Math.random()&lt;/code&gt; is, by definition, non-deterministic. None of these killed the web. Developers adapted, and they'll adapt here too.&lt;/p&gt;

&lt;p&gt;The "we can't standardize non-deterministic output" argument proves too much. If it were applied consistently, half the modern web platform wouldn't exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Is the Real Baseline: Not Firefox's Future Model
&lt;/h2&gt;

&lt;p&gt;Here's the thing critics seem to be missing: developers building serious AI features today aren't choosing between Chrome's Prompt API and Firefox's theoretical equivalent. They're calling cloud APIs: OpenAI, Anthropic, Gemini Cloud. Those are where the quality is, where the context windows are, where the capable models live.&lt;/p&gt;

&lt;p&gt;Gemini Nano is a small model. It's good at lightweight, well-scoped tasks: summarizing a paragraph, classifying sentiment, extracting a date from a string. It's not replacing GPT-4o or Claude Sonnet for anything that actually matters.&lt;/p&gt;

&lt;p&gt;So the Prompt API isn't competing with cloud AI. It's filling a specific niche:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero latency&lt;/strong&gt; tasks that need to feel instant&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline-capable&lt;/strong&gt; features in PWAs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy-sensitive&lt;/strong&gt; processing where data must stay on device&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-sensitive&lt;/strong&gt; at-scale operations (spell check, auto-tagging, content filtering)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers will reach for it as a progressive enhancement layer: use the Prompt API when available, fall back to a cloud call when not. The non-determinism objection collapses entirely in this framing: nobody is relying on Chrome and Firefox producing the same tokens. They're relying on "good enough local inference" vs "cloud inference." That gap is fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Have Seen This Movie Before
&lt;/h2&gt;

&lt;p&gt;PWAs. Web Components. Service Workers. WebRTC. Each time, the pattern is the same:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Google ships something useful but contested&lt;/li&gt;
&lt;li&gt;Mozilla and Apple raise principled standards objections (sometimes valid, sometimes a proxy for business interests)&lt;/li&gt;
&lt;li&gt;Developers adopt it anyway, because Chrome is 65% of global browser traffic&lt;/li&gt;
&lt;li&gt;The holdouts implement their own version 2–5 years later&lt;/li&gt;
&lt;li&gt;It retroactively becomes a "web standard"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PWAs are the sharpest example. Apple resisted for years: not primarily because of standards purity, but because native apps and the App Store are a multi-billion dollar business. They eventually shipped, incompletely at first, then more fully as the pressure became undeniable. Web Components took a similarly winding road: Google and Mozilla aligned early, Apple dragged its feet, and today Custom Elements and Shadow DOM are universally supported.&lt;/p&gt;

&lt;p&gt;The Prompt API will follow the same arc. The only open question is how long the lag is and what compromises get made along the way. (My guess: Firefox and Safari eventually ship something with a compatible API surface but their own models underneath. Mozilla with something open-source, Apple with something Core ML-optimized. The outputs will differ. Nobody will care.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Concern Nobody Is Saying Out Loud
&lt;/h2&gt;

&lt;p&gt;Apple's strategic worry isn't about spec compliance. It's about this: Google just normalized the browser as an AI delivery vehicle and installed its model on over 4 billion devices. That's not a web standards problem. That's an ecosystem control problem.&lt;/p&gt;

&lt;p&gt;Whoever controls the model layer of the browser controls a significant surface area of how users interact with the web: what gets summarized, how content gets classified, what gets surfaced and what doesn't. Apple understands this better than anyone; it's exactly the kind of leverage they've built with the App Store for 15 years.&lt;/p&gt;

&lt;p&gt;That's a legitimate concern worth having a serious conversation about. But dressing it up as a standards integrity argument dilutes it and, frankly, makes the objectors look like they're arguing in bad faith. That weakens their position when the real fight (model governance, content policies, on-device data access) eventually arrives.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means for You
&lt;/h2&gt;

&lt;p&gt;If you're building web products today:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers:&lt;/strong&gt; Start experimenting with the Prompt API now for lightweight, latency-sensitive tasks. Design with graceful degradation: the API isn't available in Firefox or Safari yet, so treat it as enhancement, not baseline. WebGPU-based bring-your-own-model approaches (via transformers.js, ONNX Runtime Web) remain the cross-browser story for anything more demanding. If you want a unified abstraction over both, check out &lt;a href="https://web-ai-sdk.dev/" rel="noopener noreferrer"&gt;web-ai-sdk.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Product and business:&lt;/strong&gt; The interesting unlock here isn't replacing your cloud AI pipeline. It's enabling AI features that previously couldn't exist on the web: instant, offline, private, zero marginal cost. Think client-side content moderation, on-device personalization, local draft assistance. The economics and privacy story are genuinely new.&lt;/p&gt;

&lt;p&gt;The browser is becoming an AI runtime. Google didn't ask for permission. That ship has sailed.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The Prompt API is available in Chrome 148+. WebGPU-based inference works cross-browser today via libraries like Transformers.js. WebNN remains experimental across all browsers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>frontend</category>
      <category>browser</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to improve the Critical Path CSS on web using the “Above-The-Fold" strategy?</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 31 May 2021 15:28:04 +0000</pubDate>
      <link>https://dev.to/obetomuniz/how-to-improve-the-critical-path-css-on-web-using-the-above-the-fold-strategy-3nkd</link>
      <guid>https://dev.to/obetomuniz/how-to-improve-the-critical-path-css-on-web-using-the-above-the-fold-strategy-3nkd</guid>
      <description>&lt;p&gt;In this brief content, I am sharing about the &lt;strong&gt;Above-The-Fold&lt;/strong&gt; strategy to load CSS and why it matters to improve the page loading of our web pages. &lt;/p&gt;




&lt;p&gt;📁 &lt;strong&gt;Above-The-Fold&lt;/strong&gt; strategy on the web is a practice that extracts critical CSS declaration to render the layout displayed during the initial page load.&lt;/p&gt;

&lt;p&gt;⏬ Non-critical CSS is added to another context (usually a dedicated &lt;code&gt;.css&lt;/code&gt; file) to use async loading.&lt;/p&gt;




&lt;p&gt;⌛️ &lt;strong&gt;Above-The-Fold&lt;/strong&gt; enhances the loading experience while browsing since the browser will have the necessary CSS to scaffold the layout.&lt;/p&gt;

&lt;p&gt;⏱ Also, this technique is an essential strategy to improve &lt;a href="https://web.dev/first-contentful-paint" rel="noopener noreferrer"&gt;First Content Paint&lt;/a&gt; metrics in our web pages.&lt;/p&gt;




&lt;p&gt;👉 Have you already heard about this web optimization opportunity strategy? &lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>webperf</category>
    </item>
    <item>
      <title>How to avoid Meltdown, Spectre and CSRF Attacks on Web with CORP, CORB, and CORS?</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 24 May 2021 21:33:26 +0000</pubDate>
      <link>https://dev.to/obetomuniz/how-to-avoid-meltdown-spectre-and-csrf-attacks-on-web-with-corp-corb-and-cors-1944</link>
      <guid>https://dev.to/obetomuniz/how-to-avoid-meltdown-spectre-and-csrf-attacks-on-web-with-corp-corb-and-cors-1944</guid>
      <description>&lt;p&gt;A brief and useful content about the mechanics on Cross-Origin Read Blocking, Cross-Origin Resource Policy and Cross-Origin Resource Sharing against &lt;a href="https://meltdownattack.com/" rel="noopener noreferrer"&gt;Meltdown, Spectre&lt;/a&gt; and &lt;a href="https://owasp.org/www-community/attacks/csrf" rel="noopener noreferrer"&gt;CSRF&lt;/a&gt; Attacks.&lt;/p&gt;




&lt;h2&gt;
  
  
  CORB
&lt;/h2&gt;

&lt;p&gt;By design, &lt;strong&gt;Cross-Origin Read Blocking&lt;/strong&gt; validates browser requests before they even reach the server using their &lt;strong&gt;MIME type&lt;/strong&gt; as a validation rule.&lt;/p&gt;

&lt;p&gt;To enable it, send the HTTP header &lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt;  from the server.&lt;/p&gt;




&lt;h2&gt;
  
  
  CORP
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cross-Origin Resource Policy&lt;/strong&gt; is a complementary &lt;em&gt;CORB&lt;/em&gt; mechanism for validation applied to requests flagged with &lt;code&gt;no-cors&lt;/code&gt; to invalidate them if they came from different domains or origin.&lt;/p&gt;

&lt;p&gt;Send the header &lt;code&gt;Cross-Origin-Resource-Policy&lt;/code&gt; from the server with values &lt;code&gt;same-origin&lt;/code&gt; or &lt;code&gt;same-site&lt;/code&gt; to invalidate &lt;code&gt;no-cors&lt;/code&gt; requests from different domains or origin.&lt;/p&gt;




&lt;h2&gt;
  
  
  CORS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cross-Origin Resource Sharing&lt;/strong&gt; is a logical context mechanism that ensures minimal security in the way that users consume web content using browsers instructing how the browser will validate the origin of the requests.&lt;/p&gt;

&lt;p&gt;To define rules about how the origin of the request will be identified, send the HTTP header &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; using values like &lt;code&gt;&amp;lt;exact_request_origin&amp;gt;&lt;/code&gt; and even a more generic approaches using &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Hope that now you understand a bit better why to use these &lt;strong&gt;Cross-Origin Resource&lt;/strong&gt; features&lt;/p&gt;

&lt;p&gt;Try don't disable or ignore them in your web applications. &lt;strong&gt;Spectre, CSRF, and Meltdown attacks are really dangerous&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>How to Protect Cookies Against Common XSS Attacks on the Web?</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 17 May 2021 21:58:30 +0000</pubDate>
      <link>https://dev.to/obetomuniz/how-to-protect-cookies-against-common-xss-attacks-on-the-web-3p39</link>
      <guid>https://dev.to/obetomuniz/how-to-protect-cookies-against-common-xss-attacks-on-the-web-3p39</guid>
      <description>&lt;p&gt;We can ignore Cookies danger by just not recommending its usage, but the fact is that &lt;a href="https://w3techs.com/technologies/details/ta-googleanalytics#:~:text=google%20analytics%20is%20used%20by%2084.8%25%20of%20all%20the%20websites%20whose%20traffic%20analysis%20tool%20we%20know.%20this%20is%2055.2%25%20of%20all%20websites." rel="noopener noreferrer"&gt;at least 55% of all the websites&lt;/a&gt; use Cookies RIGHT NOW even with lots of existing cookieless strategies.&lt;/p&gt;

&lt;p&gt;So how to protect Cookies against Common XSS Attacks?&lt;/p&gt;

&lt;p&gt;Well, if your app really needs to use Cookies, configure each one  through &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Headers/Set-Cookie" rel="noopener noreferrer"&gt;Set-Cookie HTTP Header&lt;/a&gt; with at least the following flags:&lt;/p&gt;

&lt;p&gt;🍪 &lt;code&gt;Secure&lt;/code&gt;: To allow the Cookie only through HTTPS&lt;/p&gt;

&lt;p&gt;🍪 &lt;code&gt;HttpOnly&lt;/code&gt;: To remove the Cookie from the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie" rel="noopener noreferrer"&gt;document.cookie&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🍪 &lt;code&gt;SameSite&lt;/code&gt;: To limit the Cookie context usage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Set-Cookie: Secure&lt;span class="p"&gt;;&lt;/span&gt;HttpOnly&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;SameSite&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Strict&lt;span class="p"&gt;;&lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope that with these tips, your app now has a few more chances against XSS Attackers that use Cookies breaches. Anyway, keep in mind that complex attacks can easily bypass these tips. So try to migrate ASAP to cookieless strategies.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
    <item>
      <title>XSS Attacks Types on Web</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 10 May 2021 21:03:19 +0000</pubDate>
      <link>https://dev.to/obetomuniz/xss-attacks-types-on-web-36mh</link>
      <guid>https://dev.to/obetomuniz/xss-attacks-types-on-web-36mh</guid>
      <description>&lt;p&gt;Know how each Cross-Site Scripting Attack behaves is crucial to start to think about how vulnerabilities in our web apps allow malicious codes to be executed using the browser to take sensible data from users.&lt;/p&gt;

&lt;p&gt;That's what this article is about. &lt;/p&gt;




&lt;p&gt;🔓 &lt;strong&gt;Reflected XSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;📌 This attack XSS use URL parameters or data submitted via POST in forms to inject malicious code on that server request that persists some data for later execution in the browser. Third-party Browser extensions could even be an access point to inject such a malicious code.&lt;/p&gt;




&lt;p&gt;🔓 &lt;strong&gt;Stored XSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;📌 This attack XSS happens when malicious code is persisted by the attacker directly in the server-side of the web app and is executed by the user (victim) when she accesses the infected application.&lt;/p&gt;




&lt;p&gt;🔓 &lt;strong&gt;DOM XSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;📌 This attack XSS happens when the application manipulates the DOM incorrectly, opening breaches to malicious scripts sent by URL parameters to inject malicious code.&lt;/p&gt;




&lt;p&gt;🔓 &lt;strong&gt;The question is... How to defend against attacks XSS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;📌 There's no formula - A system security is always dependent on that system context, keep this in mind, but there are practices against well-known XSS attacks to stay updated about XSS attacks. &lt;/p&gt;

&lt;p&gt;👉 Start reading about &lt;a href="https://content-security-policy.com/" rel="noopener noreferrer"&gt;Content Security Policy&lt;/a&gt;, &lt;a href="https://observatory.mozilla.org/" rel="noopener noreferrer"&gt;Mozilla Observatory&lt;/a&gt;, &lt;a href="https://owasp.org/www-community/xss-filter-evasion-cheatsheet" rel="noopener noreferrer"&gt;OWASP recommendations&lt;/a&gt;, and &lt;a href="https://www.getrevue.co/profile/obetomuniz" rel="noopener noreferrer"&gt;signing up my newsletter&lt;/a&gt;. As a web security lover, I always talk about it.&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Proxy Pattern in JavaScript</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 03 May 2021 21:03:24 +0000</pubDate>
      <link>https://dev.to/obetomuniz/proxy-pattern-in-javascript-egn</link>
      <guid>https://dev.to/obetomuniz/proxy-pattern-in-javascript-egn</guid>
      <description>&lt;p&gt;Just a catch up about how the Proxy object works on JavaScript to allow us to implement Proxy patterns.&lt;/p&gt;

&lt;p&gt;📌 JavaScript's Proxy object allows us to intercept and modifies any JavaScript object.&lt;/p&gt;

&lt;p&gt;📌 JavaScript's Proxy object is an elegant and safe way for creating or extending libraries, caching, error handling, and complex data manipulation on JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrProxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;arrProxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "default value"&lt;/span&gt;
&lt;span class="nx"&gt;arrProxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 What are the use cases that you most liked to use such a JavaScript feature? &lt;/p&gt;

&lt;p&gt;📚 Still, for a detailed API spec of Proxy's object in JavaScript, take a look in the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy" rel="noopener noreferrer"&gt;MDN docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Earn money using the Web Monetization API</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 26 Apr 2021 16:03:05 +0000</pubDate>
      <link>https://dev.to/obetomuniz/earn-money-using-the-web-monetization-api-4c9k</link>
      <guid>https://dev.to/obetomuniz/earn-money-using-the-web-monetization-api-4c9k</guid>
      <description>&lt;p&gt;&lt;em&gt;Content inspired after I receive &lt;a href="https://twitter.com/obetomuniz/status/1385026594285236234" rel="noopener noreferrer"&gt;my first payment using Web Monetization API&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧑‍🔬  The How
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Sign up to &lt;a href="https://wallet.uphold.com/signup" rel="noopener noreferrer"&gt;wallet.uphold.com/signup&lt;/a&gt; and verify yourself&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find the Interledger Payment Pointer in the Transact panel&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pd0mbyoumewzccnd57p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pd0mbyoumewzccnd57p.png" alt="1" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdsvnqcygexw4burot6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdsvnqcygexw4burot6e.png" alt="2" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;And pick a currency target. It could be USD, BTC, etc &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4e01yeoj1wixdflccllg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4e01yeoj1wixdflccllg.png" alt="3" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Web Monetization API needs a &lt;a href="https://paymentpointers.org/" rel="noopener noreferrer"&gt;Payment Pointer&lt;/a&gt; to address micropayments for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗 The Where
&lt;/h2&gt;

&lt;p&gt;You could now use your already created Uphold's Payment Pointer on your website using this declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"monetization"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"$ilp.your.payment/pointer"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, dozens of services offer support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://help.coil.com/docs/monetize/content/twitch" rel="noopener noreferrer"&gt;Twitch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/devteam/you-can-now-web-monetize-your-dev-posts-but-don-t-get-your-hopes-up-too-quickly-goc"&gt;DEV.to&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hashnode.com/post/how-to-enable-web-monetization-on-your-hashnode-blog-in-2-steps-ckdu4rspj003tn0s1959c0ruq" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cinnamon.video/" rel="noopener noreferrer"&gt;Cinnamon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://help.coil.com/docs/monetize/content/wp-overview" rel="noopener noreferrer"&gt;WordPress&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even &lt;a href="https://help.coil.com/docs/monetize/content/youtube-monetize-channel" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;, when connected in a creator account on &lt;a href="https://coil.com/creator" rel="noopener noreferrer"&gt;Coil&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  💰 The Web Monetization API
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzoxgdhsllxa29qas93x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzoxgdhsllxa29qas93x.png" alt="Web Monetization API" width="800" height="447"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://webmonetization.org/" rel="noopener noreferrer"&gt;Web Monetization API is a W3C Standard&lt;/a&gt; that uses a neutral payment protocol called &lt;a href="https://interledger.org/" rel="noopener noreferrer"&gt;Interledger (ILP)&lt;/a&gt; for transferring money for anyone by anyone. &lt;/p&gt;

&lt;p&gt;The proposal help web creators avoid systems that slow down the web and creates annoying UX&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 More about Web Monetization Standards
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://help.coil.com/docs/monetize/content/get-monetized-overview/index.html" rel="noopener noreferrer"&gt;Get Monetized - A Coil's Overview about Web Monetization API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=dcBxWV8fu8k" rel="noopener noreferrer"&gt;Videoin 🇧🇷 about Web Monetization API on my YouTube Channel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>monetization</category>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>Map and Set in JavaScript for Humans</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 19 Apr 2021 21:37:35 +0000</pubDate>
      <link>https://dev.to/obetomuniz/map-and-set-in-javascript-for-humans-h1k</link>
      <guid>https://dev.to/obetomuniz/map-and-set-in-javascript-for-humans-h1k</guid>
      <description>&lt;p&gt;Would you like to hear more about &lt;code&gt;Set&lt;/code&gt; and &lt;code&gt;Map&lt;/code&gt; objects in JavaScript? &lt;/p&gt;

&lt;p&gt;Let's catch up with them on this thread 🧵&lt;/p&gt;




&lt;p&gt;&lt;code&gt;Set&lt;/code&gt; in JavaScript 👇&lt;/p&gt;

&lt;p&gt;📌 It's not key/value like the Object type. Keys are just values exposed&lt;/p&gt;

&lt;p&gt;📌 Don't accept duplicated values&lt;/p&gt;

&lt;p&gt;📌 It's iterable with &lt;code&gt;forEarch&lt;/code&gt; method and &lt;code&gt;for...of&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;📌 Conceptually is similar to &lt;code&gt;[]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;💡 &lt;code&gt;Set&lt;/code&gt; is useful to remove duplicates on &lt;code&gt;[]&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;Map&lt;/code&gt; in JavaScript 👇&lt;/p&gt;

&lt;p&gt;📌 Allow/preserve any key type. Even objects&lt;/p&gt;

&lt;p&gt;📌 Don't expose insecure data properties&lt;/p&gt;

&lt;p&gt;📌 Iterate with &lt;code&gt;forEarch&lt;/code&gt; method and &lt;code&gt;for...of&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;📌 Stay the insertion order doesn't matter the type&lt;/p&gt;

&lt;p&gt;💡 Prefer &lt;code&gt;Map&lt;/code&gt; instead of &lt;code&gt;{}&lt;/code&gt; for client-side data manipulation.&lt;/p&gt;




&lt;p&gt;Thoughts on &lt;code&gt;Map&lt;/code&gt;, &lt;code&gt;Set&lt;/code&gt;, &lt;code&gt;{}&lt;/code&gt;, and &lt;code&gt;[]&lt;/code&gt; in JavaScript 👇&lt;/p&gt;

&lt;p&gt;📌 Each has a specific usage in JS&lt;/p&gt;

&lt;p&gt;📌 Use &lt;code&gt;{}&lt;/code&gt; for data traffic from the server. &lt;/p&gt;

&lt;p&gt;📌 &lt;code&gt;Set&lt;/code&gt; helps apply omit, diff, etc. on &lt;code&gt;[]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;📌 &lt;code&gt;Map&lt;/code&gt; return size. &lt;code&gt;{}&lt;/code&gt; don't return size&lt;/p&gt;

&lt;p&gt;🗣 There's not a silver bullet. Use them carefully.&lt;/p&gt;




&lt;p&gt;😉 Hope that you now understand better such useful objects on JavaScript, they are highly valuable, and master them will make you a better JavaScript Developer.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using "noopener" and ”noreferrer” against Phishing Attacks</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 12 Apr 2021 19:24:45 +0000</pubDate>
      <link>https://dev.to/obetomuniz/using-noopener-and-noreferrer-against-phishing-attacks-3jj9</link>
      <guid>https://dev.to/obetomuniz/using-noopener-and-noreferrer-against-phishing-attacks-3jj9</guid>
      <description>&lt;p&gt;Want to help users to avoid some Phishing Attacks with &lt;strong&gt;HTML&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;👉 Use &lt;code&gt;rel="noopener noreferrer"&lt;/code&gt; while adding external links to your website to improve user navigation security.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"noopener noreferrer"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 External Link
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🐿 &lt;strong&gt;noopener&lt;/strong&gt;: tells the browser to remove sensitive data from &lt;code&gt;window.opener&lt;/code&gt; object when the user arrives at the destination website.&lt;/p&gt;

&lt;p&gt;🤓 &lt;strong&gt;noreferrer&lt;/strong&gt;: protect sensitive data of the origin website removing it from the &lt;code&gt;Referrer&lt;/code&gt; header while the user navigates between origin website and destination website.&lt;/p&gt;




&lt;p&gt;😋 Super easy security strategy to implement. Adopt this recommendation without moderation. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>cybersecurity</category>
      <category>security</category>
      <category>html</category>
    </item>
    <item>
      <title>CSS Custom Properties with @property</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 05 Apr 2021 14:19:38 +0000</pubDate>
      <link>https://dev.to/obetomuniz/css-custom-properties-with-property-5dgm</link>
      <guid>https://dev.to/obetomuniz/css-custom-properties-with-property-5dgm</guid>
      <description>&lt;p&gt;Have you heard about the CSS &lt;strong&gt;@property&lt;/strong&gt; statement?&lt;/p&gt;




&lt;p&gt;📣 @property is a &lt;strong&gt;CSS Houdini&lt;/strong&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule" rel="noopener noreferrer"&gt;at-rule&lt;/a&gt; that allows us to configure CSS custom properties by data type using the &lt;code&gt;syntax&lt;/code&gt; field, default values using the &lt;code&gt;initial-value&lt;/code&gt; field, and set if it allows inheritance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@property&lt;/span&gt; &lt;span class="n"&gt;--colorPrimary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;syntax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"&amp;lt;color&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;initial-value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;magenta&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Fallback for browsers without @property support. */&lt;/span&gt;
  &lt;span class="py"&gt;--colorPrimary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;magenta&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--colorPrimary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🪄 The nicest aspect about &lt;strong&gt;@property&lt;/strong&gt; is the capability to enhance CSS dynamics through high-level declarations with simplicity and certain performance enhancements.&lt;/p&gt;

&lt;p&gt;🔬 Some use cases for &lt;strong&gt;@property&lt;/strong&gt; statement are data type validation on CSS and animations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@property&lt;/span&gt; &lt;span class="n"&gt;--status&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;initial-value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;syntax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'&amp;lt;percentage&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.progress-bar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;gold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;progress&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;progress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;😋 Really cool, right? &lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CSS Property: content-visibility</title>
      <dc:creator>Beto Muniz</dc:creator>
      <pubDate>Mon, 29 Mar 2021 19:19:01 +0000</pubDate>
      <link>https://dev.to/obetomuniz/css-property-content-visibility-2kn1</link>
      <guid>https://dev.to/obetomuniz/css-property-content-visibility-2kn1</guid>
      <description>&lt;p&gt;👉 The CSS property &lt;code&gt;content-visibility&lt;/code&gt; allows the web developer inform to the browser rendering engine which parts of the page are out of the user view.&lt;/p&gt;

&lt;p&gt;😍 With this info, the browser can optimize the render flow time to focus on where really matters for the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;content-visibility: visible;
content-visibility: hidden;
content-visibility: auto;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🪔  &lt;code&gt;content-visibility&lt;/code&gt; using &lt;code&gt;visible&lt;/code&gt; or &lt;code&gt;hidden&lt;/code&gt; values show or hide respectively the content on a rendering engine level.&lt;/p&gt;

&lt;p&gt;⚡️  &lt;code&gt;content-visibility&lt;/code&gt; with value &lt;code&gt;auto&lt;/code&gt; tells the browser rendering engine to render the elements based on user needs.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>webperf</category>
    </item>
  </channel>
</rss>
