Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Safely rendering generated UI means treating the output as untrusted data, not as code. Parse a serialized component description, validate it against a narrow, versioned schema, map approved component IDs to components you control, and render ordinary values through your framework’s escaping rules. Reject unknown structures, constrain URLs, keep authorization on the server, and test the rendered result at real viewport, keyboard, and screen-reader paths.

This approach supports AI-generated interfaces and other runtime-generated screens without handing generated text the ability to inject markup, import modules, or perform privileged actions. It also gives you a clear failure mode: an invalid description becomes a safe fallback or useful error instead of a partially trusted interface.

What “dynamically generated UI” should mean

A generated interface should be a data document that describes presentation, not executable source code. A payload might identify a card, heading, list, form field, or button and provide the text and constrained properties needed to render it. Your application remains responsible for component code, event handlers, data fetching, permissions, and side effects.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

That separation matters because a model, remote service, user, or compromised upstream system can return values that are malformed, misleading, or deliberately hostile. A syntactically valid payload can still contain a phishing URL, an inaccessible control, an oversized tree, or a button that appears to grant an operation the caller is not allowed to perform. Schema validation is the first boundary; it is not a complete security or accessibility proof.

#1 Best Overall
Sale
Compressed Air Duster,130000RPM Super Power Cordless Air Duster,Rechargeable Brushless Blower,3 Gear Adjustable Blower with LED Light,Dust Remover for Computer/House/Outdoor/Car
  • Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
  • With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
  • Wide Application: attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
  • Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
  • Economical &Reusable: Built durable materials with a long-lasting battery,our CAGIWIRU air duster it's a sustainable alternative to disposable air cans.

Use a contract that describes the exact object your client accepts. The OpenAI plugin reference describes output schemas as a way to specify the precise object returned so clients can validate it: OpenAI Plugins reference. The registry and policy decisions below are practical implementation guidance built around that contract.

Design a narrow, versioned component contract

Choose a small vocabulary

Start with the components your product genuinely needs. For example, an initial registry might contain text, heading, stack, card, link, and button. Each identifier maps to an implementation that is shipped with your application. Do not let generated data name an arbitrary JavaScript module, React component, event handler, or import path.

Keep the top-level shape explicit. A useful envelope includes a schema version, a root node, and optional metadata that has no authority over security decisions:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
{
  "version": 1,
  "root": {
    "type": "card",
    "props": {
      "title": "Release notes",
      "body": "Read the latest changes.",
      "href": "/docs/releases"
    },
    "children": []
  }
}

Every field should have a defined type, required/optional status, maximum size, and allowed values. If a property is not part of the contract, reject it or remove it during normalization rather than passing it through “just in case.” Unknown fields often become accidental future attack surfaces.

Version the schema deliberately

Include a numeric or string version and validate it before traversing the tree. A new version can add a component or change a property without silently changing the meaning of old payloads. Support only versions that the deployed client understands; return a controlled “unsupported UI version” state for everything else.

Separate content from behavior

Generated text can populate a label or description, but it must not become executable code. Represent actions as identifiers such as save_draft or open_help from a fixed action catalog. The identifier is a request for your application to consider; it is never an authorization grant. Do not accept generated JavaScript, callback names, SQL, shell commands, or module paths as component properties.

Use explicit constraints

Constraints should cover nesting, collection sizes, string lengths, numeric ranges, and enum values. The following limits are illustrative policy choices, not limits mandated by a platform:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Allow only registered component types.
  • Set a maximum tree depth and maximum node count appropriate to the device and screen.
  • Cap text length, list items, and option counts to prevent denial-of-service behavior and unusable layouts.
  • Permit only documented prop names and reject values with the wrong type.
  • Require unique keys or stable IDs where your rendering framework needs them.
  • Reject cyclic references, even if the input format could represent them.

Fail closed when a structural check cannot be completed. A safe fallback can explain that the content could not be displayed and offer a normal, trusted navigation path.

Rank #2
EVEO® Screen Cleaner Spray Kit (Streak-Free) TV Screen Cleaner for Smart TV, Lcd, LEd, Oled | Computer Screen Cleaner Spray and Wipe Microfiber Cloth - TV, Monitor, Laptop, iPad, Car - 6.7oz 1 Pack
  • Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
  • Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
  • Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
  • Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
  • Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth

Validate before any component is rendered

Validation should happen on the serialized payload before it reaches JSX, templates, DOM APIs, or an action dispatcher. A robust pipeline is:

  1. Receive data, not source. Accept JSON or another data format. Never evaluate generated JavaScript and never compile a generated template as part of rendering.
  2. Parse safely. Handle malformed serialization, unexpected encodings, and excessively large input without crashing the host.
  3. Validate the envelope. Check the version, root presence, and exact top-level keys.
  4. Walk the tree. At every node, verify the type, allowed props, child rules, depth, and cumulative size.
  5. Normalize. Convert accepted values to the canonical representation your components expect. Do not “repair” dangerous values by guessing their intent.
  6. Apply independent trust checks. Validate URL properties, action identifiers, and any resource references with their own policies.
  7. Render only the accepted result. Pass the normalized object to a fixed registry. Invalid input goes to a fallback or an error state.

Validation libraries can reduce boilerplate, but the important property is the contract and the rejection behavior. Unit-test both valid examples and adversarial payloads: unknown types, extra props, deeply nested nodes, huge strings, invalid Unicode, duplicate IDs, malformed URLs, and action names outside the catalog.

An illustrative TypeScript shape

type UiNode =
  | { type: 'text'; props: { value: string } }
  | { type: 'heading'; props: { level: 1 | 2 | 3; value: string } }
  | { type: 'link'; props: { label: string; href: string } }
  | { type: 'button'; props: { label: string; action: 'save_draft' | 'open_help' } }
  | { type: 'stack'; props: { direction: 'row' | 'column' }; children: UiNode[] }
  | { type: 'card'; props: { title: string; body?: string; href?: string }; children?: UiNode[] };

The type definition helps your implementation, but runtime validation is still required because data arriving over a network is not made trustworthy by a compile-time type.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Map accepted IDs to trusted components

Use an allowlisted registry rather than dynamic lookup. The registry is the point where untrusted data becomes a choice among code paths you have reviewed:

const registry = {
  text: TextView,
  heading: HeadingView,
  link: LinkView,
  button: ActionButton,
  stack: StackView,
  card: CardView
} as const;

function RenderNode({ node }: { node: UiNode }) {
  const Component = registry[node.type];
  if (!Component) return <SafeFallback reason='unsupported component' />;
  return <Component {...node.props} children={node.children} />;
}

In production, the validator should guarantee that node.type is a key in the registry before this function runs. Keep the registry static or explicitly configured by trusted application code. Never do the equivalent of import(node.type), call a generated function name, or spread an unvalidated object into a component that has security-sensitive props.

Normalize props before they reach the component. For example, convert a validated heading level to one of three known values, trim a label only according to your content policy, and remove fields that are not accepted by that component. Components should also use narrow prop types so a value intended for one context cannot accidentally reach another.

Render values through the framework, not HTML strings

React’s normal rendering treats a string as text. Preserve that behavior by passing generated strings as ordinary values or as children. Do not concatenate generated content into an HTML string and send it to dangerouslySetInnerHTML. React’s documentation warns: “This is dangerous. Unless the markup is coming from a completely trusted source, it is trivial to introduce an XSS vulnerability.” See React common components documentation.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For example, this is the safe pattern for a generated message:

Rank #3
Sale
BladeHawks RGB Gaming Mouse Pad Extra Large Extended 31.5x12 Inch-Black | LED mouse pad with 14 lighting modes, covers keyboard & mouse, anti-slip rubber base, waterproof surface, USB powered
  • 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
  • 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
  • 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
  • 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
  • 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.
function Message({ value }: { value: string }) {
  return <p>{value}</p>;
}

It is not safe to interpolate the same value into a markup string:

// Do not do this with generated or user-controlled content
const html = '<p>' + value + '</p>';
return <div dangerouslySetInnerHTML={{ __html: html }} />;

When rich text is a real requirement

First ask whether a small structured format can meet the need: paragraphs, emphasis, links, and lists can each be represented as validated nodes. If arbitrary rich HTML is unavoidable, put the sink in one narrowly reviewed component and sanitize with a maintained, allowlist-based sanitizer. Allow only the elements and attributes your product needs, remove event-handler attributes, and apply URL checks to link and resource attributes as well. Sanitization is not a substitute for schema validation; it is an additional boundary for the one place where HTML is accepted.

Do not assume that escaping text makes every prop safe. Raw HTML sinks and URL-valued attributes have different failure modes and require separate controls, as summarized in the React web security guidance.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Treat URLs as an independent trust boundary

A URL can be structurally valid and still be dangerous. Validate every generated value before using it in href, src, navigation, redirects, or a resource prop.

  • Parse the value with a standards-compliant URL implementation.
  • Allow only schemes required by the specific component. For ordinary links, that usually means approved https destinations and controlled relative paths; add mailto or another scheme only when the feature needs it.
  • Explicitly reject javascript: and be cautious with data:, which can carry executable or unexpectedly large content.
  • Where possible, prefer same-site relative paths such as /docs/releases.
  • Use a host allowlist for external links or resource loads when the product has a known set of destinations.
  • Fail closed: replace an invalid URL with a non-link state or a safe, trusted destination.

The security guidance linked above recommends scheme and host constraints and specifically calls out blocking risky schemes. Apply the policy per context: an image source, navigation link, download, and iframe have different acceptable destinations. Do not validate once and reuse the result in a more privileged context.

function safeHref(raw: string, origin: string): string | null {
  try {
    const url = new URL(raw, origin);
    if (url.protocol !== 'https:' && url.protocol !== 'http:') return null;
    if (url.origin !== origin) return null; // change only with an explicit host allowlist
    return url.pathname + url.search + url.hash;
  } catch {
    return null;
  }
}

The example intentionally allows only same-origin HTTP(S) URLs. If your application must support external destinations, replace the same-origin check with a documented allowlist and test the parser against mixed-case schemes, encoded characters, credentials, unusual ports, and redirect behavior.

Keep authorization and sensitive actions out of presentation

A generated button that says “Delete account” does not prove that deletion is allowed, and hiding a button does not revoke permission. Enforce authorization in the server-side handler, API, or tool implementation that performs the operation. Recheck the caller, resource, and current state when the action is invoked.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Expose only fixed action identifiers to the UI. The button component can dispatch save_draft, but the server must decide whether the user may save that draft and which record is affected. Never let generated props select an endpoint, supply an unvalidated object ID to a privileged operation, or bypass confirmation and audit requirements.

Rank #4
Sale
Vaydeer Wrist Rest for Keyboard and Mouse, Computer Ergonomic Wrist Support Pad, Soft Memory Foam Arm Cushion for Desk, Palm Hand Office Laptop Typing
  • 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
  • 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
  • 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
  • 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
  • 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.

This separation also improves portability. OpenAI’s MCP Apps guidance says the underlying tool workflow should remain useful even when a host does not render the custom UI. Read Add UI to your MCP server for the platform-specific integration model. A text or structured response should still communicate the result, while the UI remains an optional presentation layer.

Handle invalid, excessive, or unavailable UI gracefully

Generated content will sometimes be incomplete or unavailable. Decide the behavior before shipping:

  • Malformed payload: show a stable error state and log a redacted validation reason.
  • Unsupported version or component: show a fallback representation rather than attempting a best-effort import.
  • Invalid URL: render the label as text or omit the link.
  • Unknown action: disable the control and provide an explanation that does not expose internal details.
  • Too many nodes or excessive text: stop traversal and offer a bounded fallback.
  • Host lacks the custom renderer: return the tool’s normal structured or textual result.
  • Network or resource failure: preserve the surrounding page and provide retry or alternate navigation.

Log enough information to diagnose the producer and schema version, but avoid storing secrets, access tokens, or unredacted personal content. Metrics can count validation failures by reason and version without turning the log into a copy of user input.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Assess the rendered result, not just the JSON

A payload can pass validation and still produce a broken interface. Acceptance testing must inspect the actual DOM and interaction behavior at the viewport sizes your product supports.

Layout and responsive behavior

Check mobile and desktop widths, long translations, large text settings, narrow containers, and zoom. Look for overflow, clipped content, overlapping controls, unstable fixed-format elements, and focus indicators that disappear. OpenAI’s UI guidance recommends content that fits on mobile and desktop and avoids overlap; see UI guidelines and the frontend prompt instructions. Those documents provide practical design guidance, not a guarantee that following it alone establishes accessibility conformance.

Keyboard and assistive technology

Every interactive element must be reachable and operable with a keyboard, with a visible focus state and a logical order. Use semantic buttons for actions and links for navigation. Give controls meaningful accessible names, associate errors and descriptions with their fields, and expose state such as expanded, selected, or busy when it changes. React supports aria-* attributes as accessibility-tree information; the correct semantic element, name, state, and interaction pattern still depend on your implementation. The relevant React documentation is here.

Test generated combinations, not only hand-authored examples. A heading without a following region, a button whose label is only an icon, or a dialog with no focus management can all arise from otherwise valid data. Include screen-reader checks and keyboard-only passes in the acceptance criteria.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Content and visual safety

Review whether generated labels make truthful claims, whether links identify their destination, and whether warnings or destructive actions are unmistakable. Schema validation cannot establish that content is accurate or semantically appropriate; moderation, business rules, and human review may be needed for high-impact interfaces.

Best Value
Sale
Under Desk Cable Management Tray No Drill, Metal Mesh Cable Management Under Desk with Clamp Mount, 2 Hole Cable Tray with Wire Management and Cord Organizer for Home Office Standing Desk
  • 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
  • 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
  • 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
  • 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
  • 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.

MCP Apps integration: keep platform contracts separate

For a ChatGPT-compatible MCP Apps integration, associate the tool with its UI resource through the _meta.ui.resourceUri metadata field and use the shared bridge where the host provides one. The exact resource, isolation, and bridge behavior is platform-specific; consult the current MCP UI guide and plugin reference for the host contract.

Do not confuse that metadata association with permission to perform an action. The tool remains the authoritative place for validation, authorization, and side effects. Design a useful non-UI response so another host, an older client, or a blocked renderer can still complete the workflow. Other hosts may define different resource and bridge contracts, so keep the renderer’s security assumptions local to each integration.

Implementation choices compared

Decision axis Preferred approach Riskier alternative What to verify
Representation Structured data rendered by trusted components Generated HTML inserted into the DOM No raw markup sink receives untrusted content
Schema handling Versioned, strict validation with rejection Permissive pass-through and silent coercion Unknown types, props, depth, and sizes fail predictably
Component selection Static registry of reviewed implementations Dynamic imports or generated function names Data cannot choose executable code
URL policy Context-specific scheme and host allowlists Arbitrary destinations from generated strings javascript:, risky data:, and unapproved hosts are rejected
Permissions Server-side authorization on every action Hidden or disabled controls treated as security Direct API calls receive the same authorization checks
Host behavior UI enhances a useful underlying tool response Workflow works only in one custom renderer Fallback host can still complete or understand the operation
Quality assurance Measured viewport, keyboard, and screen-reader behavior Schema-only or screenshot-only review Rendered combinations remain usable and accessible

A practical test and release checklist

  1. Document the schema, version policy, component registry, action catalog, and URL rules.
  2. Test parser failures, unknown fields, invalid enums, huge values, deep nesting, duplicate IDs, and malformed encodings.
  3. Prove that strings render as text and that the application has no uncontrolled HTML injection path.
  4. Exercise every URL-valued prop with relative paths, approved hosts, unapproved hosts, alternate casing, credentials, ports, and dangerous schemes.
  5. Invoke actions directly through the API as well as through the UI to verify server-side authorization.
  6. Run generated examples at mobile and desktop widths, with zoom and large text, and inspect overflow and overlap.
  7. Complete keyboard-only and screen-reader passes, including focus movement, names, descriptions, errors, and state changes.
  8. Verify the safe fallback for each rejection class and make sure it does not leak internal validation details.
  9. For MCP deployments, test a host that renders the UI and one that uses only the underlying tool response.
  10. Review logs and telemetry for sensitive-data leakage before enabling broad rollout.

Common mistakes and their fixes

“The schema passed, so the UI is safe.”

Shape validation says that the data matches your contract. It does not prove that a URL is acceptable, that content is truthful, that a user is authorized, or that the resulting controls are accessible. Add the URL, authorization, content, and rendered-behavior checks described above.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“React escapes everything.”

Ordinary text rendering is safer, but raw HTML sinks and URL-valued attributes still need controls. Avoid dangerouslySetInnerHTML for generated content and apply a separate URL policy.

“We can hide a dangerous button.”

Presentation is not authorization. Enforce permission in the operation that changes data, and assume a caller can invoke that operation without your UI.

“Unknown components can fall back to a dynamic import.”

That turns data into code selection. Keep the registry explicit and return a fallback for an unsupported component or schema version.

“Accessibility can be fixed after launch.”

Generated combinations multiply the ways a layout or name can fail. Make viewport, keyboard, and assistive-technology behavior part of acceptance before the payload is considered renderable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.