Skip to content

feat: preserve slide overview position via url hash#2476

Open
Barbapapazes wants to merge 2 commits into
slidevjs:mainfrom
Barbapapazes:feat/overview-page-reload-resilience
Open

feat: preserve slide overview position via url hash#2476
Barbapapazes wants to merge 2 commits into
slidevjs:mainfrom
Barbapapazes:feat/overview-page-reload-resilience

Conversation

@Barbapapazes
Copy link
Copy Markdown
Contributor

Hey!

This PR includes some UX improvements for the overview page. When clicking on a slide link, a hash is now added to the URL (e.g. http://localhost:3030/overview#slide-24), making it easy to refresh the page or share a direct link to a specific slide section in long decks.

Copilot AI review requested due to automatic review settings March 9, 2026 11:44
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 9, 2026

Deploy Preview for slidev failed.

Name Link
🔨 Latest commit b6236eb
🔍 Latest deploy log https://app.netlify.com/projects/slidev/deploys/69aeb5bef3c6400008526bbc

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Mar 9, 2026

Open in StackBlitz

@slidev/client

npm i https://pkg.pr.new/@slidev/client@2476

create-slidev

npm i https://pkg.pr.new/create-slidev@2476

create-slidev-theme

npm i https://pkg.pr.new/create-slidev-theme@2476

@slidev/parser

npm i https://pkg.pr.new/@slidev/parser@2476

@slidev/cli

npm i https://pkg.pr.new/@slidev/cli@2476

@slidev/types

npm i https://pkg.pr.new/@slidev/types@2476

commit: 0ac0d21

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds URL hash-based navigation to the Slidev slide overview page. When clicking a slide number in the left sidebar, the URL updates with a hash (e.g., #slide-24), enabling page refresh persistence and direct linking to specific slides. The template loop variable was also renamed from route to slide to avoid shadowing the vue-router useRoute() variable.

Changes:

  • Added hash-based scroll tracking with getSlideHashId, getSlideHash, getSlideIndexFromHash, and scrollToSlideAndUpdateHash functions that update the URL hash when clicking sidebar slide numbers
  • Added a vue-router hash watcher and onMounted hook to restore scroll position from the URL hash on page load and browser navigation
  • Renamed the v-for loop variable from route to slide throughout the template to avoid shadowing the vue-router route object, and updated documentation

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/client/pages/overview.vue Core implementation: hash generation/parsing functions, scroll-to-hash on mount, hash update on sidebar click, watcher for hash changes, and template loop variable rename
docs/guide/ui.md Documents the new URL hash behavior in the Slide Overview section

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/guide/ui.md Outdated
const blocks: Map<number, HTMLElement> = reactive(new Map())
const activeBlocks = ref<number[]>([])
const edittingNote = ref<number | null>(null)
const skipHashScroll = ref<string>()
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

There is a potential race condition with rapid clicks on the sidebar buttons. skipHashScroll stores a single hash value, but the watcher contains await nextTick() which yields control. If the user clicks slide 1 then quickly clicks slide 2 before the watcher finishes processing the first hash change, the second click overwrites skipHashScroll to "#slide-2", and then the watcher for #slide-1 sees a mismatch and triggers an unwanted smooth scroll back to slide 1.

While unlikely in practice, consider using a Set<string> instead of a single ref to track all hashes that should skip scrolling, removing each entry as it's consumed by the watcher.

Copilot uses AI. Check for mistakes.
Comment thread docs/guide/ui.md Outdated
}

function scrollToSlide(idx: number) {
function getSlideHashId(no: number) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How about inining getSlideHashId?

<div
v-for="(route, idx) of slides"
:key="route.no"
v-for="(slide, idx) of slides"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How about reverting the renaming of route, which is common in the codebase?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants