Skip to content

Latest commit

 

History

History

vike-solid-query

npm version

vike-solid-query

Enables your Solid components to fetch data using TanStack Query.

Note

You'll also get progressive rendering and supports for triggering SolidJS Suspense and ErrorBoundary components when the query is in a pending or error state.

Installation
Basic usage
QueryBoundary
<head> tags
See also

Installation

  1. npm install @tanstack/solid-query vike-solid-query

  2. Extend +config.js:

    // pages/+config.js
    
    import vikeSolid from 'vike-solid/config'
    import vikeSolidQuery from 'vike-solid-query/config'
    
    export default {
      // ...
      extends: [vikeSolid, vikeSolidQuery]
    }

Note

The vike-solid-query extension requires vike-solid.

Basic usage

import { createQuery } from "@tanstack/solid-query";
import { Suspense } from "solid-js";

const Movie = (props: { id }) => {
    const query = createQuery(() => ({
        queryKey: ["movies", props.id],
        queryFn: () =>
        fetch(`https://brillout.github.io/star-wars/api/films/${props.id}.json`)
        .then((res) => res.json()),
    }));

  return (
    <Suspense fallback={"Loading ..."}>
      Title: <b>{query.data?.title}</b>
    </Suspense>
  )
}

QueryBoundary

// Define the loading fallback
<QueryBoundary query={query} loadingFallback={Loading}>
    {(data) => <div>{data.something}</div>}
</QueryBoundary>
// Define the loading and error fallback 
<QueryBoundary query={query} loadingFallback={Loading} errorFallback={Error}>
    {(data) => <div>{data.something}</div>}
</QueryBoundary>
// Define the loading, error and not found fallback 
<QueryBoundary query={query} loadingFallback={Loading} errorFallback={Error} notFoundFallback={NotFound}>
    {(data) => <div>{data.something}</div>}
</QueryBoundary>

Types :

query: CreateQueryResult<T, Error>;  
loadingFallback?: JSX.Element;  
notFoundFallback?: JSX.Element;  
errorFallback?: JSX.Element | ((err: any, reset: () => void) => JSX.Element);  
children: (data: Exclude<T, null | false | undefined>) => JSX.Element;
// Movie.tsx

import { createQuery } from "@tanstack/solid-query";
import { QueryBoundary } from "vike-solid-query";

function Movie(props: { id: string }) {
  const query = createQuery(() => ({
    queryKey: ["movies", props.id],
    queryFn: () =>
        fetch(`https://brillout.github.io/star-wars/api/films/${props.id}.json`)
        .then((res) => res.json())
  }));

  return (
    <QueryBoundary
      query={query}
      loadingFallback={<p>Loading movie {props.id}</p>}
      errorFallback={(err, reset) => (
        <>
          <div>Failed to load movie {props.id}</div>
          <button
            onClick={async () => {
              reset();
              await query.refetch();
            }}
          >
            Retry
          </button>
        </>
      )}
    >
      {(movie) => (
        <div>
            Title: <b>{movie.title}</b>
        </div>
      )}
    </QueryBoundary>
  );
}

<head> tags

To set tags such as <title> and <meta name="description"> based on fetched data, you can use <Config>, <Head>, and useConfig().

import { createQuery } from "@tanstack/solid-query";
import { Config } from 'vike-solid/Config'
import { Head } from 'vike-solid/Head'
import { QueryBoundary } from "vike-solid-query";
import { For } from "solid-js";

function Movies() {
  const query = createQuery(() => ({
    queryKey: ["movies"],
    queryFn: () => fetch('https://star-wars.brillout.com/api/films.json')
  }));
  
  return (
    <QueryBoundary query={query} loadingFallback={<p>Loading movies ...</p>}>
      {(movies) => (
        <>
          <Config title={`${movies.length} Star Wars movies`} />
          <Head>
            <meta name="description" content={`All ${movies.length} movies from the Star Wars franchise.`} />
          </Head>
          <h1>Star Wars Movies</h1>
          <ol>
            <For each={movies}>
              {(movie) => (
                <li>{movie.title}</li>
              )}
            </For>
          </ol>
        </>
      )}
    </QueryBoundary>
  )
}

Settings

You can modify the defaults defined by QueryClient.

// +config.js

export default {
  queryClientConfig: {
    defaultOptions: {
      queries: {
        staleTime: 60 * 1000
      }
    }
  }
}

See also