I have a custom post type that is configured to use a permalink structure prepended with the post type name. When using get_permalink(), the URL that is returned does not include the post type name. This is virtually identical to the scenario described in this question.

register_post_type('activity', [
  'public' => true,
  'rewrite' => [
    'slug' => 'activities',
    'with_front' => true,

The permalink should take the form http://example.com/activities/the-activity-title, whereas get_permalink() returns http://example.com/the-activity-title.

Usually, WordPress does a pretty good job of guessing the correct post that should be displayed, and redirects the former to the latter. However, if the post is set to be private, that first URL results in a 404, even though the second URL is visible to the logged in user.

  1. Is it normal for get_permalink() to omit the post type slug from the URL it returns, resulting in a redirect? If not, what's causing it?
  2. If it is normal, how can I fix the 404 so it also redirects for logged in users?

The code I'm working with is all defined in a custom plugin. The register_post_type() snippet above is called by an init hook action, while the problem get_permalink() calls are in the plugins_loaded hook action.

The author of the question linked above states that his issues was caused by querying the permalink before the post type had been registered. Are the hooks I'm using in my code sufficient to avoid this cause?

  • Haven't fully delved yet, but I wonder if, instead of the public attribute, you need to configure the more fine-grained attributes, like show_in_nav_menus, show_ui, exclude_from_search, publicly_queryable. I bet that's not the full story, though. Apr 4, 2019 at 17:55
  • I am already using the public attribute in my register_post_type() call, and it is set to true. However, I'm talking about setting an individual post's visibility using the Visibility option in the edit post page of the admin area. Some posts of this post type will be public and some will be private. The ones set to private are causing the issue described above. Apr 4, 2019 at 22:38
  • I've added 'public' => true to my question to improve clarity. Apr 4, 2019 at 22:40

1 Answer 1


My problem was indeed the same as in the question I linked, in that the get_permalink() call was happening before the post type was registered. I confirmed this when trying to write a work-around that used get_post_type_object(), which worked fine in functions.php but returned null when moved into my plugin.

By referring to the action reference page in the WordPress documentation (which, although it doesn't mention it, is sorted by the firing sequence of the actions) I could see that the action I was using to get the permalink, init is fired after the one I was using for registering the post type, plugins_loaded.

By moving the code using get_permalink() to the init action, I was able to fix the problem, and now the correct URLs are being returned, with the post type slug as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.