Skip to content

Slug query returns null when post_name is stored as percent-encoded (non-ASCII slugs: Korean, Japanese, etc.) #3582

@cheonmux

Description

@cheonmux

Description

When WordPress stores post_name (slug) in percent-encoded form (e.g. %eb%b2%a0%ed%8a%b8%eb%82%a8-%ed%8e%b8%ec%9d%98%ec%a0%90 instead of 베트남-편의점), all slug-based queries return null.

Expected: Querying by slug (decoded or encoded) should return the post.
Actual: All slug-based query methods return null. Only DATABASE_ID works.

The WP REST API handles this correctly — GET /wp-json/wp/v2/posts?slug=%eb%b2%a0%ed%8a%b8%eb%82%a8-%ed%8e%b8%ec%9d%98%ec%a0%90 returns the post successfully.

This affects any non-ASCII language where WordPress stores slugs in percent-encoded form (Korean, Japanese, etc.).

Steps to reproduce

  1. Create a WordPress post with a non-ASCII title (e.g. Korean: 베트남-편의점)
  2. WordPress generates a percent-encoded slug stored in wp_posts.post_name as %eb%b2%a0%ed%8a%b8%eb%82%a8-%ed%8e%b8%ec%9d%98%ec%a0%90
  3. Confirm the post is retrievable via REST API:
   GET /wp-json/wp/v2/posts?slug=%eb%b2%a0%ed%8a%b8%eb%82%a8-%ed%8e%b8%ec%9d%98%ec%a0%90
   → Returns the post (works)
  1. Query via GraphQL — all return null:
   # Decoded Korean slug
   { post(id: "베트남-편의점", idType: SLUG) { databaseId title } }
   # → null

   # Percent-encoded slug (lowercase)
   { post(id: "%eb%b2%a0%ed%8a%b8%eb%82%a8-%ed%8e%b8%ec%9d%98%ec%a0%90", idType: SLUG) { databaseId title } }
   # → null

   # Percent-encoded slug (uppercase)
   { post(id: "%EB%B2%A0%ED%8A%B8%EB%82%A8-%ED%8E%B8%EC%9D%98%EC%A0%90", idType: SLUG) { databaseId title } }
   # → null

   # URI
   { post(id: "/베트남-편의점/", idType: URI) { databaseId title } }
   # → null

   # nodeByUri
   { nodeByUri(uri: "/베트남-편의점/") { ... on Post { databaseId title } } }
   # → null

   # postBy
   { postBy(slug: "베트남-편의점") { databaseId title } }
   # → null

5/ Only DATABASE_ID works:


   { post(id: "29099", idType: DATABASE_ID) { databaseId title slug } }
   # → Returns: { databaseId: 29099, title: "...", slug: "베트남-편의점" }

Additional context

WPGraphQL returns the slug in decoded form ("slug": "베트남-편의점") when queried by DATABASE_ID, yet cannot find the same post when that exact slug is used as input for idType: SLUG.

GraphiQL IDE result:

{

"data": {

"test_slug": null,

"test_id": {

"databaseId": 29099,

"title": "다낭, 나트랑 및 베트남 지역별 편의점 완전 가이드",

"slug": "베트남-편의점"

}

}

}

The root cause appears to be that WPGraphQL does not apply urldecode() when comparing the input slug against the DB-stored post_name. The WP REST API handles this correctly.

WPGraphQL Version

2.9.0

WordPress Version

6.9.1

PHP Version

8.2.27

Additional environment details

Local development environment: Local by Flywheel (macOS)

No additional WPGraphQL extensions installed.

WordPress permalink structure: /%postname%/

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have disabled ALL plugins except for WPGraphQL.

  • Yes
  • My issue is with compatibility with a specific WordPress plugin, and I have listed all my installed plugins (and version info) above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    🆕 New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions