Skip to content

Portal is not ssr compat - accesses document during render #3721

@mattcosta7

Description

@mattcosta7

Description

When using InlineAutocomplete we inherit usage of <Portal /> rendering on page load.

I think the issue occurs because <Portal> calls document.createElement and createPortal with a ref to an element that can't be created.

const hostElement = document.createElement('div')

we should avoid these apis in render in portal (which creates a div on every render) and rely on other mechanisms to sync it

In addition to this, it renders an _Autocomplette which uses useCombobox which calls useLayoutEffect resulting in a call to console.error on the server -

useLayoutEffect(() => {
const optionElements = getOptionElements()
// Ensure each option has a unique ID (required by the Combobox class), but respect user provided IDs
for (const [i, option] of optionElements.entries()) {
if (!option.id || option.id.startsWith(optionIdPrefix)) option.id = `${optionIdPrefix}-${i}`
option.setAttribute('data-combobox-list-index', i.toString())
option.addEventListener('mousedown', onOptionMouseDown)
// the combobox class has a bug where it resets the default on navigate, but not on clearSelection
option.removeAttribute('data-combobox-option-default')
}
comboboxInstance?.clearSelection()
return () => {
for (const option of optionElements) option.removeEventListener('mousedown', onOptionMouseDown)
}
}, [getOptionElements, optionIdPrefix, options, comboboxInstance, onOptionMouseDown])

Steps to reproduce

Atempt to SSR an app that uses InlineAutocomplete

Version

latest

Browser

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions