diff --git a/CHANGELOG.md b/CHANGELOG.md
index 489d2314f54..4bd9308c691 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,9 @@
- Make the `client` field of the `MutationResult` type non-optional, since it is always provided.
[@glasser](https://github.com/glasser) in [#6617](https://github.com/apollographql/apollo-client/pull/6617)
+- Allow passing an asynchronous `options.renderFunction` to `getMarkupFromTree`.
+ [@richardscarrott](https://github.com/richardscarrott) in [#6576](https://github.com/apollographql/apollo-client/pull/6576)
+
## Apollo Client 3.0.2
## Bug Fixes
diff --git a/src/react/ssr/getDataFromTree.ts b/src/react/ssr/getDataFromTree.ts
index 4e2b53a143e..9d639827a38 100644
--- a/src/react/ssr/getDataFromTree.ts
+++ b/src/react/ssr/getDataFromTree.ts
@@ -18,7 +18,9 @@ export function getDataFromTree(
export type GetMarkupFromTreeOptions = {
tree: React.ReactNode;
context?: { [key: string]: any };
- renderFunction?: (tree: React.ReactElement) => string;
+ renderFunction?: (
+ tree: React.ReactElement,
+ ) => string | PromiseLike;
};
export function getMarkupFromTree({
@@ -31,24 +33,26 @@ export function getMarkupFromTree({
}: GetMarkupFromTreeOptions): Promise {
const renderPromises = new RenderPromises();
- function process(): Promise | string {
+ function process(): Promise {
// Always re-render from the rootElement, even though it might seem
// better to render the children of the component responsible for the
// promise, because it is not possible to reconstruct the full context
// of the original rendering (including all unknown context provider
// elements) for a subtree of the original component tree.
const ApolloContext = getApolloContext();
- const html = renderFunction(
- React.createElement(
- ApolloContext.Provider,
- { value: { ...context, renderPromises } },
- tree
- )
- );
- return renderPromises.hasPromises()
- ? renderPromises.consumeAndAwaitPromises().then(process)
- : html;
+ return new Promise(resolve => {
+ const element = React.createElement(
+ ApolloContext.Provider,
+ { value: { ...context, renderPromises }},
+ tree,
+ );
+ resolve(renderFunction(element));
+ }).then(html => {
+ return renderPromises.hasPromises()
+ ? renderPromises.consumeAndAwaitPromises().then(process)
+ : html;
+ });
}
return Promise.resolve().then(process);