Reflections on moving the blog from gatsby to frontity

I’m in the process of moving my blog and personal site from gatsby to frontity: https://czaplinski.io

While doing it, I’ve collected some notes on things that we might improve:

  • I think that we could create a very barebones “hello-world” theme which has just 1 component and no configuration. I think this would help users to understand what is the “baseline” for a fronity app. Especially for someone used to create-react-app or next or gatsby, this could make more sense initially.

  • When running npx frontity create and asking the user to select a theme we should probably explain in one sentence what a theme is! For many JS developers who have used gatsby or next.js this is something completely new and they might not understand why they need to select a theme!

    We should say that you should use mars or 2020 if you already have a WP instance and that you want to see how it would look like with a frontity theme. And you could use a “barebones” theme if you have a completely green field and just want to see what the simplest possible app looks like.

  • We should ask the user to add the api endpoint as a question in the CLI (JuanMa has actually mentioned it already in Add WP REST API url directly from command line when "frontity create")

  • Maybe we could always add the packages:

    "@frontity/tiny-router",
    "@frontity/html2react",
    

    by default and with default settings so that we do not need to specify them in the frontity.settings.js for a basic theme. This way, we only have the theme and wp-source defined in the frontity.settings.js, which is the absolute minimum.

    A more advanced user could always override them with e.g. a specific beforeSSR() action if they want. I think it would be less overwhelming to a first time user who doesn’t need to configure html2react and tiny-router right away.

  • Similarly to the previous point, I think we should add the image and iframe processor by default and only require the user to specify a libraries property in the index.js of the theme if they want to add new libraries / extend existing ones. Like:

    const marsTheme = {
       // ...roots
       //...state
       //...actions
    
        // Make specifying this optional
        libraries: {
          html2react: {
            processors: [image, iframe],
          },
        },
    };
    
  • We should add more comments to the frontity.settings.js & the index.js generated by default by the CLI with some more information about the purpose of each setting, some examples:

    • explain why all the code is under packages.
    • explain what is mars-theme and that it’s like a “starter” theme in WordPress.
    • explain what is the purpose of the wp-source package in the frontity.settings.js
    • explain that the settings, state & actions in index file are merged with the ones in frontity.settings.js

This is not a complete list (because I’m not done with migrating :sweat_smile:) so I ll add to it as I go along.

5 Likes

Great suggestions @mmczaplinski.

@juanma has already created a couple of issues in the docs repo(https://github.com/frontity/docs/issues/154, https://github.com/frontity/docs/issues/153) and I’m sure that @SantosGuillamot will also take a look at this in the next weeks.

1 Like

Really nice feedback @mmczaplinski :slightly_smiling_face:

Do you mean extending this message and explaining a bit there what a theme is before asking to select one? Would it be just changing that message?

As far as I know, the framework is designed to be as hackable as possible so if people don’t want to use tiny-router and they want to use another router they are able to do so right? I mean, in Frontity, if I’m not mistaken, you always need at least three packages: one for the theme, one for the source and one for the router. Even though there is just one package for the source (wp-source) and one for the router (tiny-router). I feel it isn't a problem you have at least that packages in your frontity.settings.js`.

Also, I can imagine some users that don’t want to use html2react if it’s not needed for their case, so they can just remove it from the frontity.settigns.js. Apart from that, both packages are included directly in the frontity.settings.jsafter doingfrontity create` right?

I asked these questions because I’d like to understand better the pros and cons of one approach or the other.

Do you mean in the official themes? Adding them by default in mars-theme and the twentytwenty-theme? How would it work if users don’t want to use the image processor?

Btw, if the discussion keeps growing let’s start a new topic for each of them.

yup, exactly. Add more info about what a theme is and why you need to choose one. and a link to our docs. This mostly geared towards JS developers because in every other popular CLI tool like create-react-app, gatsby-cli or next there is nothing like that. I know that to WP developers it’s more obvious, but not to JS devs :slight_smile: . So, I’d say something like:

? Pick a starter theme to clone: (Use arrow keys)
❯ @frontity/mars-theme (recommended)
  @frontity/twentytwenty-theme
  
  A theme in Frontity is analogous to a theme in WordPress but built
  with JS and react! Each frontity site is built as a theme.
  If you're still unsure, just go with the recommended mars-theme :) 
  For more info: <link to docs>

You’re right @SantosGuillamot that we want frontity to remain as hackable as possible :slight_smile:

At the same time, I’d like to see if it’s possible to keep that philosophy and make it as friendly to beginners as possible! :slight_smile:

I’m quite conviced that even the basic frontity.settings.js included in the mars-theme is too long and unclear to a new user:

const settings = {
  name: "frontity-test-project",
  state: {
    frontity: {
      url: "http://czapla.local/",
      title: "Test Frontity Blog",
      description: "WordPress installation for Frontity development",
    },
  },
  packages: [
    {
      name: "@frontity/mars-theme",
      state: {
        theme: {
          menu: [
            ["Home", "/"],
            ["Nature", "/category/nature/"],
            ["Travel", "/category/travel/"],
            ["Japan", "/tag/japan/"],
            ["About Us", "/about-us/"],
          ],
          featured: {
            showOnList: false,
            showOnPost: false,
          },
        },
      },
    },
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          api: "http://czapla.local/wp-json",
        },
      },
    },
    "@frontity/tiny-router",
    "@frontity/html2react",
  ],
};

It’s not clear that which of those settings are:

  • required by frontity (like specifying the router, source and theme packages)
  • required by the theme (html2react, because without it we cannot use the processors)
  • generally optional (e.g. the state.theme.menu, because it could just be hardcoded instead).

My proposal would be to simplify the settings.frontity.js so that we only put the required and necessary settings/state there in our starter themes. For example, I imagine the most minimal settings.frontity.js could look like this:

const settings = {
  name: "frontity-test-project",
  state: {
    frontity: {
      url: "http://czapla.local/",
      title: "Test Frontity Blog",
      description: "WordPress installation for Frontity development",
      wordpressUrl: "http://czapla.local/wp-json" // According to the new proposal for global backend url : )
    },
  },
  packages: [ "@frontity/mars-theme" ]
  // no other packages because tiny-router and wp-source
  // are always included 
};

Then, because the framework is hackable, we should allow the user to replace the router or source by specifying it under the key:

const settings = {
  name: "frontity-test-project",
  state: {
    frontity: {
      url: "http://czapla.local/",
      title: "Test Frontity Blog",
      description: "WordPress installation for Frontity development",
      wordpressUrl: "http://czapla.local/wp-json" // According to the new proposal for backendUrl : )
    },
  },
  router: differentRouterImplementation,
  source: otherSourcePackage,
  packages: [
    "@frontity/mars-theme"
    "@frontity/html2react",
    // You can still put all other packages here
  ]
};

This way, it’s clear that router and source packages are “special” and have to always be present, but can also be modified.

This would also be backwards-compatible, because the setting in the router and source could take precedence

Finally, (And I have a slightly less strong opinion about this) - I think I would remove the menu from the state.theme because I think that it’s not the best illustration of what we want to use the frontity state for. We also don’t want to suggest that it’s necessary to put your menu in the state and it’s not clear that this is NOT the case. It’s just one possible solution and it adds more noise in to the frontity.settings.js file IMO.

Of course, I understand that it was put there so that the user can “discover” that they can put their state in state.theme but I’d rather have it hardcoded and use another example to show users how to use frontity state.

(I can split this into separate topic if you agree and we should make more formal proposals) :slight_smile:

Hey @mmczaplinski, glad to hear you’re thinking about this :slightly_smiling_face:

Regarding that, I’d like to keep packages “not special” by any means. The less hardcoded we make the core, the more flexible and powerful it’ll be. For that reason, both the router and the source are packages like any other. Even themes are regular packages. To replace the need for hardcoded packages, we have “official namespaces”. But the core doesn’t know about them and that is good.

I’ve been also thinking how to simplify the “package requirements” for the user. My idea to solve that is to give packages a way to declare their namespace needs. I think we should introduce a dependency system for packages at some point that solves this problem. I have briefly outline an idea at the end of this post: Create an index of "frontity" packages. With something like that it’d be possible to have the simpler frontity.settings.js file you shared, while not hardcoding anything and letting the user replace some of the requirements for alternatives, like for example using a different source package.