-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
Clear and concise description of the problem
Hi 👋
I use Vue with Inertia, so the root template is rendered in PHP.
Here is the template:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <!-- Not reactive, comes from PHP -->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title inertia>{{ config('app.name', 'Laravel') }}</title>
@routes
@vite(['resources/js/app.ts', "resources/js/pages/{$page['component']}.vue"])
@inertiaHead
</head>
<body class="font-sans antialiased">
@inertia
</body>
</html>
Sometime, from the Vue app, I need to change some attributes on the <html>
or <body>
tag from the Vue.js.
For exemple, changing a theme class or attribute (data-theme), changing the lang attribute without doing a hard reload.
Currently, the best way would be to use a watch()
and document.documentElement.dataset.theme = myRef
, which is a bit ugly and verbose.
Suggested solution
It would be nice to have a VueUse composable for this.
Something like this:
useElementAttrs('html', {
lang: i18n.locale
});
Another example:
useElementAttrs('body', {
'data-theme': $page.props.theme
});
The first argument is a DOM selector, the second arguments are attrs to reactively sync with the element.
Maybe we could have a 3rd option argument with merging strategy (replace (default), concat/append) if the attrs already exist on the element.
To prevent misuse, maybe we should detect if the element is inside the Vue app, where we would show an error/warning so as to make to composable only usable with DOM nodes outside the Vue app.
Alternative
No response
Additional context
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.