[{"data":1,"prerenderedAt":628},["ShallowReactive",2],{"blog-playwright-en":3},{"slug":4,"published":5,"minutes":6,"category":7,"tags":8,"keywords":13,"about":21,"sources":28,"cover":50,"og":51,"expertise":52,"locales":53,"lang":54,"title":57,"description":58,"coverAlt":59,"metaTitle":60,"takeaways":61,"faq":67,"toc":80,"blocks":105,"others":355},"playwright","2026-05-27",10,"web",[9,10,11,12],"End-to-end testing","Browser automation","MCP","Cross-browser",[4,14,15,16,17,18,19,20],"playwright vs selenium","playwright mcp","browser automation testing","playwright test runner","playwright for ai agents","playwright vs cypress","playwright cloud pricing",[22,25],{"name":23,"url":24},"Playwright","https:\u002F\u002Fplaywright.dev",{"name":26,"url":27},"Model Context Protocol","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FModel_Context_Protocol",[29,32,35,38,41,44,47],{"title":30,"url":31},"Playwright documentation: installation","https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fintro",{"title":33,"url":34},"Playwright MCP introduction","https:\u002F\u002Fplaywright.dev\u002Fmcp\u002Fintroduction",{"title":36,"url":37},"Playwright CLI introduction","https:\u002F\u002Fplaywright.dev\u002Fagent-cli\u002Fintroduction",{"title":39,"url":40},"Playwright Test agents","https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Ftest-agents",{"title":42,"url":43},"npm package metadata for @playwright\u002Ftest","https:\u002F\u002Fregistry.npmjs.org\u002F@playwright\u002Ftest\u002Flatest",{"title":45,"url":46},"Microsoft Learn: Playwright Workspaces free trial","https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fapp-testing\u002Fplaywright-workspaces\u002Fhow-to-try-playwright-workspaces-free",{"title":48,"url":49},"Azure App Testing pricing","https:\u002F\u002Fazure.microsoft.com\u002Fen-us\u002Fpricing\u002Fdetails\u002Fapp-testing\u002F","\u002Fimages\u002Fblog\u002Fplaywright\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fplaywright\u002Fog.jpg","ai-engineer",[54,55,56],"en","de","hu","Playwright: one browser API for tests, scripts and agents","Playwright drives Chromium, Firefox and WebKit from one Apache-2.0 API: a test runner, an agent-facing CLI and an MCP server. What it costs and where it falls short.","A rail with three hanging squares, each holding a different small shape, and three arrows branching left.","Playwright review: tests, scripts and agents · Balázs Csorba",[62,63,64,65,66],"Playwright is Apache-2.0 with no paid edition; the money sits in CI minutes and, optionally, in Microsoft Playwright Workspaces, which bills per test minute by the second after a 30-day trial with 100 minutes.","One API covers Chromium, Firefox and WebKit on Windows, Linux and macOS, with mobile emulation for Android Chrome and Mobile Safari.","The agent surfaces are first-party: an MCP server of 70+ tools reading accessibility snapshots, a token-efficient CLI with a persistent daemon, and planner, generator and healer test agents.","Accessibility snapshots are the design decision that matters for LLM use: elements carry refs instead of pixels, so interaction stays deterministic and no vision model is required.","The runner, not the API, is where the maintenance cost lives: projects, sharding, traces and retries are free of charge but not of upkeep.",[68,71,74,77],{"q":69,"a":70},"Is Playwright free to use?","The framework is Apache-2.0 and has no paid edition. Cost appears as CI minutes and engineering time, and optionally as Microsoft Playwright Workspaces inside Azure App Testing, which bills per test minute, by the second, after a 30-day trial with 100 minutes.",{"q":72,"a":73},"Should an agent use the MCP server or the CLI?","The documentation puts the CLI ahead for coding agents: shell commands with concise output avoid loading tool schemas and accessibility trees into context. MCP suits exploratory loops that benefit from persistent state and structured parameters, and it opens a headed browser while the CLI defaults to headless.",{"q":75,"a":76},"How does Playwright differ from Selenium?","Playwright drives browsers through its own protocols and ships one API, a runner with auto-waiting and web-first assertions, and version-pinned browser binaries. Selenium speaks W3C WebDriver, which matters when a contract or a vendor grid requires it, and otherwise costs more glue for the same flows.",{"q":78,"a":79},"Can Playwright generate and repair tests with an LLM?","Yes, first-party: npx playwright init-agents installs planner, generator and healer definitions that write a Markdown test plan, turn it into specs, and patch failing tests by replaying steps and re-inspecting the page. The healer may also skip a test it believes is broken, which is a sensible default and a bad one to leave unnoticed.",[81,84,87,90,93,96,99,102],{"id":82,"title":83},"what-it-is","What it is",{"id":85,"title":86},"how-it-works","How it works",{"id":88,"title":89},"getting-started","Getting started",{"id":91,"title":92},"ai-agents","Agents at the wheel",{"id":94,"title":95},"pricing","Pricing",{"id":97,"title":98},"where-it-shingles","Where it shingles",{"id":100,"title":101},"verdict","Verdict",{"id":103,"title":104},"sources","Sources",[106,110,118,121,124,142,143,146,152,155,156,171,173,176,190,191,194,196,214,217,220,230,231,234,244,247,248,251,307,310,311,314,326,330,331],{"type":107,"content":108},"paragraph",[109],"Playwright is Microsoft’s browser automation library, and by now it is three products in one repository: a test runner, a scripting library, and an agent-facing surface made of an MCP server and a command-line tool. It is Apache-2.0, it has no paid edition, and it remains the most ergonomic API in this category. The position of this review: it is the default for new end-to-end work, and its agent surfaces are the reason to look again at an existing suite.",{"type":107,"content":111},[112,113,117],"It competes with Selenium, Cypress and Puppeteer, and increasingly with hand-written scraping and QA scripts, because the same ",{"tag":114,"children":115},"code",[116],"page"," object now serves a test in CI, a nightly report and an LLM driving a browser through accessibility snapshots. Nothing in the core requires a model: the agent tooling sits on top and can be ignored, which is why teams adopt it as a testing tool first and discover the agent layer later.",{"type":119,"level":120,"id":82,"text":83},"heading",2,{"type":107,"content":122},[123],"The project ships browser automation for Chromium, Firefox and WebKit on Windows, Linux and macOS, locally or in CI, headless or headed, with native mobile emulation for Android Chrome and Mobile Safari. The current line is 1.63, published in September 2026, and the browser binaries are pinned to that release.",{"type":125,"ordered":126,"items":127},"list",false,[128,130,132,134,136,138,140],[129],"Apache-2.0 with no paid edition; the npm package declares Node 20 or newer as its engine.",[131],"One API in four languages: JavaScript and TypeScript, Python, Java and .NET.",[133],"A test runner with auto-waiting, web-first assertions, fixtures, parallel projects, sharding, retries and an HTML report.",[135],"Browser contexts give every test a fresh profile, so authentication state is a fixture rather than a shared global.",[137],"Tooling around the run: codegen, UI mode, the trace viewer, network mocking, clock control and aria snapshots.",[139],"Official container images published per release, which is what keeps CI browsers identical to the local ones.",[141],"Three agent-facing surfaces: an MCP server, a CLI with installable skills, and planner, generator and healer test agents.",{"type":119,"level":120,"id":85,"text":86},{"type":107,"content":144},[145],"The driver speaks to each browser over its own protocol — patched Chromium and Firefox builds plus a patched WebKit — which is how one API can offer the same capabilities on all three engines instead of the lowest common denominator. Locators are resolved when the action runs and every action waits for the element to become actionable, so the usual fix for a flaky test is an assertion rather than a sleep.",{"type":147,"src":148,"alt":149,"wide":150,"caption":151},"image","\u002Fimages\u002Fblog\u002Fplaywright\u002Fdiagram-7.webp","Playwright test run A spec file goes to the runner, which spreads the tests over browser projects. A driver talks to Chromium, Firefox and WebKit, every test runs in a fresh browser context, and the report collects the traces. Snapshots and the agent surfaces hang underneath the same driver.",true,"One driver, three engines, and the same page API for the test in CI, the nightly script and the agent.",{"type":107,"content":153},[154],"Above the driver sits the runner, where most of the value accumulates: a config file declares the projects — browsers, viewports, credentials — tests are distributed across workers, sharding splits them across machines, and every failure carries a trace that can be replayed step by step. That trace is also what makes an assisted diagnosis practical, because it is structured data rather than a screenshot of a stack trace.",{"type":119,"level":120,"id":88,"text":89},{"type":107,"content":157},[158,159,162,163,166,167,170],"One scaffold, one install, one run: ",{"tag":114,"children":160},[161],"npm init playwright@latest"," writes the config and a first spec, ",{"tag":114,"children":164},[165],"npx playwright install --with-deps"," fetches the pinned browser binaries with their system libraries, and ",{"tag":114,"children":168},[169],"npx playwright test"," runs headless and in parallel across the three engines.",{"type":114,"code":172},"import { test, expect, devices } from '@playwright\u002Ftest';\n\ntest('order confirmation shows a number', async ({ page }) => {\n  await page.goto('\u002Fcheckout');\n  await page.getByLabel('Email').fill('qa@example.com');\n  await page.getByRole('button', { name: 'Place order' }).click();\n  await expect(page.getByRole('status')).toContainText(\u002FOrder WS-\\d+\u002F);\n});\n\ntest.describe('phone', () => {\n  test.use({ ...devices['iPhone 15'] });\n  test('checkout renders on a phone viewport', async ({ page }) => {\n    await page.goto('\u002Fcheckout');\n    await expect(page.getByRole('heading', { name: 'Checkout' })).toBeVisible();\n  });\n});",{"type":107,"content":174},[175],"What dates quickly is not the runner but the selectors. The project’s own advice is to prefer role and label locators, to keep assertions web-first so they re-check until the timeout instead of sampling once, and to open a trace on failure rather than guess from a stack.",{"type":177,"variant":178,"title":179,"body":180},"callout","tip","Version discipline",[181],[182,183,186,187,189],"Browsers ship pinned to the release, so upgrading ",{"tag":114,"children":184},[185],"@playwright\u002Ftest"," means re-running ",{"tag":114,"children":188},[165],": an image built for 1.62 will not find the binaries it expects. Keep package and browsers pinned together, and regenerate the agent definitions after every upgrade — the documentation says explicitly that they should be re-created whenever Playwright changes.",{"type":119,"level":120,"id":91,"text":92},{"type":107,"content":192},[193],"This is the part that changed the tool’s standing. Playwright is now a standard way for a language model to operate a browser, and the project ships three routes to it, all first-party.",{"type":114,"code":195},"# MCP server: structured tool calls, accessibility snapshots with element refs\n{\n  \"mcpServers\": {\n    \"playwright\": { \"command\": \"npx\", \"args\": [\"@playwright\u002Fmcp@latest\"] }\n  }\n}\n\n# CLI: shell commands for a coding agent, headless by default\nnpm install -g @playwright\u002Fcli\nplaywright-cli open https:\u002F\u002Fexample.com\nplaywright-cli snapshot\nplaywright-cli click e5\n\n# Test agents: planner, generator and healer, installed into the repo\nnpx playwright init-agents --loop=vscode",{"type":125,"ordered":126,"items":197},[198,204,206,212],[199,200,203],"The MCP server returns accessibility snapshots: every element carries a ref such as ",{"tag":114,"children":201},[202],"e5",", so the model clicks a reference instead of guessing coordinates, and no vision model is needed. The documentation lists 70+ tools, with network mocking, storage, tracing and video behind capability flags.",[205],"The CLI is the token-efficient route: concise output, a persistent daemon so commands do not pay browser start-up, skills discovered on demand, and sessions that keep state between commands.",[207,208,211],"Playwright Test agents — planner, generator and healer — write a Markdown test plan, turn it into specs and patch failing tests by replaying steps and re-inspecting the page; ",{"tag":114,"children":209},[210],"npx playwright init-agents"," installs the definitions for VS Code, Claude Code, Codex and OpenCode.",[213],"The documentation states the trade directly: MCP suits specialised agentic loops and exploratory automation, the CLI suits coding agents working with large codebases, and the CLI starts headless while MCP opens a headed browser.",{"type":107,"content":215},[216],"Token economics decide this choice more often than features do. An MCP round trip puts tool schemas and a fresh snapshot into context on every step; a CLI command returns a path to a YAML snapshot and one line of status. For a long-running agent that only has to click through a flow, that difference is the gap between a session that fits in context and one that does not.",{"type":107,"content":218},[219],"Screenshots still exist — they are one tool call away, and vision mode puts the mouse on coordinates — but they cost tokens by the pixel and reintroduce exactly the ambiguity the snapshot design removed. The accessibility tree is a summary the model can act on; a screenshot is evidence it has to interpret.",{"type":177,"variant":221,"title":222,"body":223},"warn","One tool is remote code execution",[224],[225,226,229],"The MCP server exposes ",{"tag":114,"children":227},[228],"browser_run_code_unsafe",", which runs arbitrary JavaScript in the Playwright server process; the documentation calls it RCE-equivalent and says to enable it only for trusted clients. A headless browser left without tool calls for an hour is closed automatically, headed ones are not, and the extension connector can attach to a browser that already holds live logins — scope the client before you scope the browser.",{"type":119,"level":120,"id":94,"text":95},{"type":107,"content":232},[233],"The framework costs nothing, and there is no Pro tier, no seat count and no usage meter. Cost appears in three places: the CI minutes the suite burns, the engineering time that keeps it green, and, only when a managed grid is wanted, Microsoft’s first-party cloud.",{"type":125,"ordered":126,"items":235},[236,238,240,242],[237],"Framework: free under Apache-2.0, unlimited projects, unlimited tests, no licence to renew.",[239],"Playwright Workspaces in Azure App Testing: pay-as-you-go per test minute, billed by the second, with a 30-day trial covering 100 minutes; beyond that the workspace converts to the metered plan, and published rates are region-dependent.",[241],"Third-party grids such as BrowserStack and Sauce Labs bill per parallel session or subscription, and are needed only for real devices, a wider browser matrix or compliance.",[243],"The largest line is never the licence: flaky-test triage and selector upkeep are the recurring cost, and no plan covers them.",{"type":107,"content":245},[246],"Because the runner is free, the migration question is usually about time rather than budget. Moving an existing suite means rewriting selectors, fixtures and custom commands, and the payback arrives with the second month of maintenance rather than on the first green build.",{"type":119,"level":120,"id":97,"text":98},{"type":107,"content":249},[250],"The weaknesses are known and mostly accepted. Browser binaries are pinned per release, so an upgrade is a scheduled task that drags CI images along with it. The breadth of the runner is a lot of surface before a team sees any benefit from sharding and traces. WebKit here is a patched build rather than Safari itself, so an Apple-specific defect can still surface late. And the CLI and MCP layers are new enough that their command sets move between minor releases.",{"type":252,"head":253,"rows":261},"table",[254,256,257,259],[255],"",[23],[258],"Selenium",[260],"Cypress",[262,271,280,289,298],[263,265,267,269],[264],"Driver",[266],"Own protocol per browser",[268],"W3C WebDriver",[270],"Proxy injected in the page",[272,274,276,278],[273],"Browsers",[275],"Chromium, Firefox, WebKit",[277],"Any WebDriver browser",[279],"Chrome, Firefox, Edge, Electron",[281,283,285,287],[282],"Runner",[284],"Built in: parallel, sharding, traces",[286],"Bring your own",[288],"Built in, sharding via plugins",[290,292,294,296],[291],"Agent surfaces",[293],"MCP, CLI and test agents",[295],"Community MCP servers",[297],"Community plugins",[299,301,303,305],[300],"Best fit",[302],"New suites and agent-driven work",[304],"Legacy stacks and vendor grids",[306],"Component-heavy front-end teams",{"type":107,"content":308},[309],"The honest comparison is about scope rather than quality. Selenium stays the answer when a contract demands WebDriver or a device cloud; Cypress is comfortable for teams already invested in its component test runner; Puppeteer is a library, not a framework, and is the right size for a script. Playwright claims that one tool covers all four jobs, and the maintenance cost of that claim is the browser matrix you now run in CI.",{"type":119,"level":120,"id":100,"text":101},{"type":107,"content":312},[313],"Playwright is the strongest default in browser automation, and the interesting question is no longer whether to adopt it but which of its three surfaces to expose to whom.",{"type":125,"ordered":150,"items":315},[316,318,320,322,324],[317],"Adopt it for new end-to-end work. Runner, context isolation and the trace viewer pay off after the second month, which is exactly when a thinner tool starts costing more.",[319],"Adopt it when an agent has to drive a browser. Refs and roles are cheaper and more deterministic than pixels, and the project maintains the MCP and CLI routes itself instead of leaving them to the community.",[321],"Budget for the upgrade cadence: a release line that pulls new browser binaries every few weeks means lockfile, image and browsers move together or not at all.",[323],"Keep Selenium where WebDriver or a device cloud is contractual, and do not rewrite a green Cypress suite only because the API elsewhere is nicer.",[325],"Do not treat the test agents as review. The healer may skip a test it believes is broken, which is a sensible default and a bad one to leave unnoticed.",{"type":327,"content":328},"quote",[329],"The browser is no longer only the thing under test; it is also the interface an agent operates. Tools that expose it as structured state — roles, refs, text — will age better than tools that expose it as pixels.",{"type":119,"level":120,"id":103,"text":104},{"type":125,"ordered":150,"items":332},[333,337,340,343,346,349,352],[334],{"tag":335,"href":31,"children":336},"a",[30],[338],{"tag":335,"href":34,"children":339},[33],[341],{"tag":335,"href":37,"children":342},[36],[344],{"tag":335,"href":40,"children":345},[39],[347],{"tag":335,"href":43,"children":348},[42],[350],{"tag":335,"href":46,"children":351},[45],[353],{"tag":335,"href":49,"children":354},[48],[356,430,486,560],{"slug":357,"published":358,"minutes":6,"category":7,"tags":359,"keywords":365,"about":377,"sources":386,"cover":423,"og":424,"expertise":425,"locales":426,"lang":54,"title":427,"description":428,"coverAlt":429},"schema-org-structured-data-b2b-shop","2026-10-17",[360,361,362,363,364],"Schema.org","Structured data","B2B e-commerce","Technical SEO","Nuxt",[366,367,368,369,370,371,372,373,374,375,376],"schema.org b2b shop","product structured data b2b","merchant listing structured data","product snippet vs merchant listing","unitpricespecification referencequantity","productgroup variants structured data","organization schema vatid","b2b prices behind login seo","json-ld nuxt schema org","merchant return policy structured data","mpn gtin structured data",[378,380,383],{"name":360,"url":379},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSchema.org",{"name":381,"url":382},"JSON-LD","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FJSON-LD",{"name":384,"url":385},"Business-to-business","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBusiness-to-business",[387,390,393,396,399,402,405,408,411,414,417,420],{"title":388,"url":389},"Google Search Central: Introduction to Product structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fproduct",{"title":391,"url":392},"Google Search Central: Merchant listing (Product, Offer) structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fmerchant-listing",{"title":394,"url":395},"Google Search Central: Product snippet structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fproduct-snippet",{"title":397,"url":398},"Google Search Central: Product variant structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fproduct-variants",{"title":400,"url":401},"Google Search Central: Organization structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Forganization",{"title":403,"url":404},"Google Search Central: Merchant return policy structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Freturn-policy",{"title":406,"url":407},"Google Search Central: General structured data guidelines","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fsd-policies",{"title":409,"url":410},"Google Search Central: Generate structured data with JavaScript","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fgenerate-structured-data-with-javascript",{"title":412,"url":413},"Schema.org: Offer","https:\u002F\u002Fschema.org\u002FOffer",{"title":415,"url":416},"Schema.org: UnitPriceSpecification","https:\u002F\u002Fschema.org\u002FUnitPriceSpecification",{"title":418,"url":419},"Unhead: Product schema (defineProduct)","https:\u002F\u002Funhead.unjs.io\u002Fdocs\u002Fschema-org\u002Fapi\u002Fschema\u002Fproduct",{"title":421,"url":422},"Nuxt SEO: Schema.org identity setup","https:\u002F\u002Fnuxtseo.com\u002Fdocs\u002Fschema-org\u002Fguides\u002Fsetup-identity","\u002Fimages\u002Fblog\u002Fschema-org-structured-data-b2b-shop\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fschema-org-structured-data-b2b-shop\u002Fog.jpg","b2b-ecommerce-developer",[54,55,56],"Schema.org structured data for B2B shops: prices behind logins, units and variants","Product markup for B2B shops: snippet or merchant listing, which price to publish, part numbers, unit pricing, variants, Organization and SSR in Nuxt.","A product rectangle with a framed outline and a small price slot hidden behind a low wall.",{"slug":431,"published":358,"minutes":432,"category":7,"tags":433,"keywords":438,"about":450,"sources":458,"cover":480,"og":481,"expertise":425,"locales":482,"lang":54,"title":483,"description":484,"coverAlt":485},"ai-assistant-b2b-shop-customer-support",9,[362,434,435,436,437],"AI assistant","Customer support","LLM agents","EU AI Act",[439,440,441,442,443,444,445,446,447,448,449],"ai assistant b2b shop","ai customer support b2b ecommerce","llm chatbot order status","ai agent customer service tools","chatbot liability air canada","klarna ai assistant results","human handoff chatbot design","eu ai act chatbot disclosure","owasp excessive agency","ai support resolution rate","b2b customer portal chatbot",[451,454,457],{"name":452,"url":453},"Customer service","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCustomer_service",{"name":455,"url":456},"Chatbot","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FChatbot",{"name":384,"url":385},[459,462,465,468,471,474,477],{"title":460,"url":461},"Klarna: AI assistant handles two-thirds of customer service chats in its first month (press release, 2024)","https:\u002F\u002Fwww.klarna.com\u002Finternational\u002Fpress\u002Fklarna-ai-assistant-handles-two-thirds-of-customer-service-chats-in-its-first-month\u002F",{"title":463,"url":464},"Entrepreneur: Klarna is hiring customer service agents again, according to its CEO (May 2025)","https:\u002F\u002Fwww.entrepreneur.com\u002Fbusiness-news\u002Fklarna-ceo-reverses-course-by-hiring-more-humans-not-ai\u002F491396",{"title":466,"url":467},"ABA Business Law Today: BC tribunal confirms companies remain liable for information provided by AI chatbot","https:\u002F\u002Fwww.americanbar.org\u002Fgroups\u002Fbusiness_law\u002Fresources\u002Fbusiness-law-today\u002F2024-february\u002Fbc-tribunal-confirms-companies-remain-liable-information-provided-ai-chatbot\u002F",{"title":469,"url":470},"OWASP GenAI Security Project: LLM06:2025 Excessive Agency","https:\u002F\u002Fgenai.owasp.org\u002Fllmrisk\u002Fllm062025-excessive-agency\u002F",{"title":472,"url":473},"OWASP GenAI Security Project: LLM05:2025 Improper Output Handling","https:\u002F\u002Fgenai.owasp.org\u002Fllmrisk\u002Fllm052025-improper-output-handling\u002F",{"title":475,"url":476},"EU AI Act, Article 50: Transparency obligations","https:\u002F\u002Fartificialintelligenceact.eu\u002Farticle\u002F50\u002F",{"title":478,"url":479},"Intercom: Fin pricing and billable outcomes","https:\u002F\u002Ffin.ai\u002Fpricing","\u002Fimages\u002Fblog\u002Fai-assistant-b2b-shop-customer-support\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fai-assistant-b2b-shop-customer-support\u002Fog.jpg",[54,55,56],"An AI assistant for B2B shop support: tools, permissions and the human handoff","How to build an AI support assistant for a B2B shop: which requests to automate, tools that run in the customer context, handoff, AI Act and metrics.","A tall wall with one narrow gap; an arrow passes through it into a boxed enclosure of three squares, and another leads down to a tray.",{"slug":487,"published":358,"minutes":488,"category":7,"tags":489,"keywords":494,"about":506,"sources":516,"cover":553,"og":554,"expertise":555,"locales":556,"lang":54,"title":557,"description":558,"coverAlt":559},"vue-ai-chat-ui-streaming-accessibility",11,[490,364,491,492,493],"Vue","Accessibility","Streaming","AI chat",[495,496,497,498,499,500,501,502,503,504,505],"vue ai chat ui","nuxt llm streaming","sse vs fetch streaming","aria-live streaming text","accessible chat interface","abort fetch stream vue","dompurify markdown llm","role log chat","reduced motion chat ui","wcag 2.2 chat","screen reader streaming",[507,510,513],{"name":508,"url":509},"Web accessibility","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWeb_accessibility",{"name":511,"url":512},"Server-sent events","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FServer-sent_events",{"name":514,"url":515},"Vue.js","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FVue.js",[517,520,523,526,529,532,535,538,541,544,547,550],{"title":518,"url":519},"MDN: Using server-sent events","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FServer-sent_events\u002FUsing_server-sent_events",{"title":521,"url":522},"MDN: AbortController","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FAbortController",{"title":524,"url":525},"MDN: ReadableStream","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FReadableStream",{"title":527,"url":528},"MDN: TextDecoderStream","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FTextDecoderStream",{"title":530,"url":531},"MDN: ARIA log role","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAccessibility\u002FARIA\u002FReference\u002FRoles\u002Flog_role",{"title":533,"url":534},"W3C: Understanding SC 4.1.3 Status Messages","https:\u002F\u002Fwww.w3.org\u002FWAI\u002FWCAG22\u002FUnderstanding\u002Fstatus-messages.html",{"title":536,"url":537},"W3C WAI: What's new in WCAG 2.2","https:\u002F\u002Fwww.w3.org\u002FWAI\u002Fstandards-guidelines\u002Fwcag\u002Fnew-in-22\u002F",{"title":539,"url":540},"MDN: prefers-reduced-motion","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FCSS\u002F@media\u002Fprefers-reduced-motion",{"title":542,"url":543},"DOMPurify README","https:\u002F\u002Fgithub.com\u002Fcure53\u002FDOMPurify",{"title":545,"url":546},"markdown-it README","https:\u002F\u002Fgithub.com\u002Fmarkdown-it\u002Fmarkdown-it",{"title":548,"url":549},"AI SDK docs: useChat","https:\u002F\u002Fai-sdk.dev\u002Fdocs\u002Fai-sdk-ui\u002Fchatbot",{"title":551,"url":552},"Vue docs: nextTick","https:\u002F\u002Fvuejs.org\u002Fapi\u002Fgeneral.html#nexttick","\u002Fimages\u002Fblog\u002Fvue-ai-chat-ui-streaming-accessibility\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fvue-ai-chat-ui-streaming-accessibility\u002Fog.jpg","vue-nuxt-developer",[54,55,56],"Streaming AI chat in Vue and Nuxt: accessible by design","How to build a Vue or Nuxt AI chat UI: fetch streams, abort and retry, safe markdown rendering, aria-live announcements, keyboard support and reduced motion.","A message card with a careful caret, a dotted line opening into ripples and a check.",{"slug":561,"published":358,"minutes":432,"category":7,"tags":562,"keywords":567,"about":579,"sources":589,"cover":622,"og":623,"expertise":555,"locales":624,"lang":54,"title":625,"description":626,"coverAlt":627},"llm-translation-pipeline-i18n",[563,564,565,490,566],"Translation","i18n","LLM","Localization",[568,569,570,571,572,573,574,575,576,577,578],"llm translation pipeline","icu messageformat placeholders","vue i18n llm translation","translation memory llm","glossary enforcement translation","german informal sie du","hungarian translation quality llm","structured output json translation","machine translation post-editing","locale file validation","cldr plural categories",[580,583,586],{"name":581,"url":582},"Internationalization and localization","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FInternationalization_and_localization",{"name":584,"url":585},"ICU MessageFormat","https:\u002F\u002Funicode-org.github.io\u002Ficu\u002Fuserguide\u002Fformat_parse\u002Fmessages\u002F",{"name":587,"url":588},"Vue I18n","https:\u002F\u002Fvue-i18n.intlify.dev\u002F",[590,592,595,598,601,604,607,610,613,616,619],{"title":591,"url":585},"Unicode ICU User Guide: Formatting Messages",{"title":593,"url":594},"Vue I18n: Message Format Syntax","https:\u002F\u002Fvue-i18n.intlify.dev\u002Fguide\u002Fessentials\u002Fsyntax",{"title":596,"url":597},"Nuxt i18n: Getting started","https:\u002F\u002Fi18n.nuxtjs.org\u002Fdocs\u002Fgetting-started",{"title":599,"url":600},"Unicode CLDR: Plural rules","https:\u002F\u002Fcldr.unicode.org\u002Findex\u002Fcldr-spec\u002Fplural-rules",{"title":602,"url":603},"OpenAI: Structured outputs","https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Fstructured-outputs",{"title":605,"url":606},"DeepL API: Glossaries","https:\u002F\u002Fdevelopers.deepl.com\u002Fdocs\u002Fapi-reference\u002Fglossaries",{"title":608,"url":609},"W3C: Localization vs. internationalization","https:\u002F\u002Fwww.w3.org\u002FInternational\u002Fquestions\u002Fqa-i18n",{"title":611,"url":612},"GNU gettext manual","https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fgettext\u002Fmanual\u002Fgettext.html",{"title":614,"url":615},"RFC 5646: Tags for Identifying Languages","https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc5646",{"title":617,"url":618},"Rat für deutsche Rechtschreibung","https:\u002F\u002Fwww.rechtschreibrat.com\u002F",{"title":620,"url":621},"Microsoft Writing Style Guide","https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fstyle-guide\u002Fwelcome\u002F","\u002Fimages\u002Fblog\u002Fllm-translation-pipeline-i18n\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fllm-translation-pipeline-i18n\u002Fog.jpg",[54,55,56],"An LLM translation pipeline for i18n: glossary, placeholders and review","How to translate product and website strings with LLMs without breaking placeholders, plurals or tone: glossary, ICU messages, QA checks and review gates.","Three source cards, one translated card with a glossary ribbon, then a checked clipboard.",1792261156581]