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

docs(isBrowser/isServer): explain why those helpers are useful #1

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ If you happened to come across one of them and don't know what its replacement i
| :-------- | :-------
| `useWatch$` | [useTask$](https://qwik.dev/docs/components/tasks/#usetask) |
| `useMount$` | [useTask$](https://qwik.dev/docs/components/tasks/#usetask) |
| `useServerMount` | [useTask$](https://qwik.dev/docs/components/tasks/#usetask) + [isServer](https://qwik.dev/docs/guides/qwik-nutshell/#isserver-conditional)
| `useClientMount` | [useTask$](https://qwik.dev/docs/components/tasks/#usetask) + [isBrowser](https://qwik.dev/docs/guides/qwik-nutshell/#isbrowser-conditional)
| `useServerMount` | [useTask$](https://qwik.dev/docs/components/tasks/#usetask) + [isServer](https://qwik.dev/docs/guides/qwik-nutshell/#isbrowser-&-isserver-conditionals)
| `useClientMount` | [useTask$](https://qwik.dev/docs/components/tasks/#usetask) + [isBrowser](https://qwik.dev/docs/guides/qwik-nutshell/#isbrowser-&-isserver-conditionals)
| `useClientEffect` - `useClientEffectQrl` | [useVisibleTask$](https://qwik.dev/docs/components/tasks/#usevisibletask) |
| `useBrowserVisibleTask` - `useBrowserVisibleTaskQrl` | [useVisibleTask$](https://qwik.dev/docs/components/tasks/#usevisibletask) |
| `useEnvData` | [useServerData](https://qwik.dev/api/qwik/#useserverdata) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ contributors:
- adamdbradley
- hamatoyogi
- maiieul
updated_at: '2023-12-14T18:38:38Z'
updated_at: '2024-04-02T18:38:38Z'
created_at: '2023-03-30T17:37:51Z'
---

Expand Down Expand Up @@ -125,23 +125,18 @@ useVisibleTask$(()=> {
}
})
// or
if (typeof window !== "undefined") {
const queryParams = new URLSearchParams(window.location.search);
const query: Record<string, string> = {};
queryParams.forEach((value, key) => {
query[key] = value;
})
doTheThing(query);
}
useTask$(() => {
if (isBrowser) {
if (window.location.href).includes('foo') {
//... do the thing
}
}
})
```

Many actions related to location information can be executed during the initial server-side render, resulting in pure HTML without any JavaScript overhead.

By forcing this logic to run on the client side, it introduces increased upfront JavaScript and leads to eager loading.

Using the `if typeof window !== "undefined"` pattern may cause the code to be skipped. On the server, the code block will be skipped since the window is always undefined.

While developers may be accustomed to code running twice, Qwik eliminates this necessity by providing a more efficient approach.
Forcing this logic to run on the client side introduces increased upfront JavaScript and leads to eager loading.

```tsx title="Optimal Implementation"
// Do this!
Expand All @@ -150,8 +145,6 @@ const location = useLocation();
if (location.url.href.includes('foo')) {
// Do the thing
}

doTheThing(location.url.searchParams);
```

### Exception
Expand All @@ -162,5 +155,4 @@ However, exercise caution! If the required information (such as query parameters

This approach helps to prevent eager loading of JavaScript and improves performance.

> See: [useLocation() Docs](/docs/(qwikcity)/api/index.mdx#uselocation)

> See: [useLocation() Docs](/docs/(qwikcity)/api/index.mdx#uselocation)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ contributors:
- adamdbradley
- hamatoyogi
- aendel
updated_at: '2023-10-03T18:53:23Z'
- maiieul
updated_at: '2024-04-02T18:53:23Z'
created_at: '2023-03-30T19:49:50Z'
---
# Qwik in a nutshell
Expand Down Expand Up @@ -665,10 +666,6 @@ This API will declare a VisibleTask that is ensured to run only on the client/br

JSX handlers such as `onClick$` and `onInput$` are only executed on the client. This is because they are DOM events, since there is no DOM on the server, they will not be executed on the server.

### `isBrowser` conditional

Qwik provides an `isBrowser` boolean exported from `@builder.io/qwik/build`. You can use this to ensure that code only runs in the browser.

## Run code only on the server

Sometimes you need to run code only on the server, such as fetching data or accessing a database. To solve this problem, Qwik provides a few APIs to run code only on the server.
Expand Down Expand Up @@ -736,6 +733,18 @@ The `routeLoader$()` is a special component that is only executed on the server.

The `server$()` is a special way to declare functions that only run on the server. If called from the client, they will behave like an RPC call, and will be executed on the server. They can take any serializable arguments, and return any serializable value.

### `isServer` conditional
### `isServer` & `isBrowser` conditionals

Instead of `if(typeof window !== 'undefined')`, it is recommended to use the `isServer` and `isBrowser` boolean helpers exported from `@builder.io/qwik/build` to ensure your code only runs in the browser. They contain slightly more robust checks to better detect the browser environment.

Qwik provides a `isServer` boolean exported from `@builder.io/qwik/build`. You can use this to ensure that code only runs on the server.
Here is the source code for reference:

```tsx
export const isBrowser: boolean = /*#__PURE__*/ (() =>
typeof window !== 'undefined' &&
typeof HTMLElement !== 'undefined' &&
!!window.document &&
String(HTMLElement).includes('[native code]'))();

export const isServer: boolean = !isBrowser;
```
Loading