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:

  1. Clears the existing Explorer tree.
  2. Rebuilds the file tree from contentIndex.json.
  3. Applies folder open/closed state from localStorage.fileTree.
  4. Removes the mobile Explorer button’s hide-until-loaded class.
  5. If the mobile Explorer is visible, reapplies .collapsed so 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.