Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Public leptos_meta::register function #3230

Open
luoxiaozero opened this issue Nov 11, 2024 · 1 comment
Open

Public leptos_meta::register function #3230

luoxiaozero opened this issue Nov 11, 2024 · 1 comment

Comments

@luoxiaozero
Copy link
Contributor

Is your feature request related to a problem? Please describe.

Currently I inject css into head via Style in SSR mode, and control css via custom logic in Hydrate mode.

fn mount_style(id: &str, content: &'static str) {
    if #[cfg(feature = "ssr")] {
        let _ = view! {
            <Style id=id>
                {content}
            </Style>
        };
    } else {
        let head = document().head().expect("head no exist");
        let style = head
            .query_selector(&format!("style#{id}"))
            .expect("query style element error");
        if style.is_some() {
            return;
        }
        let style = document()
            .create_element("style")
            .expect("create style element error");
        _ = style.set_attribute("id", &id);
        style.set_text_content(Some(content));
        _ = head.prepend_with_node_1(&style);
    }
}

When I hydrate via the following code, <Style>". b {}"</Style> gets hydrated to the <style>". a{}"</style> element instead of the <style>". b{}"</style> element.

#[component]
pub fn Button() -> impl IntoView {
    mount_style("button", ".a {}");
    view! {
        <Style>
             ".b {}"
         </Style>
    }
}

Describe the solution you'd like

Public leptos_meta::register function. Allows passing a second parameter to control the position of the generated HTML string to avoid hydration.

pub fn register<E, At, Ch>(
    el: HtmlElement<E, At, Ch>,
    config: RegisterConfig,
) -> RegisteredMetaTag<E, At, Ch>

pub struct RegisterConfig {
    position: ElementPosition
}

pub enum ElementPosition {
    // Before the <!--HEAD--> comment.
    MarkerBefore,
    // After the <!--HEAD--> comment.
    MarkerAfter,
}

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context

RegisterConfig is a struct in order to expand more fields in the future to achieve the same functions as unhead.

@gbj
Copy link
Collaborator

gbj commented Nov 11, 2024

It seems like there are multiple people interested in having the ability to inject things into the <head> where leptos_meta does it, while also modifying the behavior of the relevant components pretty signficantly. (See #2856, #3188) It would be helpful to unite these different ideas into one set of extensions to leptos_meta.

I think at least #2856 and this seem to result from the fact that the pre-0.7 leptos_meta components have side effects — simply creating a <Style>, without every using it in the view that is returned, injects something into the <head>. It seems like your implementation above relies on this behavior. (i.e., mount_style does not return a view that should be rendered, but () — it is purely side effects)

I don't think I fully understand either the use case for what you're trying to do, or what you're asking for, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants