Server-Side Rendering
tsproxy supports full SSR with Next.js using react-instantsearch's getServerState and InstantSearchSSRProvider.
How It Works
getServerSidePropscallsgetServerState()which renders the search UI on the server- The proxy API executes the search and returns results
- The HTML includes the rendered product grid — no JavaScript needed for first paint
InstantSearchSSRProviderhydrates the client with the server state
Next.js Pages Router
import { InstantSearch, InstantSearchSSRProvider, getServerState } from "react-instantsearch";
import { renderToString } from "react-dom/server";
import { createSearchClient } from "@tsproxy/js";
import type { GetServerSideProps } from "next";
const API_URL = "http://localhost:3000";
function SearchApp() {
const searchClient = useMemo(
() => createSearchClient({ url: API_URL }),
[],
);
return (
<InstantSearch searchClient={searchClient} indexName="products">
{/* Your search components */}
</InstantSearch>
);
}
export const getServerSideProps: GetServerSideProps = async () => {
const serverState = await getServerState(<SearchApp />, { renderToString });
return {
props: {
serverState: JSON.parse(JSON.stringify(serverState)),
},
};
};
export default function SearchPage({ serverState }) {
return (
<InstantSearchSSRProvider {...serverState}>
<SearchApp />
</InstantSearchSSRProvider>
);
}URL Sync
Combine SSR with URL routing so search state is shareable and bookmarkable:
import { history } from "instantsearch.js/es/lib/routers";
function createRouting() {
return {
router: history({
cleanUrlOnDispose: false,
getLocation: () =>
typeof window !== "undefined"
? window.location
: new URL("http://localhost/search"),
}),
stateMapping: {
stateToRoute(uiState) {
const state = uiState["products"] || {};
return {
q: state.query || undefined,
page: state.page > 1 ? state.page : undefined,
};
},
routeToState(routeState) {
return {
products: {
query: routeState.q || "",
page: routeState.page ? Number(routeState.page) : undefined,
},
};
},
},
};
}
// Use in InstantSearch:
<InstantSearch routing={createRouting()} ... />URLs like /search?q=keyboard&page=2 are fully SSR'd — the server renders the results matching that query.
Verifying SSR
curl http://localhost:3001/search?q=keyboardThe HTML response will contain the actual product data (e.g., "Mechanical Keyboard") without requiring JavaScript.