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

support a component to capture component ssr failed and then automatically render it on client #14885

Closed
4 tasks done
keven-wang opened this issue Sep 12, 2022 · 4 comments · Fixed by nuxt/framework#8216
Closed
4 tasks done

Comments

@keven-wang
Copy link

Describe the feature

suggest support a new build-in component: client-only-if-ssr-failed。through this feature,we can avoid the page ssr process was interrupted by errors from some not important components.

i have tried to implement it myself, but i can not find the way to capture the error throwed by slot components.

<client-only>
  <client-compoent-1/>
</client-only>

<ssr-render-component-1/>
<ssr-render-component-2/>  

<client-only-if-ssr-failed>
  <!-- if this compoent ssr failed, it while not interrupte the page ssr,some components  render result can used -->
  <ssr-render-component-3 />
</client-only-if-ssr-failed>

Additional information

  • Would you be willing to help implement this feature?
  • Could this feature be implemented as a module?

Final checks

@huang-julien
Copy link
Member

huang-julien commented Oct 12, 2022

Hi 👋 ! Just want to say that i love this idea.
I think this can be quite useful for CMS (using dynamic templates).
The component could also have a @ssr-failed event to trigger something (such as reporting the error to sentry) if component fails on ssr.
I've been trying to implement a component to render a simple div onErrorCaptured but i'm struggling with a hydration issue due to the component still being partially rendered server-side.

@danielroe
Copy link
Member

We do have <NuxtErrorBoundary> which could be perhaps enhanced with some SSR capabilities.

@huang-julien
Copy link
Member

this is the current state of what i've been trying to do:

export default defineComponent({
  props: {
    uid: {
      type: String,
      required: true
    }
  },
  setup (props, ctx) {
    if (process.server) {
      const error = ref(false) 
      onErrorCaptured(() => {
        error.value = true
        // todo  report to sentry
        useState(`error_component_${props.uid}`, () => true)

        return false
      })

      return () => error.value ? createElementBlock('div') : ctx.slots.default()
    }
    const mounted = ref(false)
    const ssrFailed = useState(`error_component_${props.uid}`)

    if (ssrFailed.value) {
      onMounted(() => { mounted.value = true })
    }

    return () => ssrFailed.value ? mounted.value ? ctx.slots.default() : createElementBlock('div') : ctx.slots.default()
  }
})

error.value is set to true by ònErrorCaptured hook but since there's no reactivity server-side, the slot is still being rendered (with the errors such as missing data in the render etc...).
I was heavily inspired by the ClientOnly component but this just doesn't work 😢.
I'm pretty sure that if this can be done, this feature could be part of NuxtErrorBoundary instead of a separate component.

@danielroe danielroe added the 3.x label Jan 19, 2023
@danielroe danielroe transferred this issue from nuxt/framework Jan 19, 2023
@danielroe
Copy link
Member

merged in nuxt/framework#8216

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

Successfully merging a pull request may close this issue.

3 participants