A Better Widget helps article readers complete one task without leaving the page. It can calculate, estimate, convert, generate, assess, or track progress.
Before implementation, define the user goal, inputs, logic, result, host, and visual context. Use the existing UI and UX principles for shared visual and form rules.
Minimum build contract
- Keep the calculation or transformation in one pure function. Define its units, ranges, assumptions, precision, and boundary tests.
- Choose controls that help the reader explore the model. A number field alone is not automatically the best interface.
- Pair custom controls and direct manipulation with a labelled, exact editable value, keyboard support, and an equivalent touch action.
- Give every input a persistent label. Show invalid state in text and code, focus the first invalid field, and keep the result readable as text.
- Render the purpose, method, assumptions, and an example in the initial HTML when the framework supports it. Never promise search rankings.
- Keep local calculations local, avoid large dependencies for small tasks, reserve result space, and measure the whole page on a slow mobile profile.
- Do not record inputs, generated text, answers, checklist state, or results by default. Never put sensitive values in URLs, logs, or analytics.
- Require expert review and primary sources for high-stakes health, legal, safety, or financial widgets. A disclaimer does not repair unsafe logic.
- Call
get-review-rules,review-ui-code, andcheck-comprehension. Fix every critical and serious issue before handoff.
Start with the reader's job
Define these facts before writing code:
- User goal: who will use the widget, and what decision or task will it help them complete?
- Inputs: what information must the user provide, including units, allowed ranges, and useful defaults?
- Transformation: what calculation, scoring rule, conversion, or other logic produces the result?
- Result: what will the widget show, explain, and let the user do next?
- Host framework: which page, framework, and component system will contain it?
- Visual context: which existing tokens, components, or brand reference must it match?
Do not build a widget only because a keyword exists. Build it when the intended audience would use it without a search-ranking benefit. Google recommends people-first content and warns against scaled pages that add little value.
Keep the widget close to the explanation that gives it meaning. The page must explain what the tool does, who it is for, and how to interpret its result.
Match the contract to the widget type
Calculator
- Define the formula, units, precision, rounding, and valid range.
- State whether the result is exact, simplified, or based on assumptions.
- Keep financial values in integer minor units or use an exact decimal library.
- Test known examples, zero, negative values when allowed, boundaries, and large values.
Estimator
- Show that the result is an estimate.
- Name every assumption that can materially change the result.
- Prefer a range when a single number would imply false precision.
- Explain what is excluded and when the reader needs a professional or primary source.
Converter
- Name the source and target units beside their controls.
- Define the conversion constant and its source when it can change.
- Make reverse conversion use the same canonical logic.
- Preserve enough internal precision to avoid drift across repeated conversions.
Generator
- State which inputs affect the output.
- Make the same inputs produce the same result unless randomness is part of the user goal.
- If randomness is required, let the user generate another result and preserve a chosen result.
- Never claim that generated output is verified, unique, safe, or legally valid without evidence.
Quiz
- Define the scoring rule before writing questions.
- Make each option clear without relying on color or position.
- Explain the result and the limits of the score.
- Never present a quiz as a diagnosis, certification, or professional assessment without a valid basis.
Checklist
- Let the user change every item directly.
- Keep progress meaningful. Do not reward checking items that do not advance the stated goal.
- Persist progress only when that helps the user, and provide a clear reset.
- Do not send item state to analytics by default.
Keep the logic as one source of truth
Put the calculation or transformation in a pure domain function. Keep rendering, analytics, URL state, and network calls outside it.
Use the same constants for the executable logic, the visible assumptions, and the tests. If a rate, threshold, weight, or formula changes, one edit must update the result and its explanation together.
Document these parts beside the domain function:
- accepted inputs and units
- normalization and parsing rules
- formula or transformation steps
- assumptions and exclusions
- precision and rounding
- result type and error cases
- source and review date for any external rate or rule
Write table-driven tests with representative values and boundaries. For an inverse operation, test round trips within the stated precision. For a score, test every threshold and tie rule.
High-stakes health, legal, safety, or financial widgets need expert review and primary sources. A disclaimer does not repair an unsafe calculation.
Design the input and result behavior
Call get-ui-principle for hierarchy, spacing, typography, color, and accessibility. Call get-ux-principle for forms, errors, responsive behavior, and microcopy.
Apply these widget-specific rules:
- Use a real
formwhen the user submits a set of inputs. - Use presets, steppers, sliders, dials, drag controls, or direct manipulation when they make a range or relationship easier to understand.
- Keep an exact editable value beside a custom control. The custom control must work with a keyboard and a 44 by 44 CSS pixel touch target.
- Treat a custom control as a useful input method, not decoration. Do not remove native semantics or hide the current value.
- Give every input a persistent label. Put the unit in the label or beside the value.
- Use a placeholder only as an example. Never use it as the only label or default.
- Keep submit enabled until submission starts. Let submission reveal missing or invalid fields.
- Show an error beside its field, identify the error in text, set
aria-invalid="true", and connect it witharia-describedby. - On submit, focus the first invalid field. Do not move focus during valid live calculation.
- Use live calculation only when it is fast, local, and unsurprising. Otherwise use a specific action such as
Calculate estimate. - Do not show an error for a partially typed number. Validate after blur or submission unless the value becomes harmful immediately.
- Put the primary result next to the inputs on wide screens and after them in reading order on narrow screens.
- Announce a changed result through a polite live region without reading every intermediate keystroke.
- Keep the result visible as text. A chart can support it, but it cannot be the only result.
- Do not animate a number count-up. The reader needs the value, not a delay.
- Keep copy, reset, and share actions secondary to the result.
Use locale-aware number and date formatting. Keep units with their values, and never infer a language from location alone.
Make the page useful to people and search engines
The widget is part of the page, not a substitute for its content. Render the title, purpose, method, assumptions, and a representative example in the initial HTML when the framework supports it.
Google can render JavaScript, but rendering happens after crawling and can wait in a queue. Server rendering or pre-rendering remains useful for people, crawlers, and bots that do not run JavaScript.
Follow these rules:
- Give the page a unique title, description, canonical URL, and crawlable internal links.
- Keep the same useful content visible to people and search engines.
- Do not hide keyword text, fake results, or generated examples for crawlers.
- Do not create many near-duplicate widget pages by changing only a keyword, location, or unit.
- Add structured data only when Google supports a type that accurately describes the visible page.
- Do not invent a schema type or promise a rich result. Valid structured data does not guarantee a search feature.
- Validate supported structured data with the Rich Results Test and inspect the rendered page in Search Console after deployment.
Do not promise that a widget will improve rankings. Measure whether it helps the intended reader, earns engagement, and supports the page's subject.
Protect page performance
Start with the host project's performance budget. Keep the widget's initial JavaScript and dependencies smaller than the value they add.
- Render the page explanation and initial controls without waiting for widget JavaScript.
- Keep local calculations local. Do not call a server on each keystroke.
- Load large charts, editors, maps, or generation libraries only when the user needs them.
- Move expensive work off the main thread when it can block input.
- Reserve enough result space to prevent avoidable layout shifts.
- Test a low-end mobile device or an equivalent CPU and network throttle.
- Measure the whole page, not only the isolated component.
Use current Core Web Vitals guidance instead of copying thresholds into product code. Check loading, interaction responsiveness, and layout stability in field data after launch.
Keep analytics useful and private
Define the measurement question before adding an event. A small widget usually needs only aggregate events such as:
widget_viewedwidget_startedwidget_completedwidget_result_copiedwidget_result_sharedwidget_error
Do not record entered values, generated text, quiz answers, checklist state, or result values by default. These fields can contain personal, health, legal, financial, or commercial information.
Use coarse properties such as widget type, page path, completion state, and error category. Follow the host site's consent and retention rules. Never put sensitive inputs into a share URL, analytics payload, log, or error report.
If URL state helps sharing, include only non-sensitive, validated values. Give the user a clear copy action and make the URL restore the same result.
Build and verify the widget
- Inspect the host framework, tokens, components, analytics, tests, and page-rendering model.
- Complete the Better Widget intake.
- Load the relevant UI and UX principles.
- Write the pure domain function and its boundary tests.
- Build the form and result with the host components and semantic tokens.
- Add URL state, sharing, or analytics only when the user goal needs them.
- Test keyboard use, touch targets, labels, errors, result announcements, long content, localization, and mobile layout.
- Test the initial HTML, JavaScript failure, performance, metadata, canonical URL, and structured data when present.
- Call
get-review-rules,review-ui-code, andcheck-comprehension. Fix every critical and serious finding. - When a rendered DOM is available, run
inspect-spacingand review desktop and mobile screenshots.
Reject unsafe or misleading output
Treat these findings as critical:
- The result is wrong for a valid input.
- The result hides a material assumption or presents an estimate as exact.
- The widget makes a health, legal, safety, or financial claim without a valid source and review.
- The interface collects or exposes sensitive data without a clear need and consent path.
- A person cannot identify, operate, or understand an input or result with assistive technology.
Treat these findings as serious:
- Units, ranges, precision, rounding, or exclusions are unclear.
- The page depends on client rendering for all useful explanation.
- Errors appear only at the top, only through color, or while the user is still typing a valid value.
- The widget adds a large dependency or network request for a small local calculation.
- Analytics captures user values instead of aggregate behavior.
- The page uses unsupported structured data or promises a ranking gain.
- The widget looks like a separate dashboard instead of part of the host article.