Skip to content

Add a regenerate-slug button to the article editor - #201

Merged
ssavutu merged 1 commit into
mainfrom
feat/regenerate-slug
Aug 7, 2026
Merged

Add a regenerate-slug button to the article editor#201
ssavutu merged 1 commit into
mainfrom
feat/regenerate-slug

Conversation

@ssavutu

@ssavutu ssavutu commented Aug 7, 2026

Copy link
Copy Markdown
Member

Editors had no way to fix a slug after an article was created — the field was read-only and the slug was frozen at whatever the title happened to be on the first save.

What this adds

A Regenerate from title button under the Slug field in the article editor.

  • New article — fills the slug box with the slugified title.
  • Existing article — the field stays read-only, but the regenerated slug is loaded into it as pending. It is only committed by an explicit Save/Publish; autosave never sends it, so an article's public URL cannot move on a 2.5s debounce. After the save succeeds the editor redirects itself to the new /articles/<slug>/edit, since the route it was on no longer resolves.
  • Collisionsarticles.slug has no unique index (it is LONGTEXT), so the button probes GET /v1/articles/<candidate> and falls back to -2, -3, … up to -20 rather than pointing two articles at one URL. The article's own slug counts as free.

Server side needed no changes: PATCH /v1/articles/{slug} already accepts and validates a slug field.

Known gap

There is no redirect table, so a regenerated slug leaves the old URL as a hard 404 rather than a 301. The pending-state hint warns about this and offers a "Keep the current slug" escape, but that is the only mitigation — worth a follow-up before this gets used much on published articles.

Supporting changes

  • slugifyCategoryslugify; it already matched the server's CanonicalizeSlug rules exactly.
  • The slug <label> was split so the buttons underneath are not read out as part of the field's accessible name.

Testing

Three tests added covering the autosave exclusion, the explicit-save path, and the -2 suffix. Full frontend suite passes (11 tests). Typecheck is clean apart from pre-existing TrixEditor.tsx errors; lint shows only the pre-existing saveArticle dependency warning.

🤖 Generated with Claude Code

Rebuilds the slug from the current title. On a new article it just fills
the slug box; on an existing one the regenerated slug is held as pending
and only committed by an explicit save, so an article's public URL can
never move under the 2.5s autosave. The editor redirects itself to the
new /articles/<slug>/edit afterwards, since the route it was on no
longer resolves.

articles.slug carries no unique index, so two articles could otherwise
land on one public URL: the button probes GET /v1/articles/<candidate>
and falls back to -2, -3, ... up to -20 rather than reusing a slug that
another article already holds.

The pending state warns that the old /article/<slug> will 404 -- there
is no redirect table, so nothing catches the old URL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ssavutu
ssavutu merged commit 80527bb into main Aug 7, 2026
6 checks passed
@ssavutu
ssavutu deleted the feat/regenerate-slug branch August 7, 2026 00:26
ssavutu added a commit that referenced this pull request Aug 7, 2026
Conflict was two tests added at the same point in the autosave describe
block: this branch's "alt text autosaves on its own" and main's three
regenerate-slug cases (#201). They test unrelated fields, so both are
kept.

editArticleView.tsx merged clean and correctly: the snapshot now carries
both photoAlt and main's isNew-scoped slugInput, so an alt-text edit
still autosaves and a regenerated slug still waits for an explicit save.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant