diff --git a/leptos/src/lib.rs b/leptos/src/lib.rs
index ac4a6b8ac2..02d98908b7 100644
--- a/leptos/src/lib.rs
+++ b/leptos/src/lib.rs
@@ -192,9 +192,11 @@ mod error_boundary;
pub use error_boundary::*;
mod animated_show;
mod for_loop;
+mod provider;
mod show;
pub use animated_show::*;
pub use for_loop::*;
+pub use provider::*;
#[cfg(feature = "experimental-islands")]
pub use serde;
#[cfg(feature = "experimental-islands")]
diff --git a/leptos/src/provider.rs b/leptos/src/provider.rs
new file mode 100644
index 0000000000..39dff0756f
--- /dev/null
+++ b/leptos/src/provider.rs
@@ -0,0 +1,40 @@
+use leptos::*;
+
+#[component]
+/// Uses the context API to [`provide_context`] to its children and descendants,
+/// without overwriting any contexts of the same type in its own reactive scope.
+///
+/// This prevents issues related to “context shadowing.”
+///
+/// ```rust
+/// # use leptos::*;
+/// #[component]
+/// pub fn App() -> impl IntoView {
+/// // each Provider will only provide the value to its children
+/// view! {
+///
+/// // correctly gets 1 from context
+/// {use_context::().unwrap_or(0)}
+///
+///
+/// // correctly gets 2 from context
+/// {use_context::().unwrap_or(0)}
+///
+/// // does not find any u8 in context
+/// {use_context::().unwrap_or(0)}
+/// }
+/// }
+/// ```
+pub fn Provider(
+ /// The value to be provided via context.
+ value: T,
+ children: Children,
+) -> impl IntoView
+where
+ T: Clone + 'static,
+{
+ run_as_child(move || {
+ provide_context(value);
+ children()
+ })
+}
diff --git a/leptos_reactive/src/context.rs b/leptos_reactive/src/context.rs
index 266df64b7a..5037fc2539 100644
--- a/leptos_reactive/src/context.rs
+++ b/leptos_reactive/src/context.rs
@@ -84,7 +84,29 @@ use std::any::{Any, TypeId};
/// that was provided in ``, meaning that the second `` receives the context
/// from its sibling instead.
///
-/// This can be solved by introducing some additional reactivity. In this case, it’s simplest
+/// ### Solution
+///
+/// If you are using the full Leptos framework, you can use the [`Provider`](leptos::Provider)
+/// component to solve this issue.
+///
+/// ```rust
+/// # use leptos::*;
+/// #[component]
+/// fn Child() -> impl IntoView {
+/// let context = expect_context::<&'static str>();
+/// // creates a new reactive node, which means the context will
+/// // only be provided to its children, not modified in the parent
+/// view! {
+///
+///
{format!("child (context: {context})")}
+///
+/// }
+/// }
+/// ```
+///
+/// ### Alternate Solution
+///
+/// This can also be solved by introducing some additional reactivity. In this case, it’s simplest
/// to simply make the body of `` a function, which means it will be wrapped in a
/// new reactive node when rendered:
/// ```rust