Skip to content

Comments

feat: User profile + settings menu in top right (AppHeader) instead of top/bottom left (AppSidebar)#6793

Open
lehnerpat wants to merge 7 commits intomealie-recipes:mealie-nextfrom
lehnerpat:push-ptptozyppqyq
Open

feat: User profile + settings menu in top right (AppHeader) instead of top/bottom left (AppSidebar)#6793
lehnerpat wants to merge 7 commits intomealie-recipes:mealie-nextfrom
lehnerpat:push-ptptozyppqyq

Conversation

@lehnerpat
Copy link
Contributor

@lehnerpat lehnerpat commented Dec 30, 2025

What this PR does / why we need it:

(REQUIRED)

This PR consolidates the link to the current user's profile and the "settings" submenu into a single profile/account menu, represented by the user's avatar in the top right (i.e. at the end of the AppHeader).
This aligns Mealie's UI more with common conventions found in other apps that have user accounts (e.g. Github, Google, etc.).
This also prevents accidental logout, especially on mobile, where the logout button on the top right was easy to hit by mistake (and there was no confirmation dialog before logging out).

In more detail:

  • before this change, there was:
    • the user avatar shown at the top of the left sidebar (link to user profile page and to user favorite recipe's)
    • the settings submenu shown at the bottom of the left sidebar (introduced in feat: consolidate settings gui #6043)
    • a login/logout button shown at the right of the top bar (AppHeader)
  • after this change, all three of these are consolidated to a "user menu" at the top right (except for the link to favorite recipes, which is moved to the nav links in the left sidebar)
    • the menu is represented by the user's avatar and user name
    • when clicked, a submenu opens, showing:
      • a link to the profile page (previous on the left sidebar on the top)
      • all items from the "settings" submenu (previously in the left sidebar on the bottom), such as theme and language switching, admin settings, etc.
        • except for the "User Settings" menu, because this linked to the "user profile" page which is now at the top of this menu
      • a logout button (previously directly in the app bar)

Screenshots

Before After
(menu closed)
After
(menu open)
Desktop CleanShot 2026-01-05 at 13 56 11@2x CleanShot 2026-01-05 at 13 56 44@2x CleanShot 2026-01-05 at 13 56 52@2x
Mobile CleanShot 2026-01-05 at 13 58 02@2x CleanShot 2026-01-05 at 13 58 26@2x CleanShot 2026-01-05 at 13 58 33@2x

Which issue(s) this PR fixes:

(REQUIRED)

Addresses discussion #5528

Special notes for your reviewer:

There are three things in particular I'd like reviewers to take a look at and/or let me know:

  • The sidebar had specific handling for when a user isn't logged in; for example, the language and theme switcher menu items were also shown to logged-out users. I'm not sure what the use cases for this are.
    • Right now, the user menu on the top right is only shown to logged-in users. If logged-out usage is important, please let me know how we should address this here (e.g. use a placeholder icon instead of user avatar for the menu button)
  • The AppHeader shows a "login" button when it's viewed in a logged-out state. I've kept this for now, but I'm not sure when this would be actionable (similar to the logged-out sidebar). Shouldn't the UI just redirect to the login page right away when the user isn't logged in? 🤔
  • I have applied PR feedback in additional commits within this PR, partially so that they're easy to adjust or revert based on pending feedback by the core maintainers. If the PR doesn't get merged with a "squash" strategy, I'm happy to squash these manually before merging (or for one of the maintainers to do this for me).

Two minor things I noticed but didn't address in this PR yet (i think these can be addressed in follow-up PRs if desired):

  • Inside the new profile menu, the user avatar and the other icons are not horizontally centered (they're left-aligned). This is the default behavior of Vuetify's v-list, and I didn't find an obvious way to change this. In fact, v-list-item uses pretty hard-coded spacing between the prepend slot and the item's text, making customization of this a bit tricky (and probably not easy to maintain). This is now addressed -- the user avatar is no longer showing inside of the menu
  • When you click the theme switcher (dark/light mode), the menu closes (default behavior of the popup menu component). This is the same as it currently does in the "settings" menu in the sidebar. I think it would be nicer if the menu stayed open, to make it easier to toggle back if you don't like the other theme or if you clicked it accidentally (imagine blinding yourself by accidentally switching to light mode at night 🙈).

Testing

Manually, running the dev server locally.

v-model="sidebar"
absolute
:top-link="topLinks"
:user="{ data: true }"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment: it seems this user prop of the sidebar wasn't even used anymore before my changes in this PR

Comment on lines 81 to 83
<!-- TODO: what was the use case for sidebar settings in logged-out state? -->
<v-divider v-if="loggedIn" class="my-2" />
<v-list-item v-if="loggedIn" :prepend-icon="$globals.icons.cog" :title="$t('profile.user-settings')" to="/user/profile" />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment: right now, these v-if="loggedIn" conditionals here are redundant, because the entire user menu is only rendered when a user is logged in.

If we want to show a menu for logged-out users too (e.g. for switching language and theme), this needs to be reviews. If we don't want to support that use-case, these redundant conditionals should be removed. See PR description for more details.

@lehnerpat lehnerpat changed the title feat: User profile + settings menu in top right (AppHeader) instead of top/bottom left (AppSidebar) [WIP] feat: User profile + settings menu in top right (AppHeader) instead of top/bottom left (AppSidebar) Dec 30, 2025
@lehnerpat
Copy link
Contributor Author

The E2E tests are currently failing because they expect the user name to appear in the sidebar (which it now no longer does).

I'm looking into how to adjust them to find the user name in the user menu instead.

@lehnerpat
Copy link
Contributor Author

lehnerpat commented Dec 30, 2025

I've updated the E2E tests to work locally.

Edit: and they work in CI as well 👌

@lehnerpat lehnerpat marked this pull request as ready for review December 30, 2025 04:45
@p0lycarpio
Copy link
Contributor

That sounds good! Here are a few suggestions:

  • To correct the avatar's misalignment with the other items on the list, could we use a generic "account" icon with the title and subtitle "Profile" + username?
  • The entry to "User Settings" seems to be a slight duplication to me, and I don't see the added value it brings other than saving a click. Perhaps it could be removed if the previous suggestion is implemented?
  • I would keep the shortcut to favorite recipes in the hamburger menu, below the "Create" button, as it is more common to navigate via this menu than the menu at the top right. This is equivalent to the "Favorites" menus found in other cloud storage services, for example.
  • The language change button is not used very often, and I think we could move it to the user settings page instead, but that could be done in another PR.

@lehnerpat
Copy link
Contributor Author

@p0lycarpio, thanks for your feedback! 🙌

  • To correct the avatar's misalignment with the other items on the list, could we use a generic "account" icon with the title and subtitle "Profile" + username?

Ah yes, good point. While looking around at other examples of this pattern, I originally thought some other sites put the profile image into the popover menu, and use that to link to the profile page. Looking around again now, that doesn't seem to be the case.

Some examples:

Github Paperless-ngx
(Desktop view)
Paperless-ngx
(Mobile view)
CleanShot 2026-01-05 at 10 46 30@2x
This shows the profile image inside the popover, but it's not an active link. There's another "Profile" link below. Also, the icons don't try to be aligned with the profile image.
CleanShot 2026-01-05 at 10 48 02@2x
This does not replicate the profile image inside the menu (caveat: Paperless-ngx doesn't currently support profile images). It shows the user name in the app bar in Desktop mode.
CleanShot 2026-01-05 at 10 50 37@2x
In mobile mode, Paperless-ngx shows the user name inside the menu, which I find a useful idea.
  • The entry to "User Settings" seems to be a slight duplication to me, and I don't see the added value it brings other than saving a click. Perhaps it could be removed if the previous suggestion is implemented?

Oh, good catch! I didn't even realize that "User Settings" links to the same page as the "Profile" link (what used to be the link of the profile image on the top left). This is clearly redundant.

In Mealie, the so-called "profile" page (at /user/profile) isn't really what you'd consider a user profile based on other apps; in my understanding, a user profile page is a place showing information about that user (profile image, name, contact info, bio, etc.).
Mealie instead shows more of an account overview or account management screen here (the subtitle text it shows is "Manage your profile, recipes, and group settings."). Confusingly, the subsection there titled "User Settings" is where you actually edit your profile information, such as your display name and email address.

Combining this with your first suggestion, I think I'll go for something like "Account" or "My Account" (though this may introduce a new translation string, I'll have to check if there is already a suitable one).

  • I would keep the shortcut to favorite recipes in the hamburger menu, below the "Create" button, as it is more common to navigate via this menu than the menu at the top right. This is equivalent to the "Favorites" menus found in other cloud storage services, for example.

Fair point, I didn't really reflect on this too much (since I never use this).
Leaving it in the left-side menu raises the question of its position in the order of the links; I expect users likely have some muscle memory about the links' current order, especially "Recipes" being the topmost one.

But adjusting the order based on further feedback should be easy, so I'll move it over there for the time being.

  • The language change button is not used very often, and I think we could move it to the user settings page instead, but that could be done in another PR.

Agreed that this doesn't need to be here (similar to the old Logout button in the top bar, the language switcher is likely too prominent here).
But I don't see a natural place where the language switcher would fit immediately in the user account page, so let's do this in a separate PR indeed.

Comment on lines 235 to 241
{
icon: $globals.icons.heart,
// TODO: how to hide this for non-logged-in view?
to: `/user/${$auth.user.value.id}/favorites`,
title: i18n.t("user.favorite-recipes"),
restricted: false,
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment: this change now introduced a dependency of this file to the logged-in state of the user; how should we handle this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set restricted to true for this.

Copy link
Contributor

@p0lycarpio p0lycarpio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes, it looks good! Here are a few more suggestions for the layout and spacing.

Comment on lines 235 to 241
{
icon: $globals.icons.heart,
// TODO: how to hide this for non-logged-in view?
to: `/user/${$auth.user.value.id}/favorites`,
title: i18n.t("user.favorite-recipes"),
restricted: false,
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set restricted to true for this.

</v-icon>
{{ smAndUp ? $t("user.logout") : "" }}
</v-btn>
<div v-if="loggedIn && sessionUser" class="mx-1">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 <div v-if="loggedIn && sessionUser" :class="xs ? 'pr-2' : 'px-2'">

<template v-if="xs">
<v-list-subheader :title="sessionUser.fullName ?? undefined" class="justify-center" />
<v-divider class="my-2" />
</template>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the block template above, here is another way to do this on mobile:

 <v-list-item
    :prepend-icon="$globals.icons.user"
    :title="$t('settings.profile')"
    :subtitle="xs ? sessionUser.fullName || undefined : undefined"
    :to="userProfileLink"
    :lines="xs ? 'two' : 'one'"
  />

Copy link
Collaborator

@michael-genson michael-genson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally like this change, I think it makes sense and solves the log out issue. A few notes:

  • You can browse Mealie even if you aren't logged-in, so keeping language and theme settings available is important
  • I don't think we should get rid of the setting menu, putting it in the lower left seems natural to me. Can we instead limit the new profile button to just "Profile" and "Logout" and keep the rest in settings?
  • This might just be personal opinion but the button being rounded looks a little odd to me since the profile picture is already rounded and right up against the border, maybe we can make it less round and add some padding? Open to criticism on this, I'm more of a backend person
Image

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants