<html lang="en">
<head></head>
<body>

<form id="mainForm" method="post" action="https://stackblitz.com/run" target="_self">
<input type="hidden" name="project[files][.gitignore]" value="
dist
.solid
.output
.vercel
.netlify
netlify
.vinxi

# Environment
.env
.env*.local

# dependencies
/node_modules

# IDEs and editors
/.idea
.project
.classpath
*.launch
.settings/

# Temp
gitignore

# System Files
.DS_Store
Thumbs.db
">
<input type="hidden" name="project[files][README.md]" value="# SolidStart

Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com);

## Creating a project

```bash
# create a new project in the current directory
npm init solid@latest

# create a new project in my-app
npm init solid@latest my-app
```

## Developing

Once you&#39;ve created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:

```bash
npm run dev

# or start the server and open the app in a new browser tab
npm run dev -- --open
```

## Building

Solid apps are built with _presets_, which optimise your project for deployment to different environments.

By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`.

## This project was created with the [Solid CLI](https://solid-cli.netlify.app)
">
<input type="hidden" name="project[files][app.config.ts]" value="import { defineConfig } from &#39;@solidjs/start/config&#39;

export default defineConfig({})
">
<input type="hidden" name="project[files][package.json]" value="{&quot;name&quot;:&quot;@tanstack/query-example-solid-start-streaming&quot;,&quot;private&quot;:true,&quot;type&quot;:&quot;module&quot;,&quot;scripts&quot;:{&quot;dev&quot;:&quot;vinxi dev&quot;,&quot;build&quot;:&quot;vinxi build&quot;,&quot;start&quot;:&quot;vinxi start&quot;,&quot;version&quot;:&quot;vinxi version&quot;},&quot;dependencies&quot;:{&quot;@solidjs/meta&quot;:&quot;^0.29.4&quot;,&quot;@solidjs/router&quot;:&quot;^0.15.3&quot;,&quot;@solidjs/start&quot;:&quot;^1.1.3&quot;,&quot;@tanstack/solid-query&quot;:&quot;https://pkg.pr.new/TanStack/query/@tanstack/solid-query@2163cc3&quot;,&quot;@tanstack/solid-query-devtools&quot;:&quot;https://pkg.pr.new/TanStack/query/@tanstack/solid-query-devtools@2163cc3&quot;,&quot;solid-js&quot;:&quot;^1.9.7&quot;,&quot;vinxi&quot;:&quot;^0.5.3&quot;},&quot;engines&quot;:{&quot;node&quot;:&quot;&gt;=18&quot;}}">
<input type="hidden" name="project[files][tsconfig.json]" value="{
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;ESNext&quot;,
    &quot;module&quot;: &quot;ESNext&quot;,
    &quot;moduleResolution&quot;: &quot;Bundler&quot;,
    &quot;allowSyntheticDefaultImports&quot;: true,
    &quot;esModuleInterop&quot;: true,
    &quot;jsx&quot;: &quot;preserve&quot;,
    &quot;jsxImportSource&quot;: &quot;solid-js&quot;,
    &quot;allowJs&quot;: true,
    &quot;strict&quot;: true,
    &quot;noEmit&quot;: true,
    &quot;types&quot;: [&quot;vinxi/client&quot;, &quot;vite/client&quot;],
    &quot;isolatedModules&quot;: true,
    &quot;paths&quot;: {
      &quot;~/*&quot;: [&quot;./src/*&quot;]
    }
  }
}
">
<input type="hidden" name="project[files][public/favicon.ico]" value="https://pkg.pr.new/template/a375c160-f37d-4248-8639-be8a081ae75b">
<input type="hidden" name="project[files][src/app.css]" value="body {
  font-family:
    Gordita, Roboto, Oxygen, Ubuntu, Cantarell, &#39;Open Sans&#39;, &#39;Helvetica Neue&#39;,
    sans-serif;
  line-height: 1.5;
}

a {
  margin-right: 1rem;
}

main {
  text-align: center;
  padding: 1em;
  margin: 0 auto;
}

h1 {
  color: #335d92;
  text-transform: uppercase;
  font-size: 2.5rem;
  font-weight: 100;
  line-height: 1.1;
  margin: 2.5rem auto 0 auto;
  max-width: 14rem;
}

p {
  max-width: 14rem;
  margin: 1rem auto;
  line-height: 1.35;
}

@media (min-width: 480px) {
  h1 {
    max-width: none;
  }

  p {
    max-width: none;
  }
}

.loader {
  color: #888;
  margin-top: 1rem;
}

.error {
  color: red;
  margin-top: 1rem;
}

.description {
  max-width: 60rem;
  margin: 3rem auto;
}

.description p {
  line-height: 1.5;
}

.description *:not(:first-child) {
  margin-top: 1rem;
}

.description_img {
  max-width: 100%;
  border-radius: 4px;
}

.example {
  border: 1px solid #ddd;
  padding: 1rem;
  max-width: 50rem;
  text-align: left;
  margin: 1rem auto;
}

.example__header {
  display: flex;
}

.example__title {
  font-size: 1rem;
  font-weight: bold;
  flex-grow: 1;
}

.example--table {
  padding: 0.5rem;
}

.example--table th,
.example--table td {
  padding: 4px 12px;
  white-space: nowrap;
}
">
<input type="hidden" name="project[files][src/app.tsx]" value="// @refresh reload
import { MetaProvider, Title } from &#39;@solidjs/meta&#39;
import { A, Router } from &#39;@solidjs/router&#39;
import { FileRoutes } from &#39;@solidjs/start/router&#39;
import { Suspense } from &#39;solid-js&#39;
import { SolidQueryDevtools } from &#39;@tanstack/solid-query-devtools&#39;
import { QueryClient, QueryClientProvider } from &#39;@tanstack/solid-query&#39;
import &#39;./app.css&#39;

export default function App() {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
        staleTime: 5000,
      },
    },
  })

  return (
    &lt;QueryClientProvider client={queryClient}&gt;
      &lt;SolidQueryDevtools /&gt;
      &lt;Router
        root={(props) =&gt; (
          &lt;MetaProvider&gt;
            &lt;Title&gt;SolidStart - Basic&lt;/Title&gt;
            &lt;a href=&quot;/&quot;&gt;Home&lt;/a&gt;
            &lt;a href=&quot;/streamed&quot;&gt;Streamed&lt;/a&gt;
            &lt;a href=&quot;/deferred&quot;&gt;Deferred&lt;/a&gt;
            &lt;a href=&quot;/mixed&quot;&gt;Mixed&lt;/a&gt;
            &lt;a href=&quot;/with-error&quot;&gt;With Error&lt;/a&gt;
            &lt;a href=&quot;/hydration&quot;&gt;Hydration&lt;/a&gt;
            &lt;A preload={true} href=&quot;/prefetch&quot;&gt;
              Prefetch
            &lt;/A&gt;
            &lt;a href=&quot;/batch-methods&quot;&gt;Batching Methods&lt;/a&gt;
            &lt;Suspense&gt;{props.children}&lt;/Suspense&gt;
          &lt;/MetaProvider&gt;
        )}
      &gt;
        &lt;FileRoutes /&gt;
      &lt;/Router&gt;
    &lt;/QueryClientProvider&gt;
  )
}
">
<input type="hidden" name="project[files][src/entry-client.tsx]" value="// @refresh reload
import { mount, StartClient } from &#39;@solidjs/start/client&#39;

const app = document.getElementById(&#39;app&#39;)
if (!app) throw new Error(&#39;Missing #app element&#39;)

mount(() =&gt; &lt;StartClient /&gt;, app)
">
<input type="hidden" name="project[files][src/entry-server.tsx]" value="// @refresh reload
import { createHandler, StartServer } from &#39;@solidjs/start/server&#39;

export default createHandler(() =&gt; (
  &lt;StartServer
    document={({ assets, children, scripts }) =&gt; (
      &lt;html lang=&quot;en&quot;&gt;
        &lt;head&gt;
          &lt;meta charset=&quot;utf-8&quot; /&gt;
          &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot; /&gt;
          &lt;link rel=&quot;icon&quot; href=&quot;/favicon.ico&quot; /&gt;
          {assets}
        &lt;/head&gt;
        &lt;body&gt;
          &lt;div id=&quot;app&quot;&gt;{children}&lt;/div&gt;
          {scripts}
        &lt;/body&gt;
      &lt;/html&gt;
    )}
  /&gt;
))
">
<input type="hidden" name="project[files][src/global.d.ts]" value="/// &lt;reference types=&quot;@solidjs/start/env&quot; /&gt;
">
<input type="hidden" name="project[files][public/imgs/deferred.png]" value="https://pkg.pr.new/template/3d735f2d-e7c7-4518-b587-cc86aadded68">
<input type="hidden" name="project[files][public/imgs/streaming.png]" value="https://pkg.pr.new/template/faafbb56-182f-4061-8cc2-74549fed15b5">
<input type="hidden" name="project[files][src/components/example.tsx]" value="import type { ParentComponent } from &#39;solid-js&#39;

export interface ExampleProps {
  title: string
  deferStream?: boolean
  sleep?: number
}

export const Example: ParentComponent&lt;ExampleProps&gt; = (props) =&gt; {
  return (
    &lt;div class=&quot;example&quot;&gt;
      &lt;div class=&quot;example__header&quot;&gt;
        &lt;div class=&quot;example__title&quot;&gt;{props.title}&lt;/div&gt;
        &lt;div&gt;[deferStream={String(props.deferStream || false)}]&lt;/div&gt;
        &lt;div style={{ &#39;margin-left&#39;: &#39;10px&#39; }}&gt;
          [simulated sleep: {props.sleep || 0}ms]
        &lt;/div&gt;
      &lt;/div&gt;

      {props.children}
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/components/post-viewer.tsx]" value="import { useQuery } from &#39;@tanstack/solid-query&#39;
import { resetErrorBoundaries } from &#39;solid-js&#39;
import { createSignal } from &#39;solid-js&#39;
import { For } from &#39;solid-js&#39;
import { Example } from &#39;./example&#39;
import { QueryBoundary } from &#39;./query-boundary&#39;
import type { Component } from &#39;solid-js&#39;
import { fetchPost } from &#39;~/utils/api&#39;

export interface PostViewerProps {
  deferStream?: boolean
  sleep?: number
  simulateError?: boolean
}

export const PostViewer: Component&lt;PostViewerProps&gt; = (props) =&gt; {
  const [simulateError, setSimulateError] = createSignal(props.simulateError)
  const [postId, setPostId] = createSignal(1)

  const query = useQuery(() =&gt; ({
    queryKey: [&#39;posts&#39;, postId()],
    queryFn: () =&gt;
      fetchPost({
        postId: postId(),
        sleep: props.sleep,
        simulateError:
          simulateError() || (simulateError() !== false &amp;&amp; postId() === 5),
      }),
    deferStream: props.deferStream,
    throwOnError: true,
  }))

  return (
    &lt;Example
      title=&quot;Post Query&quot;
      deferStream={props.deferStream}
      sleep={props.sleep}
    &gt;
      &lt;div style={{ &#39;margin-top&#39;: &#39;20px&#39; }}&gt;
        &lt;button
          onClick={() =&gt; {
            setPostId(Math.max(postId() - 1, 1))
            resetErrorBoundaries()
          }}
        &gt;
          Previous Post
        &lt;/button&gt;
        &lt;button
          onClick={() =&gt; {
            setPostId(Math.min(postId() + 1, 100))
            resetErrorBoundaries()
          }}
        &gt;
          Next Post
        &lt;/button&gt;
      &lt;/div&gt;

      {/* NOTE: without this extra wrapping div, for some reason solid ends up printing two errors... feels like a bug in solid. */}
      &lt;div&gt;
        &lt;QueryBoundary
          query={query}
          loadingFallback={&lt;div class=&quot;loader&quot;&gt;loading post...&lt;/div&gt;}
          errorFallback={(err, retry) =&gt; (
            &lt;div&gt;
              &lt;div class=&quot;error&quot;&gt;{err.message}&lt;/div&gt;
              &lt;button
                onClick={() =&gt; {
                  setSimulateError(false)
                  retry()
                }}
              &gt;
                retry
              &lt;/button&gt;
            &lt;/div&gt;
          )}
        &gt;
          {(posts) =&gt; (
            &lt;For each={posts}&gt;
              {(post) =&gt; (
                &lt;div style={{ &#39;margin-top&#39;: &#39;20px&#39; }}&gt;
                  &lt;b&gt;
                    [post {postId()}] {post.title}
                  &lt;/b&gt;
                  &lt;p&gt;{post.body}&lt;/p&gt;
                &lt;/div&gt;
              )}
            &lt;/For&gt;
          )}
        &lt;/QueryBoundary&gt;
      &lt;/div&gt;
    &lt;/Example&gt;
  )
}
">
<input type="hidden" name="project[files][src/components/query-boundary.tsx]" value="import { ErrorBoundary, Match, Suspense, Switch, children } from &#39;solid-js&#39;
import type { UseQueryResult } from &#39;@tanstack/solid-query&#39;
import type { JSX } from &#39;solid-js&#39;

export interface QueryBoundaryProps&lt;T = unknown&gt; {
  query: UseQueryResult&lt;T, Error&gt;

  /**
   * Triggered when the data is initially loading.
   */
  loadingFallback?: JSX.Element

  /**
   * Triggered when fetching is complete, but the returned data was falsey.
   */
  notFoundFallback?: JSX.Element

  /**
   * Triggered when the query results in an error.
   */
  errorFallback?: (err: Error, retry: () =&gt; void) =&gt; JSX.Element

  /**
   * Triggered when fetching is complete, and the returned data is not falsey.
   */
  children: (data: Exclude&lt;T, null | false | undefined&gt;) =&gt; JSX.Element
}

/**
 * Convenience wrapper that handles suspense and errors for queries. Makes the results of query.data available to
 * children (as a render prop) in a type-safe way.
 */
export function QueryBoundary&lt;T&gt;(props: QueryBoundaryProps&lt;T&gt;) {
  return (
    &lt;Suspense fallback={props.loadingFallback}&gt;
      &lt;ErrorBoundary
        fallback={(err: Error, reset) =&gt;
          props.errorFallback ? (
            props.errorFallback(err, async () =&gt; {
              await props.query.refetch()
              reset()
            })
          ) : (
            &lt;div&gt;
              &lt;div class=&quot;error&quot;&gt;{err.message}&lt;/div&gt;
              &lt;button
                onClick={async () =&gt; {
                  await props.query.refetch()
                  reset()
                }}
              &gt;
                retry
              &lt;/button&gt;
            &lt;/div&gt;
          )
        }
      &gt;
        &lt;Switch&gt;
          {/* &lt;Match when={props.query.isError}&gt;
            {props.errorFallback ? (
              props.errorFallback
            ) : (
              &lt;div&gt;
                &lt;div class=&quot;error&quot;&gt;{props.query.error?.message}&lt;/div&gt;
                &lt;button
                  onClick={() =&gt; {
                    props.query.refetch();
                  }}
                &gt;
                  retry
                &lt;/button&gt;
              &lt;/div&gt;
            )}
          &lt;/Match&gt; */}

          &lt;Match when={!props.query.isFetching &amp;&amp; !props.query.data}&gt;
            {props.notFoundFallback ? (
              props.notFoundFallback
            ) : (
              &lt;div&gt;not found&lt;/div&gt;
            )}
          &lt;/Match&gt;

          &lt;Match when={props.query.data}&gt;
            {props.children(
              props.query.data as Exclude&lt;T, null | false | undefined&gt;,
            )}
          &lt;/Match&gt;
        &lt;/Switch&gt;
      &lt;/ErrorBoundary&gt;
    &lt;/Suspense&gt;
  )
}
">
<input type="hidden" name="project[files][src/components/user-info.tsx]" value="import { useQuery } from &#39;@tanstack/solid-query&#39;
import { createSignal } from &#39;solid-js&#39;
import { Example } from &#39;./example&#39;
import { QueryBoundary } from &#39;./query-boundary&#39;
import type { Component } from &#39;solid-js&#39;
import { fetchUser } from &#39;~/utils/api&#39;

export interface UserInfoProps {
  deferStream?: boolean
  sleep?: number
  simulateError?: boolean
  staleTime?: number
  gcTime?: number
}

export const userInfoQueryOpts = (props?: UserInfoProps) =&gt; ({
  queryKey: [&#39;user&#39;],
  queryFn: () =&gt; fetchUser(props),
  deferStream: props?.deferStream,
  staleTime: props?.staleTime,
  gcTime: props?.gcTime,
  throwOnError: true,
})

export const UserInfo: Component&lt;UserInfoProps&gt; = (props) =&gt; {
  const [simulateError, setSimulateError] = createSignal(props.simulateError)

  const query = useQuery(() =&gt;
    userInfoQueryOpts({ ...props, simulateError: simulateError() }),
  )

  return (
    &lt;Example
      title=&quot;User Query&quot;
      deferStream={props.deferStream}
      sleep={props.sleep}
    &gt;
      &lt;QueryBoundary
        query={query}
        loadingFallback={&lt;div class=&quot;loader&quot;&gt;loading user...&lt;/div&gt;}
        errorFallback={(err, retry) =&gt; (
          &lt;div&gt;
            &lt;div class=&quot;error&quot;&gt;{err.message}&lt;/div&gt;
            &lt;button
              onClick={() =&gt; {
                setSimulateError(false)
                retry()
              }}
            &gt;
              retry
            &lt;/button&gt;
          &lt;/div&gt;
        )}
      &gt;
        {(user) =&gt; (
          &lt;&gt;
            &lt;div&gt;id: {user.id}&lt;/div&gt;
            &lt;div&gt;name: {user.name}&lt;/div&gt;
            &lt;div&gt;queryTime: {user.queryTime}&lt;/div&gt;
            &lt;button
              onClick={() =&gt; {
                query.refetch()
              }}
            &gt;
              refetch
            &lt;/button&gt;
          &lt;/&gt;
        )}
      &lt;/QueryBoundary&gt;
    &lt;/Example&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/%5B...404%5D.tsx]" value="import { Title } from &#39;@solidjs/meta&#39;
import { HttpStatusCode } from &#39;@solidjs/start&#39;

export default function NotFound() {
  return (
    &lt;main&gt;
      &lt;Title&gt;Not Found&lt;/Title&gt;
      &lt;HttpStatusCode code={404} /&gt;
      &lt;h1&gt;Page Not Found&lt;/h1&gt;
      &lt;p&gt;
        Visit{&#39; &#39;}
        &lt;a href=&quot;https://start.solidjs.com&quot; target=&quot;_blank&quot;&gt;
          start.solidjs.com
        &lt;/a&gt;{&#39; &#39;}
        to learn how to build SolidStart apps.
      &lt;/p&gt;
    &lt;/main&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/batch-methods.tsx]" value="import { notifyManager, useQuery } from &#39;@tanstack/solid-query&#39;
import { createSignal } from &#39;solid-js&#39;
import { QueryBoundary } from &#39;~/components/query-boundary&#39;

function sleep(milliseconds: number) {
  return new Promise((res) =&gt; setTimeout(res, milliseconds))
}

function spin(milliseconds: number) {
  const start = performance.now()
  while (performance.now() - start &lt;= milliseconds) {
    // do nothing
  }
}

async function sayHello(name: string) {
  console.info(&#39;[api] sayHello.start&#39;)

  await sleep(500)

  // make the layout shift more obvious, it doesn&#39;t always happen
  console.time(&#39;[api] sayHello.spin&#39;)
  spin(20)
  console.timeEnd(&#39;[api] sayHello.spin&#39;)

  console.info(&#39;[api] sayHello.end&#39;)
  return `Hello ${name}`
}

export default function BatchMethods() {
  const [count, setCount] = createSignal(0)

  const hello = useQuery(() =&gt; ({
    queryKey: [&#39;hello&#39;, count()] as const,
    queryFn: ({ queryKey: [_, count] }) =&gt; sayHello(`solid ${count}`),
  }))

  return (
    &lt;div&gt;
      &lt;select
        value=&quot;timer&quot;
        ref={(el) =&gt; (el.value = &#39;timer&#39;)} // browser caches form input
        onInput={(e) =&gt; {
          const type = e.currentTarget.value
          if (type === &#39;raf&#39;) notifyManager.setScheduler(requestAnimationFrame)
          if (type === &#39;tick&#39;) notifyManager.setScheduler(queueMicrotask)
          if (type === &#39;timer&#39;)
            notifyManager.setScheduler((cb) =&gt; setTimeout(cb, 0))
        }}
      &gt;
        &lt;option value=&quot;raf&quot;&gt;requestAnimationFrame&lt;/option&gt;
        &lt;option value=&quot;timer&quot;&gt;setTimeout&lt;/option&gt;
        &lt;option value=&quot;tick&quot;&gt;queueMicrotick&lt;/option&gt;
      &lt;/select&gt;
      &lt;button class=&quot;increment&quot; onClick={() =&gt; setCount((x) =&gt; x + 1)}&gt;
        Clicks: {count()}
      &lt;/button&gt;
      &lt;p&gt;
        &lt;QueryBoundary loadingFallback={&#39;Loading...&#39;} query={hello}&gt;
          {(data) =&gt; &lt;div style={{ &#39;background-color&#39;: &#39;aqua&#39; }}&gt;{data}&lt;/div&gt;}
        &lt;/QueryBoundary&gt;
      &lt;/p&gt;
      &lt;div style={{ &#39;background-color&#39;: &#39;red&#39; }}&gt;
        Something below to demonstrate layout shift
      &lt;/div&gt;
      &lt;p&gt;
        Due to the way solidjs handles updates, sometimes the updating of a
        query results in DOM modifications triggering a rerender twice. This is
        perceived as a glitch in the layout of the webpage that usually lasts
        for one frame. By using another batching strategy in the browser,
        instead of the default setTimeout one, we can mitigate this issue. Try
        out requestAnimationFrame or queueMicrotick.
      &lt;/p&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/deferred.tsx]" value="import { Title } from &#39;@solidjs/meta&#39;
import { PostViewer } from &#39;~/components/post-viewer&#39;
import { UserInfo } from &#39;~/components/user-info&#39;

export default function Deferred() {
  return (
    &lt;main&gt;
      &lt;Title&gt;Solid Query - Deferred&lt;/Title&gt;

      &lt;h1&gt;Solid Query - Deferred Example&lt;/h1&gt;

      &lt;div class=&quot;description&quot;&gt;
        &lt;p&gt;
          Both queries are configured with deferStream=true, so the server will
          not start streaming HTML to the client until the queries have
          resolved. In this case we are not really taking advantage of streaming
          - this mimics traditional renderAsync + Suspense behavior. Note how
          the green bar in the devtools is much larger now - the client does not
          start receiving any information until 2+ seconds (both queries
          resolve).
        &lt;/p&gt;

        &lt;p&gt;
          Clients with javascript disabled will see the resolved state for both
          queries. (try turning off javascript and reloading this page)
        &lt;/p&gt;

        &lt;img
          class=&quot;description_img&quot;
          src=&quot;/imgs/deferred.png&quot;
          alt=&quot;devtools deferred requests&quot;
        /&gt;
      &lt;/div&gt;

      &lt;UserInfo sleep={2000} deferStream /&gt;

      &lt;PostViewer sleep={2000} deferStream /&gt;
    &lt;/main&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/hydration.tsx]" value="import { useQuery } from &#39;@tanstack/solid-query&#39;
import { Suspense, createSignal } from &#39;solid-js&#39;
import { NoHydration } from &#39;solid-js/web&#39;
import { Title } from &#39;@solidjs/meta&#39;
import type { UseQueryResult } from &#39;@tanstack/solid-query&#39;
import { fetchUser } from &#39;~/utils/api&#39;

export default function Hydration() {
  const query = useQuery(() =&gt; ({
    queryKey: [&#39;user&#39;],
    queryFn: () =&gt; fetchUser({ sleep: 500 }),
    deferStream: true,
  }))

  const [initialQueryState] = createSignal(JSON.parse(JSON.stringify(query)))

  return (
    &lt;main&gt;
      &lt;Title&gt;Solid Query - Hydration&lt;/Title&gt;

      &lt;h1&gt;Solid Query - Hydration Example&lt;/h1&gt;

      &lt;div class=&quot;description&quot;&gt;
        &lt;p&gt;
          Lists the query state as seen on the server, initial render on the
          client (right after hydration), and current client value. Ideally, if
          SSR is setup correctly, these values are exactly the same in all three
          contexts.
        &lt;/p&gt;
      &lt;/div&gt;

      &lt;button onClick={() =&gt; query.refetch()}&gt;Refetch&lt;/button&gt;

      &lt;table class=&quot;example example--table&quot;&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;th&gt;Context&lt;/th&gt;
            &lt;th&gt;data.name&lt;/th&gt;
            &lt;th&gt;isFetching&lt;/th&gt;
            &lt;th&gt;isFetched&lt;/th&gt;
            &lt;th&gt;isPending&lt;/th&gt;
            &lt;th&gt;isRefetching&lt;/th&gt;
            &lt;th&gt;isLoading&lt;/th&gt;
            &lt;th&gt;isStale&lt;/th&gt;
            &lt;th&gt;isSuccess&lt;/th&gt;
            &lt;th&gt;isError&lt;/th&gt;
            &lt;th&gt;error&lt;/th&gt;
            &lt;th&gt;fetchStatus&lt;/th&gt;
            &lt;th&gt;dataUpdatedAt&lt;/th&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;

        &lt;tbody&gt;
          &lt;Suspense&gt;
            &lt;NoHydration&gt;
              &lt;QueryStateRow context=&quot;server&quot; query={query} /&gt;
            &lt;/NoHydration&gt;

            &lt;QueryStateRow
              context=&quot;client (initial render)&quot;
              query={initialQueryState()!}
            /&gt;

            &lt;QueryStateRow context=&quot;client&quot; query={query} /&gt;
          &lt;/Suspense&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
    &lt;/main&gt;
  )
}

type QueryState = UseQueryResult&lt;
  {
    id: string
    name: string
    queryTime: number
  },
  Error
&gt;

const QueryStateRow = (props: { context: string; query: QueryState }) =&gt; {
  return (
    &lt;tr&gt;
      &lt;td&gt;{props.context}&lt;/td&gt;
      &lt;td&gt;{props.query.data?.name}&lt;/td&gt;
      &lt;td&gt;{String(props.query.isFetching)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.isFetched)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.isPending)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.isRefetching)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.isLoading)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.isStale)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.isSuccess)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.isError)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.error)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.fetchStatus)}&lt;/td&gt;
      &lt;td&gt;{String(props.query.dataUpdatedAt)}&lt;/td&gt;
    &lt;/tr&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/index.tsx]" value="import { Title } from &#39;@solidjs/meta&#39;

export default function Home() {
  return (
    &lt;main&gt;
      &lt;Title&gt;Solid Query v5&lt;/Title&gt;

      &lt;h1&gt;Solid Query v5&lt;/h1&gt;

      &lt;p&gt;
        This demo demonstrates how Solid Query can be used in SSR, with
        streaming support. Use the links in the top left to navigate between the
        various examples.
      &lt;/p&gt;
    &lt;/main&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/mixed.tsx]" value="import { Title } from &#39;@solidjs/meta&#39;
import { PostViewer } from &#39;~/components/post-viewer&#39;
import { UserInfo } from &#39;~/components/user-info&#39;

export default function Mixed() {
  return (
    &lt;main&gt;
      &lt;Title&gt;Solid Query - Mixed&lt;/Title&gt;

      &lt;h1&gt;Solid Query - Mixed Example&lt;/h1&gt;

      &lt;div class=&quot;description&quot;&gt;
        &lt;p&gt;
          You may want to require that key queries resolve before the initial
          HTML is streamed to the client, while allowing the rest of your
          queries to stream to the client as they resolve. A common use case for
          this is to populate SEO meta tags and/or social graph information for
          unfurl scenarios such as sharing the page as a link in Slack.
        &lt;/p&gt;

        &lt;p&gt;
          In this example, the quick (100ms) user query has deferStream set to
          true, while the more expensive post query (1000ms) is streamed to the
          client when ready. Clients with javascript disabled will see the
          resolved state for the user query, and the loading state for the post
          query. (try turning off javascript and reloading this page)
        &lt;/p&gt;
      &lt;/div&gt;

      &lt;UserInfo deferStream sleep={100} /&gt;

      &lt;PostViewer sleep={1000} /&gt;
    &lt;/main&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/prefetch.tsx]" value="import { useQueryClient } from &#39;@tanstack/solid-query&#39;
import { isServer } from &#39;solid-js/web&#39;
import { Title } from &#39;@solidjs/meta&#39;
import { UserInfo, userInfoQueryOpts } from &#39;~/components/user-info&#39;

export const route = {
  load: () =&gt; {
    const queryClient = useQueryClient()
    // Prefetching the user info and caching it for 15 seconds.
    queryClient.prefetchQuery(userInfoQueryOpts({ sleep: 500, gcTime: 15000 }))
  },
}

export default function Prefetch() {
  return (
    &lt;main&gt;
      &lt;Title&gt;Solid Query - Prefetch&lt;/Title&gt;

      &lt;h1&gt;Solid Query - Prefetch Example&lt;/h1&gt;

      &lt;div class=&quot;description&quot;&gt;
        &lt;p&gt;
          SolidStart now supports link prefetching. This means that when a user
          hovers over a link, the browser can prefetch the data for that page
          before the user even clicks on the link. This can make navigating
          around your app feel much faster.
        &lt;/p&gt;
        &lt;p&gt;
          To see this in action, go to the home page and reload the page. Then
          hover over the &quot;Prefetch&quot; link in the navigation. You should see the
          user data prefetch in the background and in the devtools. When you
          click on the link, the page should load instantly.
        &lt;/p&gt;
      &lt;/div&gt;

      &lt;UserInfo sleep={500} /&gt;
    &lt;/main&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/streamed.tsx]" value="import { Title } from &#39;@solidjs/meta&#39;
import { PostViewer } from &#39;~/components/post-viewer&#39;
import { UserInfo } from &#39;~/components/user-info&#39;

export default function Streamed() {
  return (
    &lt;main&gt;
      &lt;Title&gt;Solid Query - Streamed&lt;/Title&gt;

      &lt;h1&gt;Solid Query - Streamed Example&lt;/h1&gt;

      &lt;div class=&quot;description&quot;&gt;
        &lt;p&gt;
          HTML is streamed from the server ASAP, reducing key metrics such as
          TTFB and TTI. Suspended queries are streamed to the client when they
          resolve on the server. This is represented in your devtools by the
          green and blue chunks of the waterfall.
        &lt;/p&gt;

        &lt;p&gt;
          Clients with javascript disabled will see the loading state for both
          queries. (try turning off javascript and reloading this page)
        &lt;/p&gt;

        &lt;img
          class=&quot;description_img&quot;
          src=&quot;/imgs/streaming.png&quot;
          alt=&quot;devtools streaming request&quot;
        /&gt;
      &lt;/div&gt;

      &lt;UserInfo sleep={2500} /&gt;

      &lt;PostViewer sleep={300} /&gt;
    &lt;/main&gt;
  )
}
">
<input type="hidden" name="project[files][src/routes/with-error.tsx]" value="import { Title } from &#39;@solidjs/meta&#39;
import { PostViewer } from &#39;~/components/post-viewer&#39;
import { UserInfo } from &#39;~/components/user-info&#39;

export default function Streamed() {
  return (
    &lt;main&gt;
      &lt;Title&gt;Solid Query - Errors&lt;/Title&gt;

      &lt;h1&gt;Solid Query - Errors&lt;/h1&gt;

      &lt;div class=&quot;description&quot;&gt;
        &lt;p&gt;
          For more control over error handling, try leveraging the `Switch`
          component and watching the reactive `query.isError` property. See
          `compoennts/query-boundary.tsx` for one possible approach.
        &lt;/p&gt;
      &lt;/div&gt;

      &lt;UserInfo sleep={10} deferStream simulateError /&gt;

      &lt;PostViewer sleep={3000} deferStream simulateError /&gt;
    &lt;/main&gt;
  )
}
">
<input type="hidden" name="project[files][src/utils/api.ts]" value="interface PostData {
  userId: number
  id: number
  title: string
  body: string
}

const doSleep = (ms: number) =&gt; new Promise((r) =&gt; setTimeout(r, ms))

export const fetchPost = async ({
  postId,
  simulateError,
  sleep,
}: {
  postId: number
  simulateError?: boolean
  sleep?: number
}) =&gt; {
  console.info(&#39;[api] fetchPost.start&#39;, { postId, sleep, simulateError })

  let response
  if (!simulateError) {
    response = await fetch(
      `https://jsonplaceholder.typicode.com/posts/${postId}`,
    ).then((res) =&gt; res.json())
  }

  // simulate extra latency to make things like streaming behavior more clear
  if (sleep) {
    await doSleep(sleep)
  }

  console.info(&#39;[api] fetchPost.done&#39;, { postId, sleep, simulateError })

  if (simulateError) {
    throw new Error(&#39;API request to get post was not OK&#39;)
  }

  return [response] as PostData[]
}

export const fetchUser = async ({
  sleep,
  simulateError,
}: { sleep?: number; simulateError?: boolean } = {}) =&gt; {
  console.info(&#39;[api] fetchUser.start&#39;, { sleep, simulateError })

  if (sleep) {
    await doSleep(sleep)
  }

  console.info(&#39;[api] fetchUser.done&#39;, { sleep, simulateError })

  if (simulateError) {
    throw new Error(&#39;API request to get user was not OK&#39;)
  }

  return {
    id: &#39;abc&#39;,
    name: `john doe`,
    queryTime: Date.now(),
  }
}
">
<input type="hidden" name="project[description]" value="generated by https://pkg.pr.new">
<input type="hidden" name="project[template]" value="node">
<input type="hidden" name="project[title]" value="@tanstack/query-example-solid-start-streaming">
</form>
<script>document.getElementById("mainForm").submit();</script>

</body></html>