Home
/ blog

A Perfect Blog Editor

I recently switched my personal site over to Nextjs. I had nothing more than a few posts and a landing page. I have done this like 6 times now each using a different framework none that seemed to stick. I always got to the point of finishing setup but wouldn't get to writing much. I think the issue was in the editor flow I had.

So why not Wordpress or Medium?

I know I could use something like Medium or Squarespace if I was more serious about writing. For now I just want something simple and closer to code than a marketing platform. SEO is not something I care too much about. I don't need to enable a team of content writers who know nothing of html or css let alone javascript.

What about a headless CMS?

I tried using Netlify cms in the past and it was ok. I didn't have the time to customize their editor with previews and the like. It was too much complexity. I have also used a headless cms Prismic specifically and it was ok. Again, it took far too much boilerplate and setup to get something simple. Yet again, these solutions all seemed like marketing platform options.

What do you want?!?!

Ok, so. I figured out that all I really need is markdown. Cool... Why didn't you just use that before? Well I did but it does have limits when it comes to customizing. What if I want to have some cool code snippets? Or some form of interactive bit when I am writing about code?

I know I know this sounds like I need a marketing platform but turns out all I need is mdx which is basically markdown with jsx react sugar. Delicious!

Mdx to the uhh...

So, I look and find first class support for mdx in Nextjs. Trivial right! Just add water and bam done. Money. Wrong. I ended up spending way too much time getting everything configured to work nicely. And again, maybe Medium would have been easier but I just can't bring myself yet to go to something like that. I had quite a few gotchas getting it setup.

So what was the issue?

Issues you mean? Yes there were many. First we need to get Nextjs to understand mdx files. Officially supported plugin. No issue. But wait! I already was using an image plugin. How can I use 2 plugins? Oh no! Well it is easy but NO documentation anywhere in their docs showed how to use more than 1 plugin. Maybe I am just a bit slower than the next dev but damn did it take me a long time to figure it out. So rant time.

All the examples show is a single next.config.js file with a single plugin export like so

const withPlugin = require("a-plugin");
module.exports = withPlugin();

Note we process this file before webpack/babel so cannot use all es6 features. Ok, simple. So how do we do two? Their documentation does not say how...it has some examples on hooking into the webpack config and adding it there but it seemed way too involved for something so simple. And well...it was. So how do we get two plugins?

const withA = require("a");
const withB = require("b");
module.exports = withA(withB());

😑 This seriously makes me question if I am just an idiot. I guess I should have seen that this was the pattern after looking at the previous example for a single plugin but I just couldn't find anything that used more than one. I finally looked at the source and finally found my exact question (and answer) in an old issue on github.

Cool, now it all works...WRONG!

Not so static...

I picked Nextjs primarily because of their simple routing for both frontend and backend apis. This would let me easily standup basic little apps without much fuss. It honestly is really cool. However, it is geared at static/SSR apps. Since I am not using a headless cms and will just have a bunch of mdx files this presents complexity.

I want a single page at pages/blog/[slug].js to simply take a slug and spit out the content. If the slug doesn't have a mdx file, give a 404. Easy. Kinda. Dynamic imports are kinda cumbersome. Nextjs has a dynamic function you import and can use. It isn't bad. Now we could technically prerender all of these posts as they are just mdx files which I may add later but for now I just want to dynamically load them. Overall, it almost worked on the first try. Nice. What didn't work?

So that part about what happens if we don't find a matching mdx file with the url slug. Well we need to know if it isn't found to redirect. And once again, Nextjs' dynamic import could easily give this to us if...their docs let us know that. You see the dynamic import provides config options. One of these is a loading render component we can provide. Now they say this component is displayed while waiting for the dynamic component to be loaded. What they don't say or show an example of is how we know if there was an error. How is this done? That loading component has an error prop passed in... Yup. That easy. How did I know this? Source code and just spitting out the props they give us on a hunch they have info there. :sigh:

No previews...

Last little issue which just is kinda a sad bit is that the mdx preview for vscode doesn't work for me. This is likely because I am using absolute imports with Nextjs as they are cleaner IMO.

Update here is that I did get much of it working with only a few gotchas. Indeed I do have to use relative imports. Another is that plugins will not work since they are setup in Nextjs config and not the vscode preview extension I am using. This isn't much of an issue since the reload time on save is so fast.

After all that huh?

Yup a whole lot of work to get something so simple. But! I now can just drop in any jsx here. I mean.

This is jsx

That is cool. And check this out. This is me dropping in another page/project I did inline. Just a little css page wishing a friend a happy birthday.

KEVIN!
21?
molecule backgroundmolecule backgroundmolecule background
test tubetest tube

Sure there are likely some formatting issues but still this is really cool. What is even cooler is that I adjusted the styling slightly using Nextjs' awesome style jsx tags. I had to put a global on it so the styling wouldn't be scoped.

This is the exact jsx for the above.

<div className="example-jsx">
  <style jsx global>{`
    .example-jsx > .page-container {
      width: auto;
    }
    .example-jsx {
      margin: 1rem 0;
    }
  `}</style>
  <Nardi />
</div>

Really? Why not Gatsby or something if you just wanted markdown with React?

Exactly! I have used gatsby once and the graphql was too much boilerplate. I know JAMstack is big and all which is why I am using Nextjs. Nextjs just left more open to me I think. Maybe I will try yet another framework out. I mean Vue is cute and Nuxt.js is even cuter...someone help me. 😅

Conclusions?

I really need to stop redoing my website with different frameworks and just write more. I also should probably start joining some discord servers or something for the frameworks I use. Likely would get answers far faster that way than digging into source code.

However this is exactly the flow I want. Markdown simplicity with the option of adding full react where ever I want.

Note this is an outstanding article that helped me with getting plugins working easily. https://dev.to/whoisryosuke/using-mdx-with-nextjs-and-when-to-go-gatsby-5e4c

TODOS

And here is a link to go home in jsx!

ET - home

Niffty