-
-
Notifications
You must be signed in to change notification settings - Fork 689
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
feat: generalize response data injection #3188
base: main
Are you sure you want to change the base?
feat: generalize response data injection #3188
Conversation
Can you say more about the problem you're trying to solve, here? There are some very significant drawbacks to making a breaking change to every application simply to add more verbosity for 99% of users, so I am wondering if there is another way to solve this than adding the generics you've added. |
Basically, I want to inject a single <style> (extracted critical CSS) block to head, where contents of this style block are being populated on the fly, by include_sass! macro. #[component]
fn PermissionConfirmation(
callback: ChallengeCallback,
app_name: String,
new_permissions: Vec<DisplayPermission>,
kept_permissions: Vec<DisplayPermission>,
) -> impl IntoView {
include_sass!(css_module, "permissions.scss");
let callback = {
move |_: MouseEvent| {
callback.run((
control::serialize(&PermissionsConfirmationResponse { confirmed: true }),
None,
))
}
};
h!(div[[
CssModule > { css_module },
h1 > { app_name },
table.permissions[[for permission in new_permissions {
tr.permission[[
td.icon[[img(src = permission.icon.clone())]],
td.name[[{ permission.name.clone() }]],
td.description[[{ permission.description.clone() }]],
]]
}]],
table.permissions[[for permission in kept_permissions {
tr.permission[[
td.icon[[img(src = permission.icon.clone())]],
td.name[[{ permission.name.clone() }]],
td.description[[{ permission.description.clone() }]],
]]
}]],
ul.login_btn[[
li[[button(onclick = callback) > "Confirm"]],
li[[button > "Cancel (Or close page)"]],
]],
]])
} (Don't mind the custom view macro, it is required for the proper css module scoping) let cl_login_btn = "mangled-class-name";
...
let css_module = DataForCssModule {...}; local variables, and the custom view macro uses them But it also requires an additional CssModule component present, which handles the lifecycle of <Style> component children. (Which is pretty complicated, because if the same style file is imported multiple times - only one Style component should be present) I have tried to reimplement this with direct usage of MetaContext/ServerMetaContext inside of the hook, but the lifecycle is still not great, and there is no way with the current ServerMetaContext api to be able to merge multiple added style tags into one. // expansion of use_sass!
let cl_login_btn = "mangled-class-name";
...
use_css_module(DataForCssModule {...});
#[component]
fn PermissionConfirmation(
callback: ChallengeCallback,
app_name: String,
new_permissions: Vec<DisplayPermission>,
kept_permissions: Vec<DisplayPermission>,
) -> impl IntoView {
include_sass!("permissions.scss");
...
h!(div[[
...
ul.login_btn[[
li[[button(onclick = callback) > "Confirm"]],
li[[button > "Cancel (Or close page)"]],
]],
]])
} To bypass the limitations of ServerMetaContext api, without the need to implement css modules building blocks in leptos itself, I have decided to implement my own response head injector, like leptos_meta does. And to do that - I need some way to make axum integration to use this response injector, where it already has hardcoded integration for leptos_meta. I agree that the current approach with ServerExtension generic parameter is not great, but I haven't found a prettier way with the current leptos SSR API. I will re-implement this PR, if someone proposes a better API. |
The problem here is not that
It's definitely possible. When I call it a "breaking change" I don't mean "it's a breaking change according to semver" I mean "it breaks users' applications" — see the fact that every example fails CI without modification. I do not plan to make this change, whether it is allowed by semver or not.
Fair enough! Is there a way we can adjust the What additional functionality do you need to support what you're trying to do? Are there one or two functions that could be added to enable it? |
The problem is, it is not easy to implement SSR without those helpers, => it is not easy to implement functionality like leptos_meta by yourself.
I agree that the current approach is bad, but it might be improved.
It might be solved by adding a couple of functions in public api, but there is no way to make this api look good, and be usable for everyone. My implementation only needs to
|
@CertainLach I found a way to solve this problem without modifying leptos. Refer to the |
I have a leptos styled components library, which is using leptos_meta for SSR for a long time.
However, I had some problems with this flow, that are probably solvable by extension of leptos_meta public API, but I decided to generalize leptos_meta server integration instead, now any other library may hook into response data generation.
This PR only implements axum integration, because I'm not sure if there is a better way to implement this feature.