Blog
ENGINEERING

How to Use The Shadow Dom To Isolate Styles on a DOM That Isnt Yours

Riley Napier

August 18, 2020

Shadow Dom Header

Table of contents

Why does this happen?

Classic Solutions

Enter the __Shadow DOM!__

Shadow DOM with React

There have been many times in my career of building web apps and frontend experiences that I have needed to embed a widget in a DOM that I did not build or have access to. For example, embedding e-commerce widgets in a CMS or building chrome extensions to augment a given website. One of the biggest frustrations I've had is the style collision. In my development environment, all the widgets look great but the second I add the widget to a customer’s page… everything is broken!

Why does this happen?

The difficulty with embedding widgets in a DOM that you don't own, is that every DOM is going to reference different default fonts and colors.  It’s rather normal for a css stylesheet to look like:

Copied!

When I embed my widget into the body of this customer’s page, it will inherit the above styles.  While sometimes this is ok, many times it will break the beautiful widget I designed because I designed the widget with a different font-size or padding.

Classic Solutions

Historically we have had 2 solutions to this problem.

  • iFrame
  • Be crazy explicit with your styles

While both solutions can work, they both have rather frustrating aspects you will have to deal with.  Below we will go over a few examples of what I’ve done in the past and then talk about what this blog post is all about, the fancy new futuristic way to make composite user interfaces! The Shadow DOM!! <insert sinister laugh here>

Working with iFrames

With an IFrame, I have no control over the element’s size, so the consumer of my widget will have to accurately carve out space in their dom for my iFrame.  If my widget is dynamic in size, this is going to cause all sorts of problems with scrolling and positioning.

The second issue we find with iFrames, is the communication between the iFrame and the parent.  While I can now use CustomEvents, I will need to build out an event system for both the parent and the iFrame context.  This can be rather frustrating if the client already has a built in SDK.  It’s basically building a mini SDK for the SDK for IFrame communication.

And Finally, maybe the most simplistic issue, my consumer can’t tweak ANY of the styles in my iFrame.  This can lead to inconsistent user interfaces and just a bad experience all around.

iFrame meme

While iFrames will work, they are outdated, difficult to communicate with, and if your widget is dynamic in size, or you need any kind of customization, good luck.

CSS Specificity

The more common approach I have taken is to just be super specific with my CSS.  So namespace everything!!!  This can be tedious and will most likely need to be tweaked for each new client integrating your components. The QA process for pushing out an update to the widget is going to be difficult, too!  There are so many ways clients can use CSS and have it break your integration.

Broken CSS Meme

Ok, so if I don’t want to use an iFrame or be crazy explicit about my CSS, what can I do?

Enter the Shadow DOM!


Wow, that sounds spooky… What is the Shadow DOM you ask? It’s an API for DOM encapsulation and we all know how important encapsulation is.

Shadow DOM allows hidden DOM trees to be attached to elements in the regular DOM tree — this shadow DOM tree starts with a shadow root, underneath which can be attached to any elements you want, in the same way as the normal DOM. -Using Shadow DOM

The most basic approach to creating a shadow is to attach it to any dom element:

Copied!

The mode open or closed allows you to specify whether or not the page’s JavaScript can interact with the Shadow DOM.  Open meaning yes, it can interact and closed, it cannot.

After I’ve created my shadow element, I can append to it just like any normal DOM node.

Copied!

The above code will create a shadow node, append a node style to the Shadow DOM, and append a div saying Hello World. The style will now be isolated, only affecting the shadow tree and not contaminating the parent! Success!

Shadow Dom Success Meme

However, the above example is very verbose and simple and is showing us the bare metal implementation of the Shadow DOM.  It’s only scratching the surface of what the Shadow DOM can do.  It’s not all that complicated and it’s pretty well supported right now!

Shadow Dom Description Image

Shadow DOM with React

I’d like to take a quick moment to highlight a really useful package that I’ve used in the past and really gave me the feeling of “WOW, I might actually be able to use this in production”.

React Shadow makes working with the shadow dom with React easy as pie!  The example I used above with react-shadow will look like this

Copied!

Now if that isn’t magic, I don’t know what else is! So take a step with me into the future, let’s not be afraid of our Shadow DOM, and let’s make beautiful composite user experiences together!

Shadow Dom Magic Meme

Check out how we used our Shadow DOM to make a beautiful composite user experience. Sign up for Courier to explore our UI.

Similar resources

what is observability
GuideIntegrationsEngineering

Notification Observability: How to Monitor Delivery, Engagement, and Provider Health

Notification observability is the practice of monitoring notification delivery, engagement, and provider health using the same tools and discipline you apply to the rest of your application infrastructure. It means tracking whether messages are delivered, opened, and acted on across email, SMS, push, and in-app channels, then surfacing that data in dashboards alongside your other application metrics. Key metrics include delivery rate by channel, bounce and failure rates, provider latency, open rate trends, and click-through rates by template. Teams can build notification observability through DIY webhook handlers that pipe provider events to Datadog or Prometheus, log aggregation from application send logs, or notification platforms with built-in observability integrations. This matters most for multi-channel systems, business-critical notifications like password resets and payment confirmations, and teams using multiple providers with fallback routing.

By Kyle Seyler

January 15, 2026

sms opt out rules 2026
Notifications LandscapeEngineeringProduct Management

SMS Opt-Out Rules in 2026

TCPA consent rules changed in April 2025. Consumers can now revoke consent using any reasonable method, including keywords like "stop," "quit," "end," "revoke," "opt out," "cancel," or "unsubscribe." Businesses must honor opt-out requests within 10 business days, down from 30. The controversial "revoke all" provision, which would require opt-outs to apply across all automated messaging channels, has been delayed until January 2027 and may be eliminated entirely. SMS providers like Twilio handle delivery infrastructure and STOP keyword responses at the number level. They don't sync opt-outs to your email provider, push notification service, or in-app messaging. That cross-channel gap is your responsibility. Courier provides unified preference management that enforces user choices across SMS, email, push, and chat automatically.

By Kyle Seyler

January 13, 2026

top 8 transactional emails
EngineeringIntegrations

Top 8 Transactional Email Solutions for Developers in 2026

Transactional emails are the messages your users are waiting for: password resets, order confirmations, shipping updates, and two-factor codes. Unlike marketing emails, they're triggered by user actions and need to arrive fast. With Gmail, Yahoo, and Microsoft now enforcing strict authentication requirements (DMARC, SPF, DKIM), choosing the right transactional email provider matters more than ever. Non-compliant emails face permanent rejection. This guide compares 8 solutions for 2026: Courier for multi-channel orchestration across email, SMS, push, and Slack. SendGrid for scale and analytics. Postmark for speed (under 2 seconds average delivery). Resend for React/Next.js teams. Amazon SES for cost-conscious AWS shops. Plus Mailgun, Mailtrap, and SMTP2GO. We cover pricing, deliverability, developer experience, and when each provider makes sense. If you're building a product where notifications will eventually span multiple channels, start with Courier. If you genuinely only need email, we break down the tradeoffs.

By Kyle Seyler

January 12, 2026

Multichannel Notifications Platform for SaaS

Products

Platform

Integrations

Customers

Blog

API Status

Subprocessors


© 2026 Courier. All rights reserved.