-
Notifications
You must be signed in to change notification settings - Fork 164
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
Flow page title is not propagated to the top part of the app layout in a Hilla main layout #19200
Comments
I propose to retest this issue after we implement #19127. |
The menu title does not necessarily have anything to do with the page title, especially in the case of The view title needs to be propagated to the Furthermore, the page title should be updated even if the application doesn't use the automatic main menu feature at all but instead defines the menu manually. |
This is implemented in the layout component as I think for Hilla the generated |
The metadata is known at compile time for Hilla views but it's only known after a round trip for Flow views. (Though there's also the question on how to implement dynamic page titles for Hilla views...) |
Browser knows already the correct title but only via So using import { useSignal } from '@vaadin/hilla-react-signals';
...
export default function MainLayout() {
...
useEffect(() => {
document.title = currentTitle;
}, [currentTitle]);
const documentTitle = useSignal(currentTitle);
new MutationObserver((mutations: MutationRecord[]) => {
documentTitle.value = mutations[0].target.textContent || '';
}).observe(
document.querySelector('title') as Node,
{ subtree: true, characterData: true, childList: true }
);
...
<h2 slot="navbar" className="text-l m-0">
{documentTitle}
</h2>
... |
That sounds like a hack even though it would in one way also solve the related problem of how Hilla views would update the title shown in the layout in case the view is dynamically updating the client. One approach that I was thinking of would be that Vaadin defines a signal where the title is stored. The layout can then import and render it and any logic that wants to update the title can import as set it. One such party would be the logic in Flow that currently updates |
Setting signal e.g to So code in import { useSignal } from '@vaadin/hilla-react-signals';
...
export default function MainLayout() {
...
useEffect(() => {
document.title = currentTitle;
documentTitle.value = currentTitle;
}, [currentTitle]);
const documentTitle = useSignal(currentTitle);
// @ts-ignore
window.Vaadin.documentTitleSignal = documentTitle;
...
<h2 slot="navbar" className="text-l m-0">
{documentTitle}
</h2>
...
And in Flow's JavaScriptInvocation invocation = new JavaScriptInvocation(
"document.title = $0; if(window?.Vaadin?.documentTitleSignal) { window.Vaadin.documentTitleSignal.value = $0; }",
title); |
I would rather implement the main layout in a slightly different way that should be basically equivalent from a functional point of view but might be easier to understand.
It can then directly assign the signal in the render function: |
import { Signal, useSignal } from '@vaadin/hilla-react-signals'; const vaadin = window.Vaadin as {
documentTitleSignal: Signal<string>;
};
export default function MainLayout() {
...
vaadin.documentTitleSignal = useSignal("");
useEffect(() => {
vaadin.documentTitleSignal.value = currentTitle;
document.title = vaadin.documentTitleSignal.value;
}, [currentTitle]); <h2 slot="navbar" className="text-l m-0">
{vaadin.documentTitleSignal}
</h2> I think that we can add PR in flow that sets |
`UIInternals#setTitle(String)` sets page title via JavaScript to `document.title` and optionally `window.Vaadin.documentTitleSignal.value` where documentTitleSignal is expected but not limited to be Signal<string> type with a value field. This allows Hilla main layout, when used, being kept in sync with the Flow page title even when set via PageTitle annotation or HasDynamicTitle interface. Fixes: #19200
That example might work in this particular case but it can be improved for clarity and to work as expected also in other cases. The first problem is that the signal instance is now owned by a The second problem is that With those two adjustments, we would have these lines of code before the render function: import { signal, effect } from '@vaadin/hilla-react-signals';
const vaadin = window.Vaadin as {
documentTitleSignal: Signal<string>;
};
vaadin.documentTitleSignal = signal("");
effect(() => document.title = vaadin.documentTitleSignal.value); With those changes, the React |
Starter's useEffect would still need to be changed to update the signal value with Also another thing to note with this new code is how the starter sets |
I don't think there's any reason to have For |
To summarize all so far, following import { createMenuItems, useViewConfig } from '@vaadin/hilla-file-router/runtime.js';
import { AppLayout, DrawerToggle, Icon, SideNav, SideNavItem } from '@vaadin/react-components';
import { Suspense } from 'react';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import { Signal, signal, effect } from '@vaadin/hilla-react-signals';
const vaadin = window.Vaadin as {
documentTitleSignal: Signal<string>;
};
vaadin.documentTitleSignal = signal("");
effect(() => document.title = vaadin.documentTitleSignal.value);
export default function MainLayout() {
const currentTitle = useViewConfig()?.title ?? "";
const navigate = useNavigate();
const location = useLocation();
vaadin.documentTitleSignal.value = currentTitle;
return (
<AppLayout primarySection="drawer">
<div slot="drawer" className="flex flex-col justify-between h-full p-m">
<header className="flex flex-col gap-m">
<h1 className="text-l m-0">My App</h1>
<SideNav onNavigate={({ path }) => navigate(path!)} location={location}>
{createMenuItems().map(({ to, title, icon }) => (
<SideNavItem path={to} key={to}>
{icon ? <Icon src={icon} slot="prefix"></Icon> : <></>}
{title}
</SideNavItem>
))}
</SideNav>
</header>
</div>
<DrawerToggle slot="navbar" aria-label="Menu toggle"></DrawerToggle>
<h2 slot="navbar" className="text-l m-0">
{vaadin.documentTitleSignal}
</h2>
<Suspense>
<Outlet />
</Suspense>
</AppLayout>
);
} |
I'm wondering if that could create some kind of unexpected side effect / bug for people that use the "oldish" pattern to change the page title to e.g. add (number of notifications) in front of the title.. this shouldn't probably be added to the h2 of the main layout.. because Page::setTitle from flow delegates to the changed method that also updates the documentTitleSignal. |
All the actual logic for interpreting the value that Flow sets in the signal instance is in |
`UIInternals#setTitle(String)` sets page title via JavaScript to `document.title` and optionally `window.Vaadin.documentTitleSignal.value` where documentTitleSignal is expected but not limited to be Signal<string> type with a value field. This allows Hilla main layout, when used, being kept in sync with the Flow page title even when set via PageTitle annotation or HasDynamicTitle interface. Fixes: #19200 Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com>
`UIInternals#setTitle(String)` sets page title via JavaScript to `document.title` and optionally `window.Vaadin.documentTitleSignal.value` where documentTitleSignal is expected but not limited to be Signal<string> type with a value field. This allows Hilla main layout, when used, being kept in sync with the Flow page title even when set via PageTitle annotation or HasDynamicTitle interface. Fixes: #19200 Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com>
`UIInternals#setTitle(String)` sets page title via JavaScript to `document.title` and optionally `window.Vaadin.documentTitleSignal.value` where documentTitleSignal is expected but not limited to be Signal<string> type with a value field. This allows Hilla main layout, when used, being kept in sync with the Flow page title even when set via PageTitle annotation or HasDynamicTitle interface. Fixes: #19200 Co-authored-by: Tomi Virtanen <tltv@vaadin.com> Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com>
This ticket/PR has been released with Vaadin 24.4.0.beta3 and is also targeting the upcoming stable 24.4.0 version. |
I've updated the referenced skeleton starters. We need to document also the |
Uses signal for dynamically updated page title. Part of vaadin/flow#19200
* docs: document documentTitleSignal RelatedTo: vaadin/flow#19200 * First full pass at editing additions. * Second pass: edited full document. * Third pass: minor edits. --------- Co-authored-by: Russell J.T. Dyer <6652767+russelljtdyer@users.noreply.github.com>
Uses signal for dynamically updated page title. Part of vaadin/flow#19200
This ticket/PR has been released with Vaadin 24.5.0.alpha1 and is also targeting the upcoming stable 24.5.0 version. |
Description of the bug
When using a Hilla main menu from start.vaadin.com, the page title of a Flow view (set using
@PageTitle
orHasDynamicTitle
) is applied todocument.title
but the same value is not shown in the top area above the view (the<h2 slot="navbar">
element). Instead, the title in the navbar falls back to the application name. This is inconsistent with how it works for Hilla views in the same application and with how it works in an application with a main layout implemented in Flow.Even though this should probably be ultimately fixed in Hilla or Start, I'm filing it against Flow since I expect that some new feature will have to be added to Flow first and then only enabled through Hilla or Start.
Expected behavior
Expected that the Flow view title is shown in the same way as Hilla page titles.
Minimal reproducible example
mvn
Versions
The text was updated successfully, but these errors were encountered: