diff --git a/app/entry.client.tsx b/app/entry.client.tsx
index 72fee3d..3fe091c 100644
--- a/app/entry.client.tsx
+++ b/app/entry.client.tsx
@@ -1,4 +1,4 @@
import {RemixBrowser} from '@remix-run/react';
import {hydrateRoot} from 'react-dom/client';
-hydrateRoot(document, );
+hydrateRoot(document.getElementById('root')!, );
diff --git a/app/entry.server.tsx b/app/entry.server.tsx
index 5b7ffb7..fe7a38b 100644
--- a/app/entry.server.tsx
+++ b/app/entry.server.tsx
@@ -1,6 +1,18 @@
import type {EntryContext} from '@shopify/remix-oxygen';
import {RemixServer} from '@remix-run/react';
import {renderToReadableStream} from 'react-dom/server';
+import {renderHeadToString} from 'remix-island';
+import {Head} from './root';
+
+const readableString = (value: string) => {
+ const te = new TextEncoder();
+ return new ReadableStream({
+ start(controller) {
+ controller.enqueue(te.encode(value));
+ controller.close();
+ },
+ });
+};
export default async function handleRequest(
request: Request,
@@ -8,13 +20,28 @@ export default async function handleRequest(
responseHeaders: Headers,
remixContext: EntryContext,
) {
+ const {readable, writable} = new TransformStream();
+ const head = readableString(
+ `
${renderHeadToString({
+ request,
+ remixContext,
+ Head,
+ })}`,
+ );
+ const end = readableString(`
`);
+
const body = await renderToReadableStream(
,
);
+ Promise.resolve()
+ .then(() => head.pipeTo(writable, {preventClose: true}))
+ .then(() => body.pipeTo(writable, {preventClose: true}))
+ .then(() => end.pipeTo(writable));
+
responseHeaders.set('Content-Type', 'text/html');
- return new Response(body, {
+ return new Response(readable, {
status: responseStatusCode,
headers: responseHeaders,
});
diff --git a/app/root.tsx b/app/root.tsx
index 8acd08f..f04a1d8 100644
--- a/app/root.tsx
+++ b/app/root.tsx
@@ -14,6 +14,7 @@ import {
import type {Shop} from '@shopify/hydrogen/storefront-api-types';
import styles from './styles/app.css';
import favicon from '../public/favicon.svg';
+import {createHead} from 'remix-island';
export const links: LinksFunction = () => {
return [
@@ -40,17 +41,21 @@ export async function loader({context}: LoaderArgs) {
return {layout};
}
+export const Head = createHead(() => (
+ <>
+
+
+ >
+));
+
export default function App() {
const data = useLoaderData();
const {name} = data.layout.shop;
return (
-
-
-
-
-
+ <>
+
Hello, {name}
This is a custom storefront powered by Hydrogen
@@ -58,7 +63,7 @@ export default function App() {
-
+ >
);
}
diff --git a/package-lock.json b/package-lock.json
index 04efc0e..7c33dde 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,7 +16,8 @@
"graphql": "^16.6.0",
"graphql-tag": "^2.12.6",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "remix-island": "^0.1.2"
},
"devDependencies": {
"@remix-run/dev": "1.12.0",
@@ -13186,6 +13187,17 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/remix-island": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/remix-island/-/remix-island-0.1.2.tgz",
+ "integrity": "sha512-1vXF56y7ZKb8caUduCKdkbxObAxZnTO+arQ94QlwKK6a7wVozGCfiOOk3lr919rm7cy54eeqOVI0hud3cfHlLg==",
+ "peerDependencies": {
+ "@remix-run/react": ">= 1",
+ "@remix-run/server-runtime": ">= 1",
+ "react": ">= 16.8",
+ "react-dom": ">= 16.8"
+ }
+ },
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
diff --git a/package.json b/package.json
index 92ddecf..4083505 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,8 @@
"graphql": "^16.6.0",
"graphql-tag": "^2.12.6",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "remix-island": "^0.1.2"
},
"devDependencies": {
"@remix-run/dev": "1.12.0",