# @saus/react

> React renderer for saus

Latest version **0.4.9** (published 2021-10-16) · MIT license · 0 weekly downloads

## Install

```sh
npm install @saus/react
pnpm add @saus/react
yarn add @saus/react
bun add @saus/react
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.4.9 |
| Published | 2021-10-16 |
| First published | 2021-10-03 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 32 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | aleclarson |

## Links

- npm: https://www.npmjs.com/package/@saus/react
- npm.io page: https://npm.io/package/@saus/react

## Dependencies (2)

- [@types/babel__core](https://npm.io/package/@types/babel__core.md) ^7.1.16
- [@vitejs/plugin-react](https://npm.io/package/@vitejs/plugin-react.md) ^1.0.1

## Recent versions

- 0.4.9 (latest) — 2021-10-16
- 0.4.8 — 2021-10-16
- 0.4.0 — 2021-10-09
- 0.3.1 — 2021-10-08
- 0.3.0 — 2021-10-07
- 0.2.2 — 2021-10-05
- 0.2.1 — 2021-10-05
- 0.2.0 — 2021-10-05
- 0.1.1 — 2021-10-04
- 0.1.0 — 2021-10-03

## README

# @saus/react

Pre-render your pages with React and `@saus/react` will generate the module that hydrates your page on the client-side. Use JSX to render your `<head>` and `<body>` tags. Use the automatic JSX runtime and Fast Refresh.

Start by importing the `render` function in your project's `src/render.tsx` module (or whichever module you set `render` to in your `saus.yaml` file).

```ts
import { render } from '@saus/react'
```

Use it to define the default renderer. It receives the loaded module from the page's matching route. You can export whatever you like, but in this example, we're setting the `default` export to a React component, which represents the page content.

```ts
import { render } from '@saus/react'
import React from 'react'

render(module => {
  const Page = module.default as React.ComponentType
  return <Page />
})
```

### Route parameters

If you're using route parameters, you'll want to pass those into your `Page` component.

```ts
import { render } from '@saus/react'
import React from 'react'

render((module, { params }) => {
  const Page = module.default as React.ComponentType
  return <Page {...params} />
})
```

### Routed rendering

If a certain route needs its own logic, one option is to give it a dedicated renderer.

```ts
render('/books/:book', (module, { params }) => {
  return <body>{params.book}</body>
})
```

### Isomorphic rendering

It's important to remember that your renderer will run in both Node and web environments, so you need to be conscious about keeping your code compatible with both.

The one exception to that rule is when a variable is only used for rendering the optional `<head>` element. Any code used in `<head>` and not in `<body>` will be tree-shaked while generating the client renderer.

&nbsp;

## Limitations

To reduce code complexity in the client generator, your render functions have the following limitations.

&nbsp;

**Keep `<head>` and `<body>` elements within `<html>` subtree.**

For the `<head>`-only logic to be tree-shaked, it can't be "lifted" out of the `<html>` subtree.

```tsx
// Bad
const Head = () => (
  <head>{...}</head>
)
return (
  <html>
    <Head />
  </html>
)

// Good
return (
  <html>
    <head>{...}</head>
  </html>
)
```

If you want to reuse `<head>` children between renderers, you can write a component that returns a JSX fragment containing the scripts, stylesheets, etc. that you wish to share between them.

```tsx
const SharedHeadTags = () => (
  <>
    <link rel="icon" href="/favicon.ico" type="image/x-icon" />
    <link rel="stylesheet" href="…" />
    <script src="…"></script>
  </>
)

// In your render functions:
return (
  <html>
    <head>
      <SharedHeadTags />
    </head>
  </html>
)
```

The same limitation applies to the `<body>` element, but not for tree-shaking reasons.

The `<body>` element is only required when your render function returns an `<html>` element. Otherwise, you're free to omit `<body>` and just return its children. In that case, `@saus/react` inserts the `<body>` element in SSR before rendering your JSX into a string, to ensure the HTML is well-formed. If you lift the `<body>` element into a component, you'll end up with two `<body>` elements in the HTML string, which is bad.

&nbsp;

**Keep `return` statements simple.**

When returning JSX, prefer `if` blocks over ternary expressions (eg: `a ? <b /> : <c />`) or conditional expressions (eg: `a && <b />`).

```tsx
// Bad
return condition ? <div /> : <body />

// Good
if (condition) {
  return <div />
}
return <body />
```

This **does not apply** to nested elements; just the root element that immediately follows the `return` keyword. As a rule of thumb, if your element is wrapped in a JSX curly expression (eg: `{a && <b />}`), any syntax is allowed. Additionally, this rule does _not_ apply to JSX elements in variable declarations (eg: `const a = b ? <c /> : <d />`).

Wrapping your root element in parentheses is allowed.

```tsx
return (
  <html>{...}</html>
)
```

---
_Source: https://npm.io/package/@saus/react · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
