Mobile AI chat architecture is how a chat product handles navigation on a small screen, and the honest answer for most products is that they shrink the desktop layout and hope.

That produces something that works and feels wrong. A sidebar becomes a hamburger, panels become full width, and every navigation is a page load that throws away scroll position and state. It passes QA and nobody enjoys using it.

Diagram of the ChatFuse two shell mobile architecture: dashboard routes render one React tree with a panel stack, chat routes render a separate tree, and the breakpoint is 767px.

ChatFuse runs a panel stack below 767px instead. Here is how it is put together and what it costs.

What is the ChatFuse mobile panel stack?

A navigation model borrowed from native apps, where each section is a full screen panel that slides in from the right and can be swiped back, stacked on top of whatever you came from.

Tools, Personas, Projects, Library, and Chats are each a panel. Drilling from a list into a detail pushes a panel. Swiping back pops it. The mental model is a deck of cards rather than a set of pages, which is what people already expect from every other app on the device.

Does the URL still change?

Yes, and that is the constraint that makes this harder than it looks.

The URL updates through history state rather than a full navigation, so the address bar tracks where you are and links still work, but React state survives. No full page navigation happens inside a session. You keep your scroll position, your open sheet, and your half typed message when you move between sections.

What is the two shell part of ChatFuse mobile?

Below 767px there are two completely separate React trees, and which one you get depends on the URL.

Dashboard routes render one shell with the panel stack, the top bar, the floating action button, and the bottom sheets. The chat route renders a different shell entirely. They are not variations of one layout, they are different trees with different providers.

ShellRoutesRenders
Dashboard shellcredits, personas, tools, agents, library, projects, canvas, workflowsPanel stack, top bar, action button, bottom sheets
Chat portalchatIts own chrome, sidebar as the whole navigation

Splitting them was a real decision with a real cost, which is that a shared component has to work correctly in both. The payoff is that neither shell carries conditionals for the other's behavior, and chat has genuinely different navigation needs from a catalog.

What breaks when you add a new ChatFuse route?

Deep links and refreshes, silently, unless you do one extra step.

Adding a route to the dashboard list is not enough. There is a function that rebuilds the panel stack from a URL, and every route needs a case in it. Without one, the route works when you navigate to it inside the app and reconstructs the wrong stack when someone opens the link cold or hits refresh.

That failure only shows up on a fresh load, which is exactly the path nobody tests manually while building a feature. It is now a written rule rather than folklore, because it caught us more than once.

Route added onlyRoute plus a stack case
Tapping into it in appWorksWorks
A cold deep linkRebuilds the wrong panel stackWorks
A page refreshRebuilds the wrong panel stackWorks
A shared linkRebuilds the wrong panel stackWorks

Why 767px and not a device size?

Because device sizes are a moving target and a breakpoint is a layout decision.

Mobile activates at a max width of 767px, one value, read through a shared hook. Nothing reads window width directly and nothing declares its own media query, because two components disagreeing about what mobile means produces a layout that is half one thing and half the other at exactly one width, which is miserable to debug.

The same rule covers z-index, touch target sizes, animation timings, and panel dimensions. They live in a constants file. A hardcoded pixel value in a component is treated as a defect.

How do ChatFuse modals work on a small screen?

As bottom sheets on mobile and centered dialogs on desktop, decided inside the component.

Any modal with a fixed width or one that portals itself has to make this choice explicitly. A dialog with a fixed width will overflow a small viewport, and a component that portals to the document root escapes the panel stack and renders behind or above things it should not.

Fixed width modal on mobileChatFuse bottom sheet
Small viewportOverflowsFits any width
Panel stackPortals outside itLives inside it
LayeringRenders behind the top barCorrect z-order
DismissingA tiny close targetDrag to dismiss, 44px targets

Is this just a mobile web wrapper?

No. The panel stack runs in the browser and in the native shells, so the navigation model is the same whether it is a tab or an installed app. The gestures, the panel transitions, and the sheet behavior come from the same code rather than being reimplemented per platform.

What does this cost to maintain?

More than a responsive layout, and the cost is concentrated in one place: any component under either shell has to be checked at the panel layer, not just at its own layer.

A component can look correct in isolation and be wrong inside an L2 detail panel, because the panel supplies its own scroll container and its own header. So the review question is never only whether the component renders. It is which shell renders it and at which level of the stack.

Does the desktop layout change too?

No. Above the breakpoint the desktop layout is untouched. The panel system activates below 767px and is otherwise inert, which is why the two can evolve without one constantly breaking the other.

What does a shared component have to survive?

Three positions, because the same component can render as a top level list, as a pushed detail panel, or inside a sheet.

Diagram of the three positions a shared component renders in on mobile: an L1 section list, an L2 detail panel pushed onto the stack, and a bottom sheet.

An L1 list owns the full screen and scrolls itself. An L2 detail sits on top of it with a back affordance and its own scroll container. A sheet floats above both and is dismissible by drag. A component that assumes it controls the page scroll works in the first position and breaks in the other two, usually by producing a scroll container inside a scroll container, which feels broken in a way that is hard to describe in a bug report and instantly obvious on a phone.

So the review question for anything under either shell is which position it renders in, plural. Answering only for the position you built it in is how the second one ships broken.

Is a panel stack better than tabs?

For this product, yes, because the content is deep rather than flat. Tabs work when you have 4 or 5 destinations of equal weight. A catalog with categories, items, and item details is a hierarchy, and a stack is the honest representation of a hierarchy.

How do I see ChatFuse mobile AI chat?

Open ChatFuse on a phone, or narrow a desktop browser below 767px and the panel system takes over. Start free, or read how the underlying routing works in AI model orchestration.

Back to Blog

Written by Michael

Share

Comments

Loading commentsโ€ฆ

Secure signup continues in a new tab.