Symptom
On a Quartz site, the mobile Explorer menu briefly appeared and then slid away whenever an internal page link was clicked.
The user had not pressed the menu button. The menu looked as if it opened and closed only because a page transition happened.
Cause
The cause was not document frontmatter or Markdown heading structure. It was the client-side initialization order of the Explorer plugin.
The site uses enableSPA: true. Internal links therefore trigger Quartz SPA navigation instead of a full browser reload.
During each SPA transition, Explorer does roughly this:
- Clears the existing Explorer tree.
- Rebuilds the file tree from
contentIndex.json. - Applies folder open/closed state from
localStorage.fileTree. - Removes the mobile Explorer button’s
hide-until-loadedclass. - If the mobile Explorer is visible, reapplies
.collapsedso it is closed.
The flicker happens in the short gap between steps 4 and 5. Once hide-until-loaded is removed, the Explorer content can become visible. Then .collapsed is immediately applied again, and the CSS transform transition animates the menu closed.
The final state is correct, but the user sees the intermediate state.
Why Configuration Was Not Enough
folderDefaultState, folderClickBehavior, and useSavedState control the Explorer folder tree’s default and persisted open state.
The bug was not the folder tree state. It was the mobile Explorer container briefly becoming visible during SPA navigation and then animating into its collapsed state.
That makes the problem a mobile collapse animation issue, not a normal Explorer option issue.
Fixing Principle
The plugin code under .quartz/ is installed plugin cache. Editing it directly would be brittle because reinstalling or updating plugins can overwrite the change.
The problem can be fixed with a site-level CSS override, so the change should stay in quartz/styles/custom.scss.
Applied Fix
Disable the close animation when the mobile Explorer is being collapsed:
@media all and (max-width: 800px) {
.explorer.collapsed > .explorer-content {
transition: none;
}
.explorer:not(.collapsed) > .explorer-content {
transition:
transform 200ms ease,
visibility 200ms ease;
}
}This prevents the automatic .collapsed application during page navigation from playing a closing animation.
The opening transition remains for the user’s intentional menu action. The closing direction becomes immediate, which removes the fake slide during SPA navigation.
Diagnostic Criteria
If a similar issue appears again, separate these cases:
- Did document content change cause a rendering problem?
- Did Quartz configuration change the initial server-rendered state?
- Did client-side code reapply state after SPA navigation?
- Did a CSS transition expose an intermediate state to the user?
This issue was the third and fourth case: client-side state reapplication plus a transition on the intermediate state.
Reusable Lesson
In an SPA, UI that briefly appears only during navigation may not have an incorrect final state.
Even if the final DOM state is correct, a CSS transition between server-rendered state and client-side reinitialized state can expose a transient state as a visible defect. For this kind of bug, inspect both the JavaScript state sequence and the CSS transition applied after state changes.