1

I'm writing my blog with Nuxt Content which can filter posts based on their properties. One of my properties is tags. Now I would like to create a page for each tag.

My current solution works, but the query is case-sensitive, where I would really like it to be case-insensitive.

<script>
export default {
  async asyncData({ $content, params }) {
    const tag = params.tag

    const articles = await $content('blog', params.slug)
      .where({ tags: { $contains: tag } })
      .only(['title', 'slug', 'description', 'createdAt', 'body'])
      .sortBy('createdAt', 'asc')
      .fetch()

    return { articles, tag }
  },
}
</script>

Based on the LokiJS documentation I tried to use a function in the where function, but that returns all posts, instead of just the posts for the given tag.

<script>
export default {
  async asyncData({ $content, params }) {
    const tag = params.tag

    const articles = await $content('blog', params.slug)
      .where(function (article) {
        return article.tags
          .map((tag) => tag.toLowerCase())
          .contains(params.tag.toLowerCase())
      })
      .only(['title', 'slug', 'description', 'createdAt', 'body'])
      .sortBy('createdAt', 'asc')
      .fetch()

    return { articles, tag }
  },
}
</script>

So how should I write the query in order to get articles that contain the tags without having to worry about case-sensitivity.

Johan Vergeer
  • 5,208
  • 10
  • 48
  • 105

1 Answers1

2

Today I ran into the same problem.

The closest I found was this documentation: https://content.nuxtjs.org/snippets/#case-insensitive-sorting

However, analyzing the code I came to the conclusion that in this example data is being injected into the .md files

Modifying the snippet a bit I managed to make it work in the correct way, I leave you the code below: (you must add it to nuxt.config.js file)

hooks: {
    'content:file:beforeInsert': document => {
      if (document.extension === '.md') {
        Object.entries(document).forEach(([key, value]) => {
          const _key = `case_insensitive__${key}`;

          // Strings
          if (!document[_key] && typeof value === 'string') {
            document[_key] = value.toLocaleLowerCase();
          }

          // Arrays
          if (!document[_key] && Array.isArray(value)) {
            document[_key] = value.map(val => {
              if (typeof val === 'string') {
                return val.toLocaleLowerCase();
              }
              return val;
            });
          }
        });
      }
    },
  },

After that all the properties of your markdown will be in lowercase if you put the prefix "case_insensitive__".

I leave you an example of how I filtered the tags so that it does not matter if they are uppercase or lowercase (both work in the url):

_tag.vue
...
<script>
  export default {
    async asyncData({ $content, params }) {
      const articles = await $content('articles')
        .where({ case_insensitive__tags: { $contains: params.tag.toLowerCase() } })
        .without('body')
        .sortBy('createdAt', 'asc')
        .fetch();
      return {
        articles,
      };
    },
  };
</script>
Luis Eduardo
  • 63
  • 2
  • 7