plym Docs
    plym.io

    Categories

    Learn how to categorize posts, arrange them in order, and group them under one path using Categories.

    Updated Aug 04, 2026

    On this page

    A category is a flat label with a name, a slug derived from that name, and an optional weight. There is no nesting and no per-post override: a post belongs to at most one category, and every post is offered the same list. Unlike a tag, a category changes the post's URL. Use a category when the path should say where a post lives, and tags for every other label.

    Create a category

    1. Open Categories in the sidebar.
    2. Click New category.
    3. Type a name, up to 64 characters. plym derives the slug: Getting Started becomes getting-started.
    4. Set Weight, or leave it blank.
    5. Click Add category.

    You cannot type the slug. Rename the category to change it.

    The API does the same thing:

    curl -X POST http://localhost:9173/api/categories \
      -H "Authorization: Bearer $PLYM_TOKEN" \
      -H 'Content-Type: application/json' \
      -d '{"name": "Getting Started", "weight": 10}'
    {"id": 4, "name": "Getting Started", "slug": "getting-started", "weight": 10}

    Assign a category to a post

    Pick one from Category in the editor sidebar. The default is Uncategorised, which serves the post at the blog root.

    path is the blog-root-relative URL and rendered_path is the file plym wrote for it. The category_id for Uncategorised posts is null.

    Categories are global

    A category exists once, for the whole site. There is no way to scope one to a section, an author, a template, or a user.

    Two consequences follow. Renaming a category rewrites the URL of every published post in it, and deleting one is blocked while any post still uses it.

    Weight

    Weight orders the category list, lowest first. Categories with no weight sort last, alphabetically by name.

    It orders the Categories screen and the GET /api/categories response. Weight changes no URL, and the bundled template renders no category listing, so on a default install it has no visible effect on the public site. A custom template reads post.category.weight from the render context and can group and order with it.

    Paths change with the category

    Assigning, changing, or clearing a category on a published post moves its URL immediately. plym deletes the old rendered file and writes a new one at the new path.

    Change Previous URL URL after the change
    Publish introduction, uncategorised /introduction
    Assign Getting Started /introduction returns 404 /getting-started/introduction
    Rename to Quickstart /getting-started/introduction returns 404 /quickstart/introduction
    Clear the category /quickstart/introduction returns 404 /introduction

    plym issues no redirect. The previous URL returns 404 the moment the move completes — not a 301, not a 308. Every inbound link, bookmark, and indexed result pointing at the old path breaks. This is architecture decision (partly due to SEO) and not a technical limitation.

    Treat a category change on a published post as a URL change. Update your internal links, set the old URL as a redirect at your CDN or reverse proxy if the traffic matters, and let search engines re-crawl /sitemap.xml, which already lists the new path.

    Draft posts have no rendered file, so moving them between categories costs nothing. Categorise before you publish where you can.

    Rules

    Rule Failure
    Names are unique 409 categories.conflict
    A category slug may not equal an existing post slug 409 categories.conflict
    A name may not resolve to a reserved segment: admin, api, health, mcp, media, page, plym-admin, plym-docs, static, webfonts 400 categories.reserved_name
    A name must have a URL-safe form 400 categories.invalid_name
    A category with posts assigned cannot be deleted 409 categories.in_use

    The last rule has no override. Reassign or delete every post in a category before you delete the category itself; the error message tells you how many are left.

    FAQ

    Can I move 200 posts into a category at once? Not in one call. PATCH /api/posts/{id} takes one post at a time; loop over the ids. Each published post is re-rendered as it moves.

    Frequently asked questions

    Can a post have two categories?
    No. Categories are supposed to act as folders. If you want to annotate your post with multiple labels, use tags.
    Can I change or update category of a draft post?
    Yes, and that's the intended behaviour. Draft posts are never rendered to disk, and hence have no URLs.
    Can a category have a non-Latin name?
    Yes, a slug is transliterated to ASCII, so `日本語` becomes `ri-ben-yu`.