Skip to content

Commit

Permalink
Update SSR Hydration Script approach
Browse files Browse the repository at this point in the history
  • Loading branch information
ryansolid committed Jun 12, 2021
1 parent 860e777 commit 91d9a99
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 31 deletions.
53 changes: 48 additions & 5 deletions documentation/guides/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { hydrate } from "solid-js/web";

hydrate(() => <App />, document);
```
*Note: It is possible to render and hydrate from the Document root. This allows us to describe our full view in JSX.*

_Note: It is possible to render and hydrate from the Document root. This allows us to describe our full view in JSX._

The server entry can use one of the four rendering options offered by Solid. Each produces the output and a script tag to be inserted in the head of the document.

Expand All @@ -36,10 +37,11 @@ pipeToNodeWritable(App, res);
const { readable, writable } = new TransformStream();
pipeToWritable(() => <App />, writable);
```

For your convenience `solid-js/web` exports an `isServer` flag. This is useful as most bundlers will be able to treeshake anything under this flag or imports only used by code under this flag out of your client bundle.

```jsx
import { isServer } from "solid-js/web"
import { isServer } from "solid-js/web";

if (isServer) {
// only do this on the server
Expand All @@ -48,6 +50,46 @@ if (isServer) {
}
```

## Hydration Script

In order to progressively hydrate even before Solid's runtime loads, a special script needs to be inserted on the page. It can either be generated and inserted via `generateHydrationScript`or included as part of the JSX using the `<HydrationScript />` tag.

```js
import { generateHydrationScript } from "solid-js/web";

const app = renderToString(() => <App />);

const html = `
<html lang="en">
<head>
<title>🔥 Solid SSR 🔥</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/styles.css" />
${generateHydrationScript()}
</head>
<body>${app}</body>
</html>
`
```

```jsx
import { HydrationScript } from "solid-js/web";

const App = () => {
return <html lang="en">
<head>
<title>🔥 Solid SSR 🔥</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/styles.css" />
<HydrationScript />
</head>
<body>{/*... rest of App*/}</body>
</html>
}
```

## Async and Streaming SSR

These mechanisms are built on Solid's knowledge of how your application works. It does so by using Suspense and the Resource API on the server, instead of fetching ahead and then rendering. Solid fetches as it renders on the server just like it does on the client. Your code and execution patterns is written exactly the same way.
Expand All @@ -57,9 +99,10 @@ Async rendering waits until all Suspense boundaries resolve and then sends the r
Streaming starts flushing synchronous content to the browser immediately rendering your Suspense Fallbacks on the server. Then as the async data finishes on the server it sends the data over the same stream to the client to resolve Suspense where the browser finishes the job and replaces the fallback with real content.

The advantage of this approach:
* Server doesn't have to wait for Async data to respond. Assets can start loading sooner in the browser, and the user can start seeing content sooner.
* Compared to client fetching like JAMStack, data loading starts on the server immediately and doesn't have to wait for client JavaScript to load.
* All data is serialized and transported from server to client automatically.

- Server doesn't have to wait for Async data to respond. Assets can start loading sooner in the browser, and the user can start seeing content sooner.
- Compared to client fetching like JAMStack, data loading starts on the server immediately and doesn't have to wait for client JavaScript to load.
- All data is serialized and transported from server to client automatically.

## SSR Caveats

Expand Down
46 changes: 23 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
"babel-jest": "^26.6.3",
"babel-plugin-jsx-dom-expressions": "^0.28.3",
"coveralls": "^3.1.0",
"dom-expressions": "0.28.3",
"dom-expressions": "0.28.4",
"gitly": "^2.1.0",
"hyper-dom-expressions": "0.28.3",
"hyper-dom-expressions": "0.28.4",
"jest": "~26.6.3",
"jest-ts-webcompat-resolver": "^1.0.0",
"lerna": "^4.0.0",
"lit-dom-expressions": "0.28.3",
"lit-dom-expressions": "0.28.4",
"ncp": "2.0.0",
"npm-run-all": "^4.1.5",
"rimraf": "^3.0.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/solid-ssr/examples/shared/src/components/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useContext, lazy } from "solid-js";
import { HydrationScript } from "solid-js/web";
import { Link, RouteHOC, RouterContext } from "../router";
// import stub as main package to allowing fetch as you load
import Profile from "./Profile";
Expand All @@ -15,6 +16,7 @@ const App = RouteHOC(() => {
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/styles.css" />
<HydrationScript />
</head>
<body>
<div id="app">
Expand Down

0 comments on commit 91d9a99

Please sign in to comment.