Skip to content

v1.0.0-alpha.37 - Custom Routes using `makeRoutes` API

Pre-release
Pre-release
Compare
Choose a tag to compare

One of the common usecase in a Static-Site-Generator is to use content from sources like Hashnode, Dev.to, Medium or anywhere else.

In most static-site-generators, you need a source plugin to achieve this. So every source requires a different source plugin. Every plugin comes with their own implementation and API and documentation. This can become complicated and the static-site-generators have to wait for the plugin ecosystem to develop in order to be usable.

This is how it was in Abell v0 too where we had to build source plugins for different sources.

Abell v1 comes with a philosophy that things should be intuitive and there should not be magic abstractions. Having source-plugins break this idea.

Introducing an alternate way to provide a source with makeRoutes API in entry.build.ts 🎉

Here's an example of fetching the first article from dev.to and rendering it on /blog/hello-blog path-

// src/entry.build.ts
import fetch from 'isomorphic-unfetch';
import { Route } from 'abell';
import index from './index.abell';
import blog from './blog.abell';

const fetchFirstArticle = async () => {
  const articles = await fetch(`https://dev.to/api/articles?username=saurabhdaware`).then(res => res.json());
  const blog: Record<string, any> = await fetch(`https://dev.to/api/articles/${articles[0].id}`).then(res => res.json());
  const { body_html } = blog;
  return body_html;
}

export const makeRoutes = async (): Promise<Route[]> => {
  const articleContent = await fetchFirstArticle();

  return [
    {
      path: '/',
      render: () => index()
    },
    {
      path: '/blog/hello-blog',
      render: () => blog({blogContent: articleContent})
    }
  ]
}
<!-- blog.abell -->
<html>
<body>
  <nav>blog navbar</nav>
  {{ props.blogContent }}
  <footer>blog footer</footer>
</body>
</html>

This API not only allows you to fetch articles from sources but you can do all sort of things. What you render on a page is completely in your control. Whatever HTML string you pass to render function, becomes the HTML on the page.

Do note that this is an optional API and you can completely skip entry.build.ts and your routes will be based on filepaths.

This removes the need of all sort of abell-specific source plugins! If you feel like you have to write a lot of code, you can always wrap the source APIs in some non-abell-specific NPM package and use it from package.

Breaking change

  • The export function render from earlier releases is dropped in favor of makeRoutes