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

Fix SSR for breadcrumbs and collapsible-nav #3970

Merged
merged 8 commits into from
Sep 2, 2020

Conversation

pugnascotia
Copy link
Contributor

Summary

Closes #3687. Put guards around references to window so that in an SSR environment, EUI will still work.

My choice of 1024 as a default innerWidth was entirely arbitrary - I'm open to suggestions here.

Checklist

  • Check against all themes for compatibility in both light and dark modes
  • Checked in mobile
  • Checked in Chrome, Safari, Edge, and Firefox
  • Props have proper autodocs
  • Added documentation
  • Checked Code Sandbox works for the any docs examples
  • Added or updated jest tests
  • Checked for breaking changes and labeled appropriately
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

Closes elastic#3687. Put guards around references to `window` so that in an SSR
environment, EUI will still work.
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_3970/

);

const functionToCallOnWindowResize = throttle(() => {
const newBreakpoint = getBreakpoint(window.innerWidth);
const newBreakpoint = getBreakpoint(
typeof window === 'undefined' ? 1024 : window.innerWidth
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I totally understand the intent of this PR, but I don't think setting this to a static (arbitrary) number creates expected behavior.

Instead, is there a way to only do all this breakpoint logic/dependency stuff if the window exists? That way SSR users can apply breakpoints via CSS without it getting overridden by this static number.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not really because you're not supposed to conditionally call hooks like useState. However I could change the code to use e.g. Infinity or something so that getBreakpoint() returns undefined, which it can already do according to its type. What do you think? It's a (somewhat) less arbitrary value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that will actually return undefined because any number that is not less than the largest breakpoint will return the value for the largest breakpoint, ie. xl

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can swap it for -Infinity, I checked over how values derived from window.innerWidth are used and I think it'll be OK.

(Aside: this is a philosophical brain teaser - what is the size of a server-side window?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accessing window from functionToCallOnWindowResize should never happen in SSR. The method is called from useEffect which doesn't run in a non-browser environment. I believe only the change to currentBreakpoint's initial state is necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😞 The breakpoint logic also doesn't seem to be working anymore at all (even just on our docs).

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_3970/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_3970/

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_3970/

@cchaos
Copy link
Contributor

cchaos commented Aug 27, 2020

@pugnascotia Thank you for setting up this branch. I'm trying to get a clear picture how what the behavior of these components will now be. Does this simply mean that for SSR's, on initialization of the component, it won't know what window is but if you resize the browser width it will? Is there any way we can initialize the render with window? Or does this not actually affect the render of the component at all, it's just that the build won't complain now?

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_3970/

@pugnascotia
Copy link
Contributor Author

@cchaos On the server (e.g. Next.js, whether rendering on-demand or pre-rendering for a static site), these changes will cause the breadcrumb component initialse and render (one time only) with a very narrow window width (-Infinity, but let's not get into that), and that will be reflected in the resulting HTML. I tried this out with the Next starter, and actually the generated HTML didn't change, I believe because I hadn't fiddled with the responsive object settings.

Then, the component will re-render on the client (web browser), where it will pick up the window width and render appropriately, and identically as at present.

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_3970/

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, the component will re-render on the client (web browser), where it will pick up the window width and render appropriately, and identically as at present.

😅 Ok cool! So nothing changes for the user. The breadcrumbs still properly display depending on the window size at the time of page load and on window resize.

Whew, that means I don't have to continue down my path of writing up an "Except for SSR" callout in the documentation 😸

CHANGELOG.md Outdated Show resolved Hide resolved
src/components/collapsible_nav/collapsible_nav.tsx Outdated Show resolved Hide resolved
Co-authored-by: Caroline Horn <549577+cchaos@users.noreply.github.com>
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_3970/

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Sweet, LGTM!

Copy link
Contributor

@chandlerprall chandlerprall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM! Thanks @pugnascotia

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_3970/

@pugnascotia pugnascotia merged commit fc3a93c into elastic:master Sep 2, 2020
@pugnascotia pugnascotia deleted the fix-breadcrumbs-ssr branch September 2, 2020 09:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

EuiBreadcrumbs breaks SSR
4 participants