Skip to content

Commit

Permalink
fix(useConfig): add support for useConfig() with HTML streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
phonzammi committed Sep 6, 2024
1 parent e52345c commit 72b20ec
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 6 deletions.
19 changes: 17 additions & 2 deletions packages/vike-solid/hooks/useConfig/useConfig-server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export { useConfig };
import type { PageContext } from "vike/types";
import type { PageContextInternal } from "../../types/PageContext.js";
import type { ConfigFromHook } from "../../types/Config.js";
import type { ConfigFromHook, Stream } from "../../types/Config.js";
import { usePageContext } from "../usePageContext.js";
import { getPageContext } from "vike/getPageContext";
import { objectKeys } from "../../utils/objectKeys.js";
Expand All @@ -20,7 +20,14 @@ function useConfig(): (config: ConfigFromHook) => void {

// Component
pageContext = usePageContext();
return (config: ConfigFromHook) => setPageContextConfigFromHook(config, pageContext);
return (config: ConfigFromHook) => {
if (!pageContext._headAlreadySet) {
setPageContextConfigFromHook(config, pageContext);
} else {
// <head> already sent to the browser => send DOM-manipulating scripts during HTML streaming
apply(config, pageContext._stream!);
}
};
}

const configsClientSide = ["title"];
Expand All @@ -44,3 +51,11 @@ function setPageContextConfigFromHook(config: ConfigFromHook, pageContext: PageC
}
});
}

function apply(config: ConfigFromHook, stream: Stream) {
const { title } = config;
if (title) {
const htmlSnippet = `<script>document.title = ${JSON.stringify(title)}</script>`;
stream.write(htmlSnippet);
}
}
14 changes: 11 additions & 3 deletions packages/vike-solid/integration/onRenderHtml.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,24 @@ const onRenderHtml: OnRenderHtmlAsync = async (
</html>`;
};

function getPageHtml(pageContext: PageContextServer) {
function getPageHtml(pageContext: PageContextServer & PageContextInternal) {
let pageHtml: string | ReturnType<typeof dangerouslySkipEscape> | TPipe = "";
if (pageContext.Page) {
if (!pageContext.config.stream) {
pageHtml = dangerouslySkipEscape(renderToString(() => getPageElement(pageContext)));
} else if (pageContext.config.stream === "web") {
pageHtml = renderToStream(() => getPageElement(pageContext)).pipeTo;
pageHtml = renderToStream(() => getPageElement(pageContext), {
onCompleteShell(info) {
pageContext._stream ??= info;
},
}).pipeTo;
stampPipe(pageHtml, "web-stream");
} else {
pageHtml = renderToStream(() => getPageElement(pageContext)).pipe;
pageHtml = renderToStream(() => getPageElement(pageContext), {
onCompleteShell(info) {
pageContext._stream ??= info;
},
}).pipe;
stampPipe(pageHtml, "node-stream");
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/vike-solid/types/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,4 @@ export type ConfigFromHook = PickWithoutGetter<
>;
export type ConfigFromHookResolved = Omit<ConfigFromHook, ConfigsCumulative> &
Pick<Vike.ConfigResolved, ConfigsCumulative>;
export type Stream = { write: (v: string) => void };
3 changes: 2 additions & 1 deletion packages/vike-solid/types/PageContext.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { JSX } from "solid-js";
import type { ConfigFromHookResolved } from "./Config";
import type { ConfigFromHookResolved, Stream } from "./Config";

// https://vike.dev/pageContext#typescript
declare global {
Expand All @@ -15,4 +15,5 @@ declare global {
export type PageContextInternal = {
_configFromHook?: ConfigFromHookResolved;
_headAlreadySet?: boolean;
_stream?: Stream;
};

0 comments on commit 72b20ec

Please sign in to comment.