Skip to content

Islands can no longer be “client-side only”#8948

Merged
mxdvl merged 2 commits intomainfrom
oj/islands/never-client-side-only
Oct 3, 2023
Merged

Islands can no longer be “client-side only”#8948
mxdvl merged 2 commits intomainfrom
oj/islands/never-client-side-only

Conversation

@mxdvl
Copy link
Copy Markdown
Contributor

@mxdvl mxdvl commented Sep 29, 2023

What does this change?

Remove the clientOnly prop from Island, forcing components that may be rendered on the server not to throw errors.

Why?

Components that rely on accessing window or document should handle this internally, rather than relying on a property of their parent Island.

The behaviour becomes more explicit and less prone to errors.

Follow-up on #8944

Screenshots

N/A – identical

@mxdvl mxdvl added the Health label Sep 29, 2023
@mxdvl mxdvl force-pushed the oj/islands/never-client-side-only branch from 7ed39ac to 3da8655 Compare September 29, 2023 07:28
@github-actions
Copy link
Copy Markdown

github-actions bot commented Sep 29, 2023

Size Change: 0 B 🆕

Total Size: 0 B

compressed-size-action

@mxdvl mxdvl force-pushed the oj/islands/never-client-side-only branch 4 times, most recently from 7676892 to 4165ec4 Compare September 29, 2023 11:35
@OllysCoding
Copy link
Copy Markdown
Contributor

While I agree this is probably the best way to go (since components exist outside their use in an island, it can be unclear when one is intended to be client only vs not client only, etc) - I think we ought to be providing some kind of guidance to developers to help them write islands.

This could be as simple as providing an easy component & a util isServer() function - but my preference would be to provide an easy ways to see your component side-by-side in the server render vs the client render (e.g imagine a storybook like interface where you see two versions of your component, one server-side rendered with no JS / hydration, and another client side hydrated version of that same component). I think this would really do a good job to give engineers visibility over the "lifecycle" of the code they're writing.

It's worth keeping in mind Islands are quite 'custom' and that a lot of engineers joining the guardian aren't necessarily familiar with server side rendered react or partial hydration models, so we ought to be providing a really well guided experience to writing code in this paradigm.

@mxdvl mxdvl force-pushed the oj/islands/never-client-side-only branch from 4165ec4 to f9b410d Compare September 29, 2023 15:18
@mxdvl
Copy link
Copy Markdown
Contributor Author

mxdvl commented Oct 2, 2023

I think we ought to be providing some kind of guidance to developers to help them write islands.

Do you see the lack of documentation as a blocker to this change? I think that if anything, this change makes it easier to come up with consistent documentation. None of the proposed changes invalidate existing guidance:

### After
PRs #[3629](https://github.com/guardian/dotcom-rendering/pull/3629) & [#3784](https://github.com/guardian/dotcom-rendering/pull/3784) simplify the process of partial hydration by moving the logic out of a React app and into a simple script tag. This removes the need to manage re-renders, can use standard dynamic imports and reduces the effort needed to use.
To create a new island you now:
1. Wrap you component on the server with `Island`.
2. Add `.importable` to the component filename. Eg: `[MyThing].importable.tsx`
This is simpler to use, harder to make mistakes with and is certain to only ever send the data to the client that is required.

## How can I create an 'island' in DCR?
The 'islands' pattern is DCR's way of adding client-side React code to the site.
You can read more about it in our
[Improved Partial Hydration](architecture/027-better-partial-hydration.md)
decision document.
To add an island:
1. Wrap your component on the server with an `<Island>` component.
2. Add `.importable` to the component filename. Eg: `[MyThing].importable.tsx`
3. Specify what should trigger hydration (e.g. waiting until the component
scrolls into view). See `Island.tsx` props for options.

I also think that documentation would be best adressed by the @guardian/dotcom-platform team, who is the more usual steward/custodian of this codebase.

@mxdvl mxdvl marked this pull request as ready for review October 2, 2023 13:48
@mxdvl mxdvl requested a review from a team as a code owner October 2, 2023 13:48
Base automatically changed from oj/islands/placeholder-simplification to main October 2, 2023 13:49
@mxdvl mxdvl force-pushed the oj/islands/never-client-side-only branch from f9b410d to 005acbc Compare October 2, 2023 13:54
Components that rely on accessing `window` or `document`
should handle this internally, rather than relying on
a property of their parent Island.

The behaviour becomes more explicit and less prone to errors.

Co-authored-by: Alex Sanders <[email protected]>
@mxdvl mxdvl force-pushed the oj/islands/never-client-side-only branch from 005acbc to ff451af Compare October 2, 2023 14:36
Comment on lines +423 to +431
/**
* This is a weird way of handling this client-only island,
* but as this component is temporary, it was deemed
* a more pragmatic approach over having to rewrite it entirely.
*
* (October 2023)
*/
export const EuropeLandingModal = (props: Props) =>
isServer ? null : <ClientOnlyEuropeLandingModal {...props} />;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Discussed with @oliverabrahams & @OllysCoding – this Island cannot run on the server.

@mxdvl mxdvl added the run_chromatic Runs chromatic when label is applied label Oct 2, 2023
individual components can choose to opt out of hydration
via the useHydrated hook.
@mxdvl mxdvl force-pushed the oj/islands/never-client-side-only branch from 80a6c46 to 3231a33 Compare October 2, 2023 17:17
@mxdvl mxdvl merged commit ec35e00 into main Oct 3, 2023
@mxdvl mxdvl deleted the oj/islands/never-client-side-only branch October 3, 2023 06:48
cemms1 added a commit that referenced this pull request Oct 3, 2023
sophie-macmillan pushed a commit that referenced this pull request Oct 3, 2023
@mxdvl mxdvl mentioned this pull request Oct 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dotcom-rendering run_chromatic Runs chromatic when label is applied

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants