use crate::context::ClerkContext;
use crate::core::{AuthRuntimeState, ClerkError};
use crate::options::ClerkOptions;
use crate::ssr::INITIAL_STATE_SCRIPT_ID;
use dioxus::prelude::*;
#[component]
pub fn ClerkProvider(
#[props(into)]
publishable_key: Option<String>,
#[props(into)]
sign_in_url: Option<String>,
#[props(into)]
sign_up_url: Option<String>,
#[props(into)]
sign_in_fallback_redirect_url: Option<String>,
#[props(into)]
sign_in_force_redirect_url: Option<String>,
#[props(into)]
sign_up_fallback_redirect_url: Option<String>,
#[props(into)]
sign_up_force_redirect_url: Option<String>,
#[props(into)]
after_sign_out_url: Option<String>,
#[props(into)]
after_multi_session_single_sign_out_url: Option<String>,
#[props(into)]
after_switch_session_url: Option<String>,
#[props(into)]
waitlist_url: Option<String>,
#[props(into)]
user_profile_url: Option<String>,
#[props(into)]
organization_profile_url: Option<String>,
#[props(into)]
create_organization_url: Option<String>,
#[props(into)]
proxy_url: Option<String>,
#[props(into)]
domain: Option<String>,
is_satellite: Option<bool>,
satellite_auto_sync: Option<bool>,
prefetch_ui: Option<bool>,
allowed_redirect_origins: Option<Vec<String>>,
allowed_redirect_protocols: Option<Vec<String>>,
appearance: Option<serde_json::Value>,
localization: Option<serde_json::Value>,
#[props(default = ClerkOptions::from_value(serde_json::Value::Null), into)]
options: ClerkOptions,
#[props(into)]
script_nonce: Option<String>,
#[props(into)]
clerk_js_url: Option<String>,
#[props(into)]
clerk_ui_url: Option<String>,
#[props(default = true)]
load_clerk_js: bool,
#[props(into)]
router_push: Option<Callback<String>>,
#[props(into)]
router_replace: Option<Callback<String>>,
children: Element,
) -> Element {
let options = options
.maybe_sign_in_url(sign_in_url)
.maybe_sign_up_url(sign_up_url)
.maybe_sign_in_fallback_redirect_url(sign_in_fallback_redirect_url)
.maybe_sign_in_force_redirect_url(sign_in_force_redirect_url)
.maybe_sign_up_fallback_redirect_url(sign_up_fallback_redirect_url)
.maybe_sign_up_force_redirect_url(sign_up_force_redirect_url)
.maybe_after_sign_out_url(after_sign_out_url)
.maybe_after_multi_session_single_sign_out_url(after_multi_session_single_sign_out_url)
.maybe_after_switch_session_url(after_switch_session_url)
.maybe_waitlist_url(waitlist_url)
.maybe_user_profile_url(user_profile_url)
.maybe_organization_profile_url(organization_profile_url)
.maybe_create_organization_url(create_organization_url)
.maybe_proxy_url(proxy_url)
.maybe_domain(domain)
.maybe_is_satellite(is_satellite)
.maybe_satellite_auto_sync(satellite_auto_sync)
.maybe_prefetch_ui(prefetch_ui)
.maybe_allowed_redirect_origins(allowed_redirect_origins)
.maybe_allowed_redirect_protocols(allowed_redirect_protocols)
.maybe_appearance(appearance)
.maybe_localization(localization)
.into_value();
let startup = use_hook({
let publishable_key = publishable_key.clone();
move || std::rc::Rc::new(crate::startup::provider_startup(publishable_key))
});
let initial_state_json = startup.initial_state_json.clone();
let auth = use_signal({
let initial_auth = startup.auth.clone();
move || initial_auth.clone()
});
let load_error = use_signal(|| None);
let action_error = use_signal({
let warning = startup.warning.clone();
move || warning.clone()
});
let pending = use_signal(Vec::new);
#[cfg(clerk_client)]
crate::lifecycle::use_drive_lifecycle(
crate::lifecycle::ClerkLifecycleSignals { auth, load_error },
startup.publishable_key.clone(),
crate::lifecycle::ClerkLoadOptions {
value: options.clone(),
router_push,
router_replace,
},
crate::lifecycle::ClerkScriptOptions {
load_clerk_js,
script: crate::loader::ScriptOptions {
url: clerk_js_url,
ui_url: clerk_ui_url,
nonce: script_nonce,
},
},
);
#[cfg(not(clerk_client))]
let _ = &options;
#[cfg(not(clerk_client))]
let _ = (
&script_nonce,
&clerk_js_url,
&clerk_ui_url,
load_clerk_js,
&router_push,
&router_replace,
);
rsx! {
if let Some(json) = initial_state_json {
script {
id: INITIAL_STATE_SCRIPT_ID,
r#type: "application/json",
dangerous_inner_html: "{json}",
}
}
ClerkContextProvider { auth, load_error, action_error, pending, children }
}
}
#[component]
fn ClerkContextProvider(
auth: Signal<AuthRuntimeState>,
load_error: Signal<Option<ClerkError>>,
action_error: Signal<Option<ClerkError>>,
pending: Signal<Vec<crate::actions::ClerkOperation>>,
children: Element,
) -> Element {
let ctx = use_context_provider(|| ClerkContext {
auth,
load_error,
action_error,
pending,
});
#[cfg(clerk_client)]
crate::actions::use_action_scheduler(ctx);
#[cfg(not(clerk_client))]
let _ = ctx;
rsx! { {children} }
}