Skip to content

fix: add missing url field type#648

Merged
ascorbic merged 4 commits into
emdash-cms:mainfrom
CacheMeOwside:fix/635
Apr 19, 2026
Merged

fix: add missing url field type#648
ascorbic merged 4 commits into
emdash-cms:mainfrom
CacheMeOwside:fix/635

Conversation

@CacheMeOwside

Copy link
Copy Markdown
Contributor

What does this PR do?

Closes #635

Adds the url field 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.

CleanShot 2026-04-18 at 20 19 57@2x CleanShot 2026-04-18 at 20 21 30@2x

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

  • Added "url" as a field type across core schema types, schema validation, editor rendering, and API input checks
  • Users who don't use seed files, would have no way to create a URL field. Since the doc says url is a supported field type, I have added "URL" to the admin field type picker, content editor, and repeater sub-fields.
  • Added client-side validation on blur that requires a valid http:// or https:// URL with a proper hostname. Blocks both save and autosave for invalid values.

Output

  1. The collection gets added successfully:
CleanShot 2026-04-18 at 20 47 37@2x

2. URL is now a supported field that can be added to any content type:

CleanShot 2026-04-18 at 20 48 01@2x

3. URL validation on save:

CleanShot.2026-04-18.at.20.57.00.mp4



Type of change

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

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation and pnpm locale:extract has been run (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

@changeset-bot

changeset-bot Bot commented Apr 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 357c257

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

This PR includes changesets to release 10 packages
Name Type
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/admin 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

@github-actions

Copy link
Copy Markdown
Contributor

Scope check

This 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.

@github-actions

github-actions Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
packages/admin/src/locales/ar/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/de/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/en/messages.po Source changed, localizations will be marked as outdated.
packages/admin/src/locales/es-419/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/eu/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/fr/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/ja/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/ko/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/pseudo/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/pt-BR/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/zh-CN/messages.po Localization changed, will be marked as complete.
packages/admin/src/locales/zh-TW/messages.po Localization changed, will be marked as complete.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@CacheMeOwside CacheMeOwside changed the title Fix/635 fix: add missing url field type Apr 18, 2026
@pkg-pr-new

pkg-pr-new Bot commented Apr 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

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

@emdash-cms/auth

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

@emdash-cms/blocks

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

@emdash-cms/cloudflare

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

emdash

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

create-emdash

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

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

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

@emdash-cms/x402

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

@emdash-cms/plugin-ai-moderation

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

@emdash-cms/plugin-atproto

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

@emdash-cms/plugin-audit-log

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

@emdash-cms/plugin-color

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

@emdash-cms/plugin-embeds

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

@emdash-cms/plugin-forms

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

@emdash-cms/plugin-webhook-notifier

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

commit: 357c257

@github-actions

Copy link
Copy Markdown
Contributor

Overlapping PRs

This PR modifies files that are also changed by other open PRs:

This may cause merge conflicts or duplicated work. A maintainer will coordinate.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment on lines 414 to +416
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (hasInvalidUrls(formData)) return;

Copilot AI Apr 19, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 54 to +58
function getBaseSchema(type: FieldType, field: Field): ZodTypeAny {
switch (type) {
case "url":
return z.string().url();

Copilot AI Apr 19, 2026

Copy link

Choose a reason for hiding this comment

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

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).

Copilot uses AI. Check for mistakes.

@ascorbic ascorbic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks!

@ascorbic ascorbic merged commit ada4ac7 into emdash-cms:main Apr 19, 2026
32 checks passed
@emdashbot emdashbot Bot mentioned this pull request Apr 19, 2026
0aveRyan pushed a commit to 0aveRyan/emdash that referenced this pull request Apr 27, 2026
* add url field type to core schema

* add url field type to admin UI

* update locale catalogs for url field type

* add changeset
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.

The "url" field type is missing.

3 participants