Skip to content

fix(admin): debounce SEO sidebar saves#87

Merged
ascorbic merged 7 commits intoemdash-cms:mainfrom
txhno:fix/seo-panel-debounce
Apr 13, 2026
Merged

fix(admin): debounce SEO sidebar saves#87
ascorbic merged 7 commits intoemdash-cms:mainfrom
txhno:fix/seo-panel-debounce

Conversation

@txhno
Copy link
Copy Markdown
Contributor

@txhno txhno commented Apr 2, 2026

What does this PR do?

Closes #78

Debounces SEO sidebar text-field saves in the admin sidebar instead of issuing a PUT on every keystroke, keeps stale save responses from overwriting newer local typing, and preserves immediate noIndex updates.

Type of change

  • Bug fix
  • Feature (requires approved Discussion)
  • Refactor (no behavior change)
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm --silent lint:json | jq '.diagnostics | length' returns 0
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...

AI-generated code disclosure

  • This PR includes AI-generated code

Screenshots / test output

  • npx pnpm@10.28.0 --filter @emdash-cms/admin exec vitest run tests/components/SeoPanel.test.tsx
  • npx pnpm@10.28.0 --filter @emdash-cms/admin typecheck
  • npx pnpm@10.28.0 --silent lint:quick

@JULJERYT
Copy link
Copy Markdown
Contributor

JULJERYT commented Apr 6, 2026

i noticed a few issues:

  • useDebouncedValue gets a new object reference every render
  • onChange is not stable at the call site
    (in ContentEditor.tsx onSeoChange is passed directly as onChange without useCallback and since ContentEditor re-renders frequently (it holds all the form state) onChange gets a new identity on every render.)
  • noIndex toggle has duplicated snapshot logic
  • deprecated import (@vitest/browser/context)
  • and last but not least - missing changeset

@JULJERYT
Copy link
Copy Markdown
Contributor

JULJERYT commented Apr 6, 2026

matt could u commit those?
packages/admin/tests/components/SeoPanel.test.tsx line 1

import { userEvent } from "vitest/browser";

packages/admin/src/components/SeoPanel.tsx
(too many changes had to paste entire file with changes to gist)
https://gist.github.com/JULJERYT/b7a9148a3d213fc7a0b4b023c45ec64f

changeset

---
"emdash": patch
---

Fixes SEO sidebar text fields firing a PUT on every keystroke by debouncing saves; guards against stale server responses overwriting newer local edits.

@ascorbic is there any other way I can suggest changes to the code besides commenting on them in PRs?

@JULJERYT
Copy link
Copy Markdown
Contributor

JULJERYT commented Apr 6, 2026

Thanks to Nick Gray for sponsoring my time on this review

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 6, 2026

🦋 Changeset detected

Latest commit: 4938e3d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@emdash-cms/admin Patch
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
create-emdash Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 6, 2026

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@87

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@87

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@87

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@87

emdash

npm i https://pkg.pr.new/emdash@87

create-emdash

npm i https://pkg.pr.new/create-emdash@87

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@87

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@87

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@87

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@87

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@87

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@87

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@87

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@87

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@87

commit: 4938e3d

@txhno txhno force-pushed the fix/seo-panel-debounce branch from 70349fc to 76fecae Compare April 9, 2026 07:16
@txhno
Copy link
Copy Markdown
Contributor Author

txhno commented Apr 9, 2026

Pushed a follow-up on top of current main: addressed the SEO panel review notes, added the changeset, updated the PR body to the template, and reran targeted validation for SeoPanel plus admin typecheck and lint:quick.

@txhno txhno force-pushed the fix/seo-panel-debounce branch from 7f32ed5 to 0d5208c Compare April 9, 2026 07:19
@txhno
Copy link
Copy Markdown
Contributor Author

txhno commented Apr 9, 2026

Latest follow-up commit: txhno@0d5208c . This is the current PR head after rewriting the format-only change into a normal commit.

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 updates the admin content editor’s SEO sidebar behavior to avoid firing a content update request on every keystroke, while also preventing older save responses from clobbering newer locally-typed values.

Changes:

  • Debounce SEO text field (title, description, canonical) saves while keeping noIndex updates immediate.
  • Add local draft + snapshot syncing logic to avoid overwriting newer local edits when stale props arrive.
  • Add browser tests covering debouncing, immediate noIndex, stale-props protection, and reset on content switch.

Reviewed changes

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

File Description
packages/admin/src/components/SeoPanel.tsx Introduces debounced draft-based editing + stale-props guards; adds contentKey reset behavior.
packages/admin/src/components/ContentEditor.tsx Passes contentKey into SeoPanel and routes SEO changes through a callback.
packages/admin/tests/components/SeoPanel.test.tsx Adds new test coverage for debounced saves and stale response protection.
.changeset/fair-donkeys-ring.md Adds a changeset entry describing the behavior change.

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

@ascorbic
Copy link
Copy Markdown
Collaborator

@txhno I'd love to get this in. Can you address the review comments so I can merge it?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 13, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@txhno
Copy link
Copy Markdown
Contributor Author

txhno commented Apr 13, 2026

Follow-up on the remaining review threads:

  • kept the SEO draft flush behavior already on this branch: pending debounced text saves are flushed before contentKey resets and on unmount
  • kept the changeset scoped to @emdash-cms/admin, which matches the affected published package
  • switched the new SEO panel browser test to vitest/browser after rerunning the targeted test and confirming @vitest/browser/context emits a deprecation warning in the current Vitest version

Validation rerun: npx pnpm@10.28.0 --filter @emdash-cms/admin exec vitest run tests/components/SeoPanel.test.tsx

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

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


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

@ascorbic
Copy link
Copy Markdown
Collaborator

recheck

github-actions bot added a commit that referenced this pull request Apr 13, 2026
@txhno
Copy link
Copy Markdown
Contributor Author

txhno commented Apr 13, 2026

@ascorbic the follow-up changes are in now: the remaining review comments have been addressed, the review threads are resolved, the CLA is passing, and the checks are green. This should be good to merge.

@ascorbic ascorbic force-pushed the fix/seo-panel-debounce branch from b44810d to 4938e3d Compare April 13, 2026 19:34
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Apr 13, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-playground 4938e3d Apr 13 2026, 07:36 PM

Copy link
Copy Markdown
Collaborator

@ascorbic ascorbic left a comment

Choose a reason for hiding this comment

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

Great! Thanks

@ascorbic ascorbic enabled auto-merge (squash) April 13, 2026 19:39
@ascorbic ascorbic merged commit c869df2 into emdash-cms:main Apr 13, 2026
29 checks passed
@emdashbot emdashbot bot mentioned this pull request Apr 13, 2026
fmhall pushed a commit to fmhall/emdash that referenced this pull request Apr 13, 2026
* fix(admin): flush pending seo sidebar saves

* style: format

* fix(admin): flush pending seo sidebar saves

* test(admin): use non-deprecated vitest browser import

* style: format

* fix(admin): tighten seo panel follow-up

* style: format

---------

Co-authored-by: emdashbot[bot] <emdashbot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SEO Fields making immediate PUT, instead of having debounce.

4 participants