Content: Hot Reloading does not work TS + Composition API + Markdown

Created on 1 Jun 2020  Â·  3Comments  Â·  Source: nuxt/content

Version

@nuxt/content: 1.2.0
@nuxt/typescript-runtime: 0.4.8
nuxt-composition-api: 0.8.0

nuxt: 2.12.2

Steps to reproduce

I use nuxt with typescript and composition api:

pages/_slug.vue:

<template>
  <nuxt-content :document="doc" />
</template>

<script lang="ts">
import { defineComponent, useContext, useAsync, onServerPrefetch, computed } from 'nuxt-composition-api'

export default defineComponent({
  setup() {
    const { $content, params } = useContext()
    const fetchContent = () => {
      return $content(params.value.slug || 'index').fetch()
    }

    const doc = useAsync(fetchContent)
    onServerPrefetch(async () => {
      doc.value = await fetchContent()
    })

    return {
      doc
    }
  }
})
</script>

content/index.md:

# Test

What is Expected?

Hot reloading after modify content/index.md.

What is actually happening?

ℹ Type checking in progress...      nuxt:typescript 21:59:23
ℹ No type errors found                  nuxt:typescript 21:59:26
ℹ Version: typescript 3.8.3            nuxt:typescript 21:59:26
ℹ Time: 4104 ms                           nuxt:typescript 21:59:26
ℹ Updated ./content/index.md       @nuxt/content 21:59:38
bug

Most helpful comment

@pi0 @hason At first glance, I think this is an issue with nuxt-composition-api, not @nuxt/content.

Here's what's happening. The docs for useAsync say:

On the server, this helper will inline the result of the async call in your HTML and automatically inject them into your client code. Much like asyncData, it won't re-run these async calls client-side.

Because you've hard reloaded the page initially, the value of doc is inlined in your page. When the page hot-reloads, it's still there and so it re-populates doc with that same initial call (now outdated).

Obviously we'd prefer to support HMR with useAsync and ssrRef more generally so I'll create an issue with nuxt-composition-api and address it there.

UPDATE: Above notwithstanding, to get HMR working with vanilla component syntax you might need to use asyncData or the store - or create a custom handler for update.

All 3 comments

/cc @danielroe any ideas? :see_no_evil:

@pi0 @hason At first glance, I think this is an issue with nuxt-composition-api, not @nuxt/content.

Here's what's happening. The docs for useAsync say:

On the server, this helper will inline the result of the async call in your HTML and automatically inject them into your client code. Much like asyncData, it won't re-run these async calls client-side.

Because you've hard reloaded the page initially, the value of doc is inlined in your page. When the page hot-reloads, it's still there and so it re-populates doc with that same initial call (now outdated).

Obviously we'd prefer to support HMR with useAsync and ssrRef more generally so I'll create an issue with nuxt-composition-api and address it there.

UPDATE: Above notwithstanding, to get HMR working with vanilla component syntax you might need to use asyncData or the store - or create a custom handler for update.

@hason I've just released HMR support for nuxt-composition-api in v0.8.1. However, that won't fix this issue as @nuxt/content doesn't trigger a reload of the component, and $nuxt.refresh only reloads fetch and asyncData.

So you'll need to add the below to your component's setup():

if (process.NODE_ENV === 'development' && process.client) {
  window.$nuxt.$on('content:update', async () => {
    doc.value = await fetchContent()
  })
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Haeresis picture Haeresis  Â·  3Comments

katerlouis picture katerlouis  Â·  3Comments

giticon picture giticon  Â·  3Comments

pxwee5 picture pxwee5  Â·  4Comments

thely picture thely  Â·  4Comments