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

[Vue]: Unique ID doesn't work in SSR #825

Closed
jiblett1000 opened this issue Apr 26, 2023 · 5 comments · Fixed by #866 or #918
Closed

[Vue]: Unique ID doesn't work in SSR #825

jiblett1000 opened this issue Apr 26, 2023 · 5 comments · Fixed by #866 or #918

Comments

@jiblett1000
Copy link

Hey again,

Stumbled on an issue while using various components. The unique id created with the useId() utility within the component and passed to the machine isn't unique when using SSR. In addition, any id prop passed to the component is ignored. Doing a brief scan, it looks like some components are also still missing the id prop.

As of now, it seems the only solutions are either:

  1. Wrap every component in <ClientOnly>.

  2. Develop an SPA.

These reproductions show some issues stemming from this. In the Select repro, the second menu position is not where it should be. In the Editable repro, the active styling remains on the second input when focusing between the two inputs. In either one, wrapping the components in ClientOnly or adding ssr: false to the nuxt.config.ts should fix the issues and create a different id as expected (which you can see in the DOM).

https://stackblitz.com/edit/nuxt-starter-xzqjnc?file=app.vue

https://stackblitz.com/edit/nuxt-starter-g6mate?file=nuxt.config.ts

Hope this helps. Perhaps there's another solution I'm unaware of as well.

@codebender828
Copy link
Collaborator

@jiblett1000 Noted and thank you. We initially designed the useId hook to populate when the component is mounted. On SSR we shall need to modify is such that it is isomorphic.

We've started working on a fix for this. Will open a PR soon for it.

@jiblett1000
Copy link
Author

@codebender828 Very much appreciated 😄

@cschroeter
Copy link
Member

@codebender828 In this bug report there is another important issue we need to tackle in Vue.

I noticed that only 4 of the 22 components declare id as a property and I'm sure that a lot more properties of the underlying zag component are not declared.

To solve that problem I recommend that we create a custom declareProps function, that ensures that every prop / type that is declared in the provided interface is translated to a vue property. Like so:

const props = customDeclareProps<UseAccordionContext>({
  collapsible: {
    type: Boolean as PropType<AccordionProps['collapsible']>,
    default: false,
  } // etc.
})

Let me know what you think.

@cschroeter
Copy link
Member

Here is an idea:

import type { PropType } from 'vue'

type CustomDeclareProps<T> = {
  [K in keyof T]: {
    type: PropType<T[K]>
    default?: T[K]
  }
}

function customDeclareProps<T extends object>(
  properties: CustomDeclareProps<T>,
): CustomDeclareProps<T> {
  return properties
}

interface AccordionProps {
  collapsible: boolean
  ids: object
  getRootNode: () => HTMLElement
  orientation: string
}

interface UseAccordionContext {
  collapsible: AccordionProps['collapsible']
  ids: AccordionProps['ids']
  getRootNode: AccordionProps['getRootNode']
  orientation: AccordionProps['orientation']
}

type UseAccordionContextProps = CustomDeclareProps<UseAccordionContext>

const props: UseAccordionContextProps = customDeclareProps({
  collapsible: {
    type: Boolean as PropType<AccordionProps['collapsible']>,
    default: false,
  },
  ids: {
    type: Object as PropType<AccordionProps['ids']>,
  },
  getRootNode: {
    type: Function as PropType<AccordionProps['getRootNode']>,
  },
  orientation: {
    type: String as PropType<AccordionProps['orientation']>,
  },
})

@Shyrro
Copy link
Collaborator

Shyrro commented May 4, 2023

I'm reopening this ( closed automatically ). The SSR id issue is fixed but we still need to make all the components accept an id prop.

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