fix: add missing url field type#648
Conversation
🦋 Changeset detectedLatest commit: 357c257 The changes in this PR will be included in the next version bump. This PR includes changesets to release 10 packages
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 |
Scope checkThis PR changes 4,094 lines across 20 files. Large PRs are harder to review and more likely to be closed without review. If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs. See CONTRIBUTING.md for contribution guidelines. |
Lunaria Status Overview🌕 This pull request will trigger status changes. Learn moreBy default, every PR changing files present in the Lunaria configuration's You can change this by adding one of the keywords present in the Tracked Files
Warnings reference
|
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/blocks
@emdash-cms/cloudflare
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
Overlapping PRsThis PR modifies files that are also changed by other open PRs: This may cause merge conflicts or duplicated work. A maintainer will coordinate. |
There was a problem hiding this comment.
Pull request overview
Adds first-class support for a "url" field type (previously referenced by docs/seed files but not implemented), wiring it through core schema typing/validation and the admin UI/editor with client-side URL validation.
Changes:
- Extend core schema types + API schema validation to accept
"url"fields (incl. column mapping and runtime field kind mapping). - Add URL field rendering and validation in the admin Content Editor and expose URL in the field type picker (incl. repeater sub-fields).
- Add unit coverage for Zod schema generation for the new field type and update i18n catalogs.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/tests/unit/schema/zod-generator.test.ts | Adds a unit test validating the generated Zod schema for url fields. |
| packages/core/src/schema/zod-generator.ts | Adds Zod base schema handling and TS type mapping for url. |
| packages/core/src/schema/types.ts | Adds url to FieldType, FIELD_TYPES, column mapping, and repeater sub-field types. |
| packages/core/src/emdash-runtime.ts | Maps url field type to an editor/runtime kind of "url". |
| packages/core/src/api/schemas/schema.ts | Extends API schema enum validation to accept "url". |
| packages/admin/src/lib/api/schema.ts | Extends admin-side FieldType union to include "url". |
| packages/admin/src/components/FieldEditor.tsx | Adds URL to field type picker and repeater sub-field type dropdown. |
| packages/admin/src/components/ContentEditor.tsx | Adds URL field renderer and URL validation that blocks save/autosave. |
| packages/admin/src/locales/en/messages.po | Updates catalog (incl. new URL validation strings). |
| packages/admin/src/locales/zh-CN/messages.po | Updates catalog (incl. new URL validation strings). |
| packages/admin/src/locales/pseudo/messages.po | Updates catalog (incl. new URL validation strings). |
| packages/admin/src/locales/eu/messages.po | Updates catalog (incl. new URL validation strings). |
| packages/admin/src/locales/es-419/messages.po | Updates catalog (incl. new URL validation strings). |
| packages/admin/src/locales/de/messages.po | Updates catalog (incl. new URL validation strings). |
| .changeset/add-url-field-type.md | Adds a changeset entry for releasing the new url field type support. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const handleSubmit = (e: React.FormEvent) => { | ||
| e.preventDefault(); | ||
| if (hasInvalidUrls(formData)) return; |
There was a problem hiding this comment.
handleSubmit (and autosave) silently aborts when hasInvalidUrls is true, but it doesn't surface which field is invalid (and a user can hit Save without triggering onBlur, so no inline error is shown). Consider tracking invalid URL fields centrally and showing an error/toast (or triggering validation for all URL inputs) before returning so the user understands why save/autosave didn’t run.
| function getBaseSchema(type: FieldType, field: Field): ZodTypeAny { | ||
| switch (type) { | ||
| case "url": | ||
| return z.string().url(); | ||
|
|
There was a problem hiding this comment.
The admin-side URL validator (isValidUrl) enforces http(s):// and requires either localhost or a hostname containing a dot, but the server-side schema for url fields uses z.string().url() (less strict). This can lead to values being accepted via API/seed but blocked in the UI (or vice versa). Consider aligning the validation rules between client and server (either by relaxing the UI check or adding a matching refinement on the server).
* add url field type to core schema * add url field type to admin UI * update locale catalogs for url field type * add changeset
What does this PR do?
Closes #635
Adds the
urlfield type that is referenced in the docs but was missing from the code.The problem
When a seed file (refer to this example) includes a field with
"type": "url",validateSeed()rejected it as an unsupported type. The entire seed (including valid collections like posts and pages) gets silently skipped, leaving the admin empty with no collections (Posts , Pages) and no indication of what went wrong.Example collections in the seed.json file I used for testing
{ "collections": [ { "slug": "posts", "label": "Posts", "labelSingular": "Post", "supports": ["drafts", "revisions", "search", "seo"], "commentsEnabled": true, "fields": [ { "slug": "title", "label": "Title", "type": "string", "required": true, "searchable": true }, { "slug": "featured_image", "label": "Featured Image", "type": "image" }, { "slug": "content", "label": "Content", "type": "portableText", "searchable": true }, { "slug": "excerpt", "label": "Excerpt", "type": "text" } ] }, { "slug": "pages", "label": "Pages", "labelSingular": "Page", "supports": ["drafts", "revisions", "search"], "fields": [ { "slug": "title", "label": "Title", "type": "string", "required": true, "searchable": true }, { "slug": "content", "label": "Content", "type": "portableText", "searchable": true } ] }, { "slug": "links", "label": "Links", "labelSingular": "Link", "description": "The friend links", "icon": "link", "fields": [ { "slug": "homepage", "label": "The links", "type": "url", "required": true, "unique": true } ] } ] }Changes
"url"as a field type across core schema types, schema validation, editor rendering, and API input checks"URL"to the admin field type picker, content editor, and repeater sub-fields.http://orhttps://URL with a proper hostname. Blocks both save and autosave for invalid values.Output
2. URL is now a supported field that can be added to any content type:
3. URL validation on save:
CleanShot.2026-04-18.at.20.57.00.mp4
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runpnpm locale:extracthas been run (if applicable)AI-generated code disclosure
Screenshots / test output