WordPress URLs ending in .html

I think the issue is because we are using the init function, which doesn’t guarantee that the libraries from other packages have been initialized. In this case the handlers from wp-source.

In Frontity, the packages are initialized in the order they are defined in the frontity.settings.js file. In the case of the default mars-theme, the theme is before the wp-source package. This means that when we call the init function of the theme, the handlers don’t exist yet.

There are two easy ways of solving this:

export default {
  actions: {
    myPackage: {
      beforeSSR: ({ libraries }) => {
        libraries.source.handlers.map((handler) => {
          handler.pattern += "(\\.html)?";
          return handler;
        });
      },
    },
  },
};

  • Move the wp-source package to the top of the frontity.settings.js file so it is initialized before the theme.

I’ve tested both and they seem to work fine for me, but I guess that using beforeSSR is safer.

Could you please test if this works for you as well @hsbas ? :slightly_smiling_face:

1 Like

Hi,

I guess I didn’t understand exactly where to use these actions. When I check “frontity.libraries.source.handlers” value at the console, I don’t see handlers ending with “.html”.

For mars-theme, can you tell me where I should place this action you’ve sent?

For mars-theme, can you tell me where I should place this action you’ve sent?

Sure! In the case of the default mars-theme I think you could edit the index.js file. This could be it:

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

const marsTheme = {
  name: "@frontity/mars-theme",
  roots: {
    /**
     * In Frontity, any package can add React components to the site.
     * We use roots for that, scoped to the `theme` namespace.
     */
    theme: Theme,
  },
  state: {
    /**
     * State is where the packages store their default settings and other
     * relevant state. It is scoped to the `theme` namespace.
     */
    theme: {
      autoPrefetch: "in-view",
      menu: [],
      isMobileMenuOpen: false,
      featured: {
        showOnList: false,
        showOnPost: false,
      },
    },
  },

  /**
   * Actions are functions that modify the state or deal with other parts of
   * Frontity like libraries.
   */
  actions: {
    theme: {
      toggleMobileMenu: ({ state }) => {
        state.theme.isMobileMenuOpen = !state.theme.isMobileMenuOpen;
      },
      closeMobileMenu: ({ state }) => {
        state.theme.isMobileMenuOpen = false;
      },
      beforeSSR: ({ libraries }) => {
        libraries.source.handlers.map((handler) => {
          console.log(handler.pattern);
          handler.pattern += "(\\.html)?";
          return handler;
        });
      },
    },
  },
  libraries: {
    html2react: {
      /**
       * Add a processor to `html2react` so it processes the `<img>` tags
       * and internal link inside the content HTML.
       * You can add your own processors too.
       */
      processors: [image, iframe, link],
    },
  },
};

export default marsTheme;

2 Likes

Yes, I did it the same way. But for some reason, nothing changed:

Oh, I see. I just checked that the post was loading correctly in SSR.

With the second option I suggested, using the init function instead of beforeSSR, but moving the wp-source package before the mars-theme package in the frontity.settings.js file, it seems to appear also in the console. Did that work for you?

@luisherranz Do you know the pros and cons of each approach? Should we go back to initial idea of modifying the pattern in wp-source directly?

In this case, it works for the first page. But the same problem occurs when I surf between pages and refresh.

You’re right. I’ve noticed that it only works for the latest post. The older ones don’t work in SSR with these solutions. I’ve written what I found in the issue to keep researching the issue there.

The ending .html is not the only change to the URLs of that site. It also contains the post id and the slug is not complete, so it can’t be used.

I have made a video to explain a possible solution. It also contains the configuration for the tags and categories.

This is the init function:

init: ({ libraries }) => {
  const { handlers } = libraries.source;
  const postTypeHandler = handlers.find((h) => h.name === "post type");
  const tagHandler = handlers.find((h) => h.name === "tag");
  const categoryHandler = handlers.find((h) => h.name === "category");

  // Configure the post type URLs.
  postTypeHandler.pattern = "/(.*)?/:slug-:id(\\d+).html";
  postTypeHandler.priority = 20;

  // Add tag + category handler.
  handlers.push({
    name: "category + tag",
    priority: 30,
    pattern: "/:slug",
    func: async (...args) => {
      try {
        await tagHandler.func(...args);
      } catch (e) {
        await categoryHandler.func(...args);
      }
    },
  });
};

It wouldn’t work as it is because it would require that our postTypeHandler checks if there is a params.id and use that instead of the params.slug to retrieve the content from the REST API. But I think a change like that would make sense. It is also explained in the video.

The code would be something like this:

const apiParams = { _embed: true, ...state.source.params };
params.id ? (apiParams.include = params.id) : (apiParams.slug = params.slug);

const response = await libraries.source.api.get({
  endpoint,
  params: apiParams,
});

EDIT: @hsbas how are the URLs of the pages? They also need /:slug?

1 Like

Can i use this one code for only pages ?

Thank you.

Sure, you can add a custom handler for your pages :slightly_smiling_face:

Docs: @frontity/wp-source - API Reference

Hi @all ,

I have created code for pages. we can use below code for .html pages.

init: async ({ libraries }) => {
const { handlers } = await libraries.source;
//const postTypeHandler = handlers.find((h) => h.name === “post type”);
libraries.source.handlers.push({
name: “post type”,
priority: 20,
pattern: “/(.*)?/:slug.html”, // post or page or attachment
func: postTypeHandler({
// Those are the default endpoints plus “product”
endpoints: [“pages”],
}),

We can use this one code for pages and add in index.js file.

1 Like

Hi @all

I have used above code .html link for pages then link is working fine. but i have faced after url slash.(.html/)

So can you please help me how we remove / after url.

Thanks.