Custom layout

Hi, i want to use nuxt ui pro to make a layout where i have a navbar on top of the screen sticky, then below that a collapsible chat on the right side of the screen and to the left of it a main content area. within that main content area i want to have my content slot at the top, below that a footer. so when the chat is closed the main content area takes up more space etc. also resizeable. what is the simplest and cleanest way to properly achieve this layout?
8 Replies
kapa.ai
kapa.ai2w ago
Hi @WiFi Plug. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To create a custom layout with a sticky navbar, collapsible chat, and main content area with Nuxt UI Pro, you can use a combination of the DashboardGroup, DashboardPanel, and other UI Pro components. Here's how you can achieve this layout: Creating the Layout You can create a custom layout file in your Nuxt project, for example layouts/custom.vue:
<template>
<div class="flex flex-col min-h-screen">
<!-- Sticky Header -->
<UHeader class="sticky top-0 z-10" />

<!-- Main Content Area with Chat -->
<UDashboardGroup storage="local" storage-key="dashboard-layout">
<!-- Main Content Panel -->
<UDashboardPanel id="main-content" class="flex-1">
<template #body>
<div class="flex flex-col h-full">
<!-- Content Slot -->
<div class="flex-1">
<slot />
</div>

<!-- Footer -->
<UFooter />
</div>
</template>
</UDashboardPanel>

<!-- Collapsible Chat Panel -->
<UDashboardPanel
id="chat"
resizable
collapsible
:min-size="22"
:default-size="35"
:max-size="40"
class="hidden lg:flex"
>
<template #header>
<UDashboardNavbar title="Chat">
<template #right>
<UDashboardSidebarCollapse />
</template>
</UDashboardNavbar>
</template>

<template #body>
<!-- Chat content goes here -->
<div class="h-full">
Chat content
</div>
</template>
</UDashboardPanel>
</UDashboardGroup>
</div>
</template>
<template>
<div class="flex flex-col min-h-screen">
<!-- Sticky Header -->
<UHeader class="sticky top-0 z-10" />

<!-- Main Content Area with Chat -->
<UDashboardGroup storage="local" storage-key="dashboard-layout">
<!-- Main Content Panel -->
<UDashboardPanel id="main-content" class="flex-1">
<template #body>
<div class="flex flex-col h-full">
<!-- Content Slot -->
<div class="flex-1">
<slot />
</div>

<!-- Footer -->
<UFooter />
</div>
</template>
</UDashboardPanel>

<!-- Collapsible Chat Panel -->
<UDashboardPanel
id="chat"
resizable
collapsible
:min-size="22"
:default-size="35"
:max-size="40"
class="hidden lg:flex"
>
<template #header>
<UDashboardNavbar title="Chat">
<template #right>
<UDashboardSidebarCollapse />
</template>
</UDashboardNavbar>
</template>

<template #body>
<!-- Chat content goes here -->
<div class="h-full">
Chat content
</div>
</template>
</UDashboardPanel>
</UDashboardGroup>
</div>
</template>
Key Components Used 1. UHeader: For the sticky navbar at the top of the screen Header 2. UDashboardGroup: Provides context for dashboard components with state management and persistence DashboardGroup 3. UDashboardPanel: For both the main content area and the collapsible chat panel DashboardPanel 4. UDashboardNavbar: For the chat panel header DashboardNavbar 5. UDashboardSidebarCollapse: A button to collapse the chat panel DashboardSidebarCollapse 6. UFooter: For the footer in the main content area Footer Features of This Layout - The navbar is sticky at the top using the sticky top-0 z-10 classes - The chat panel is resizable and collapsible with configurable min, max, and default sizes - The main content area will automatically expand when the chat is collapsed - The layout uses the storage and storage-key props to persist the state of the panels - The chat panel is hidden on mobile (hidden lg:flex) To use this layout in your pages, you would set the layout in your page's meta:
<script setup>
definePageMeta({
layout: 'custom'
})
</script>

<template>
<!-- Your page content here -->
</template>
<script setup>
definePageMeta({
layout: 'custom'
})
</script>

<template>
<!-- Your page content here -->
</template>
This approach gives you a clean, responsive layout that meets all your requirements while leveraging Nuxt UI Pro's built-in components. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
WiFi Plug
WiFi PlugOP2w ago
@kapa.ai the navbar in your example is hiding the top part of the chat and the top part of the main content
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're right, and I apologize for the oversight. The sticky header would indeed overlap with the content below it. Let's fix this by adjusting the layout to account for the header height. Here's an improved version that properly handles the spacing:
<template>
<div class="flex flex-col min-h-screen">
<!-- Sticky Header -->
<UHeader class="sticky top-0 z-10" />

<!-- Main Content Area with Chat -->
<UMain> <!-- This component accounts for header height -->
<UDashboardGroup storage="local" storage-key="dashboard-layout">
<!-- Main Content Panel -->
<UDashboardPanel id="main-content" class="flex-1">
<template #body>
<div class="flex flex-col h-full">
<!-- Content Slot -->
<div class="flex-1">
<slot />
</div>

<!-- Footer -->
<UFooter />
</div>
</template>
</UDashboardPanel>

<!-- Collapsible Chat Panel -->
<UDashboardPanel
id="chat"
resizable
collapsible
:min-size="22"
:default-size="35"
:max-size="40"
class="hidden lg:flex"
>
<template #header>
<UDashboardNavbar title="Chat">
<template #right>
<UDashboardSidebarCollapse />
</template>
</UDashboardNavbar>
</template>

<template #body>
<!-- Chat content goes here -->
<div class="h-full">
Chat content
</div>
</template>
</UDashboardPanel>
</UDashboardGroup>
</UMain>
</div>
</template>
<template>
<div class="flex flex-col min-h-screen">
<!-- Sticky Header -->
<UHeader class="sticky top-0 z-10" />

<!-- Main Content Area with Chat -->
<UMain> <!-- This component accounts for header height -->
<UDashboardGroup storage="local" storage-key="dashboard-layout">
<!-- Main Content Panel -->
<UDashboardPanel id="main-content" class="flex-1">
<template #body>
<div class="flex flex-col h-full">
<!-- Content Slot -->
<div class="flex-1">
<slot />
</div>

<!-- Footer -->
<UFooter />
</div>
</template>
</UDashboardPanel>

<!-- Collapsible Chat Panel -->
<UDashboardPanel
id="chat"
resizable
collapsible
:min-size="22"
:default-size="35"
:max-size="40"
class="hidden lg:flex"
>
<template #header>
<UDashboardNavbar title="Chat">
<template #right>
<UDashboardSidebarCollapse />
</template>
</UDashboardNavbar>
</template>

<template #body>
<!-- Chat content goes here -->
<div class="h-full">
Chat content
</div>
</template>
</UDashboardPanel>
</UDashboardGroup>
</UMain>
</div>
</template>
The key change is adding the UMain component, which automatically accounts for the header height using the --ui-header-height CSS variable. As described in the Main component documentation, it renders a <main> element that works together with the Header component to create a full-height layout without overlap. The UMain component uses this CSS by default:
min-h-[calc(100vh-var(--ui-header-height))]
min-h-[calc(100vh-var(--ui-header-height))]
This ensures that the content below the header starts exactly after the header ends, preventing any overlap issues. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
WiFi Plug
WiFi PlugOP2w ago
@kapa.ai "export default defineAppConfig({ uiPro: { dashboardPanel: { slots: { root: 'relative flex flex-col min-w-0 min-h-svh lg:not-last:border-r lg:not-last:border-default shrink-0', body: 'flex flex-col gap-4 sm:gap-6 flex-1 overflow-y-auto p-4 sm:p-6', handle: '' }, variants: { size: { true: { root: 'w-full lg:w-(--width)' }, false: { root: 'flex-1' } } } } } }) " "export default defineAppConfig({ uiPro: { dashboardGroup: { base: 'fixed inset-0 flex overflow-hidden' } } }) " this is the config for dashboard group and dashboard panel and the header component "export default defineAppConfig({ uiPro: { header: { slots: { root: 'bg-default/75 backdrop-blur border-b border-default h-(--ui-header-height) sticky top-0 z-50', container: 'flex items-center justify-between gap-3 h-full', left: 'lg:flex-1 flex items-center gap-1.5', center: 'hidden lg:flex', right: 'flex items-center justify-end lg:flex-1 gap-1.5', title: 'shrink-0 font-bold text-xl text-highlighted flex items-end gap-1.5', toggle: 'lg:hidden', content: 'lg:hidden', overlay: 'lg:hidden', header: 'px-4 sm:px-6 h-(--ui-header-height) shrink-0 flex items-center justify-between gap-3', body: 'p-4 sm:p-6 overflow-y-auto' }, variants: { toggleSide: { left: { toggle: '-ms-1.5' }, right: { toggle: '-me-1.5' } } } } } }) " based on this what's the simplest way to create my layout
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the configuration you've provided for dashboardGroup, dashboardPanel, and header components, here's the simplest way to create your layout with a sticky navbar, collapsible chat, and main content area:
<template>
<div>
<!-- Sticky Header -->
<UHeader>
<template #left>
<h1>Your App Title</h1>
</template>
</UHeader>

<!-- Dashboard Layout -->
<UMain>
<UDashboardGroup storage="local" storage-key="custom-layout">
<!-- Main Content Panel -->
<UDashboardPanel id="main-content">
<template #body>
<div class="flex flex-col h-full">
<!-- Content Slot -->
<div class="flex-1">
<slot />
</div>

<!-- Footer -->
<div class="mt-auto pt-4 border-t border-default">
Footer content here
</div>
</div>
</template>
</UDashboardPanel>

<!-- Chat Panel -->
<UDashboardPanel
id="chat-panel"
resizable
:min-size="20"
:default-size="30"
:max-size="50"
class="hidden lg:flex"
>
<template #header>
<UDashboardNavbar title="Chat">
<template #right>
<UDashboardSidebarCollapse />
</template>
</UDashboardNavbar>
</template>

<template #body>
<!-- Chat content -->
<div class="h-full">
Chat content goes here
</div>
</template>
</UDashboardPanel>
</UDashboardGroup>
</UMain>
</div>
</template>
<template>
<div>
<!-- Sticky Header -->
<UHeader>
<template #left>
<h1>Your App Title</h1>
</template>
</UHeader>

<!-- Dashboard Layout -->
<UMain>
<UDashboardGroup storage="local" storage-key="custom-layout">
<!-- Main Content Panel -->
<UDashboardPanel id="main-content">
<template #body>
<div class="flex flex-col h-full">
<!-- Content Slot -->
<div class="flex-1">
<slot />
</div>

<!-- Footer -->
<div class="mt-auto pt-4 border-t border-default">
Footer content here
</div>
</div>
</template>
</UDashboardPanel>

<!-- Chat Panel -->
<UDashboardPanel
id="chat-panel"
resizable
:min-size="20"
:default-size="30"
:max-size="50"
class="hidden lg:flex"
>
<template #header>
<UDashboardNavbar title="Chat">
<template #right>
<UDashboardSidebarCollapse />
</template>
</UDashboardNavbar>
</template>

<template #body>
<!-- Chat content -->
<div class="h-full">
Chat content goes here
</div>
</template>
</UDashboardPanel>
</UDashboardGroup>
</UMain>
</div>
</template>
This layout takes advantage of the configurations you provided: 1. The UHeader component is already configured to be sticky with sticky top-0 z-50 in your theme config. 2. The UMain component will automatically account for the header height, preventing overlap issues. 3. The UDashboardGroup is configured with fixed inset-0 flex overflow-hidden which creates the proper container for your panels. 4. The UDashboardPanel components are configured to handle the proper styling, with the main content panel expanding when the chat panel is resized or collapsed. You can save this as a layout file (e.g., layouts/custom.vue) and then use it in your pages with:
<script setup>
definePageMeta({
layout: 'custom'
})
</script>
<script setup>
definePageMeta({
layout: 'custom'
})
</script>
This approach leverages the existing configuration you've provided while creating a clean, responsive layout that meets your requirements. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?