How to remove category prefix from category URLs?

Hey everyone,

is it possible to remove the category prefix from my URLs (for category archives)? I know it’s possible to set state.source.categoryBase, but I would like to remove it completely. Background is that I use Yoast to remove the prefix from the category pages. If I leave categoryBase empty, it says post type from endpoints "posts,pages,media" with slug "mycategory" not found.

Thank you!

Hey @cobra,

The problem you are finding is that once you are not using categoryBase at all, the url of your categories are matching the pattern "/(.*)?/:slug" , which is assigned to the postType handler.

You could try to create a new handler, at the index.js of your theme, with the same pattern but a higher priority where you try the function of the category handler and if it returns an error try the postType. This means it will make a REST API call to check if that slug exists as a category and if not, make the REST API calls for postType. It should be something similar to this:

import Theme from "./components";
import image from "@frontity/html2react/processors/image";

const newHandler = {
  name: "categoryOrPostType",
  priority: 19,
  pattern: "/(.*)?/:slug", 
  func: async ({ route, params, state, libraries }) => {
    // 1. try with category.
    try {
      const category = libraries.source.handlers.find(
        handler => handler.name == "category"
      );
      await category.func({ route, params, state, libraries });
    } catch (e) {
      // It's not a category
      const postType = libraries.source.handlers.find(
        handler => handler.name == "post type"
      );
      await postType.func({ route, params, state, libraries });
    }
  }
};
const marsTheme = {
  name: "@frontity/mars-theme",
  roots: { ... },
  state: { ... },
  actions: { ... },
  libraries: {
    source: {
      handlers: [newHandler]
    },
    ...
  }
};
export default marsTheme;

Please, let us know if you finally make it work or if there’s anything else where we can help.

1 Like

I just tried implementing this and noticed an error with your example code. Unlike the taxonomy handler, which can accept the prop route (https://github.com/frontity/frontity/blob/83c5eadb4dffc6275fe4d93b8d379c21449a2727/packages/wp-source/src/libraries/handlers/taxonomy.ts#L21), the postType handler does not support this and expects a link param only (https://github.com/frontity/frontity/blob/83c5eadb4dffc6275fe4d93b8d379c21449a2727/packages/wp-source/src/libraries/handlers/postType.ts#L9).

The result is the categories working but postTypes failing.

My corrected snippet would be (note: link: route):

import Theme from "./components";
import image from "@frontity/html2react/processors/image";

const newHandler = {
  name: "categoryOrPostType",
  priority: 19,
  pattern: "/(.*)?/:slug", 
  func: async ({ route, params, state, libraries }) => {
    // 1. try with category.
    try {
      const category = libraries.source.handlers.find(
        handler => handler.name == "category"
      );
      await category.func({ route, params, state, libraries });
    } catch (e) {
      // It's not a category
      const postType = libraries.source.handlers.find(
        handler => handler.name == "post type"
      );
      await postType.func({ link: route, params, state, libraries });
    }
  }
};
const marsTheme = {
  name: "@frontity/mars-theme",
  roots: { ... },
  state: { ... },
  actions: { ... },
  libraries: {
    source: {
      handlers: [newHandler]
    },
    ...
  }
};
export default marsTheme;
1 Like

A further update on this. If you set the priority of this handler to 19 it will override the tag and author endpoints and give you a 404. If you set it to 30 all should run smoothly.

1 Like

Thanks for your help, however where exactly in the file should i add this code or replace?

And one last question, if i am using another theme, what to change exactly in the code? i will use Chakra theme.

You can follow Santos’ instructions at the top and place it in your index.js of your theme.

I have implemented it but now when I try to access category URL directly it throws internal server error.
Go home page > click category link works fine.
Open directly category link doesn’t work for some categories.

Here is the example
https://divaksh.com/java/ Works fine directly and from the home page.
https://divaksh.com/git/ Works only from the frontity links, doesn’t work on direct access.

Smilarly
https://divaksh.com/c/ Works fine directly and from the home page.
https://divaksh.com/http/ Works only from the frontity links, doesn’t work on direct access.

This is what I get in console when I try to access https://divaksh.com/git/

  TypeError: Cannot read property '32' of undefined
      at Header (webpack-internal:///./packages/forgotten-developer/src/components/header.js:11:392)
      at runAsReaction (webpack-internal:///./node_modules/@frontity/connect/src/reactionRunner.js:16:45)
      at reaction (webpack-internal:///./node_modules/@frontity/connect/src/observer.js:7:131)
      at eval (webpack-internal:///./node_modules/@frontity/connect/src/connect.js:21:16)
      at processChild (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:397:2319)
      at resolve (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:396:122)
      at ReactDOMServerRenderer.render (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:433:1199)
      at ReactDOMServerRenderer.read (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:433:55)
      at renderToString (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:470:116)
      at eval (webpack-internal:///./node_modules/@frontity/core/src/server/index.tsx:68:243)

This is what I get in console when I try to access https://divaksh.com/http/

  TypeError: Cannot read property '39' of undefined
      at Header (webpack-internal:///./packages/forgotten-developer/src/components/header.js:13:35)
      at runAsReaction (webpack-internal:///./node_modules/@frontity/connect/src/reactionRunner.js:16:45)
      at reaction (webpack-internal:///./node_modules/@frontity/connect/src/observer.js:7:131)
      at eval (webpack-internal:///./node_modules/@frontity/connect/src/connect.js:21:16)
      at processChild (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:397:2319)
      at resolve (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:396:122)
      at ReactDOMServerRenderer.render (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:433:1199)
      at ReactDOMServerRenderer.read (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:433:55)
      at renderToString (webpack-internal:///./node_modules/react-dom/cjs/react-dom-server.node.development.js:470:116)
      at eval (webpack-internal:///./node_modules/@frontity/core/src/server/index.tsx:68:243)

Hi @Divaksh

In header.js line 11

const post = state.source[data.type][data.id];

returns undefined.

When you remove this line, and of course the reference to post in line 50, then all the category links work on direct access.

This removes the heading from the single post page though doesn’t seem to affect the list pages, but hopefully this will give you a clue in tracking down the problem.

1 Like

Thank you, it helped; :slight_smile: I have fixed the issue. I just removed the line 11 and updated line 50.

2 Likes

This was helpful I was getting following error

ServerError: You have tried to access content at route: undefined/ but it does not exist
    at Object.eval [as func] (postType.ts?e855:97)
    at async Object.func (index.js?35f5:23)
    at async eval (actions.ts?f1c8:132)

It got corrected with your solution.