Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Where nuxt.callHook should be called on? #8

Open
tonywei92 opened this issue Feb 9, 2021 · 5 comments
Open

Where nuxt.callHook should be called on? #8

tonywei92 opened this issue Feb 9, 2021 · 5 comments

Comments

@tonywei92
Copy link

The guide isn't stating where this code should sit on:

nuxt.callHook('lunr:document', ({ locale: 'af', // optional, default en document, meta // optional })

Can I call it on asyncData? Any Example? thanks

Copy link
Member

Atinux commented Feb 9, 2021

You can take a look at this example @tonywei92 : https://github.com/nuxt-community/lunr-module/blob/master/example/nuxt.config.js

I think @pimlie may be the best to answer how to use it properly

@pimlie
Copy link
Member

pimlie commented Feb 10, 2021

@tonywei92 Where you have to call the lunr:document hook isnt documented because it depends on your implementation / use-case.

Note that creating the search index is done at build time, not during runtime. Ie you build the index during build, and the index is then added to your project so it can be used during runtime.

@ryanweal
Copy link

I'm trying this module out today and I am very confused as well. I have been using Nuxt a long time now but hooks are still new to me.

I am trying to add the documents that the build process discovers to a search index. That seems to be the default case we are talking about here.

The example does not add this module to the nuxt modules. It also provides a set of documents that occur outside of the generate process. I find this very confusing. How do I get access to the documents that are accessed during the build process (crawl)?

I'm going to try some things and will report back what I uncover. Just wanted to let you know my first thoughts on this module as I am working with it for the first time. Thanks.

@gruis
Copy link

gruis commented Mar 22, 2021

Yup, there are ways to setup your asyncData handler so that certain actions, e.g., adding Lunr documents, are only done during the generate process. This allows you to execute API calls in the same manner as the rest of your app and during the generate. Relying on a callHook in the config file requires you to setup API handlers that are outside of the normal app lifecycle.

I think the way around this is to take the nuxt.hook('lunr:document' handler and extract it to a function that is also injected into the context, at least for the "server", i.e., in a lunr.server.plugin.js. This would allow rapid iteration during development and testing when combined with asyncData handler. If setup correctly it'll only run on the server side and will be run during generation.

https://github.com/nuxt-community/lunr-module/blob/master/lib/module.js#L102

Example usage:

  async asyncData(ctx) {
    const { $lunr, $api, req, store } = ctx;
    // $lunr and $api are injected via a server plugin, so aren't available in the client
    if (!($api && $lunr)) {
      return;
    }
    const documents = await $api.getTheThingsIWantToIndexAndDisplay({ req })
    store.commit("things/INSERT", documents);
    Object.values(documents).forEach((d) => {
      $lunr.addDoc({ id: d.id, ...normalize(d) })
    })
  },
  computed: {
    // provide the things For SSR or client side navigation
    things() {
      return this.$store.getters["things/all"]
    }
  }

@pimlie
Copy link
Member

pimlie commented Mar 28, 2021

@gruis Although your approach could work, I wouldn't recommend it personally cause I think adding the lunr/indexing logic into your page components could be confusing. Instead I would recommend to add a nuxtServerInit to preload your store and load the docs from your api in a build before hook:

// nuxt.config
  hooks: {
    'build:before'(nuxt) {
      // preload all docs from your API and save to disk or global obj
    },
    ready(nuxt) {
      // add docs to lunr
    }
  }

// ~/store/index.js
actions: {
  nuxtServerInit ({ commit }, { req }) {
    const documents = // load from disk or global obj
    commit("things/INSERT", documents);
  }
}

If you really need / want to use asyncData to load/index specific documents then please note that maybe nuxt/content is more suited to your needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants