···11+---
22+'@urql/solid-start': minor
33+---
44+55+Fix SSR runtime failures caused by importing SolidStart's `action` API at module load time by reading `action` from `Provider` context instead.
+5
.changeset/shiny-pets-give.md
···11+---
22+'@urql/solid-start': patch
33+---
44+55+Fix `createSubscription` to use `@urql/solid-start` context instead of re-exporting the Solid-only implementation from `@urql/solid`.
+35-27
docs/basics/solid-start.md
···61616262### Providing the `Client`
63636464-To make use of the `Client` in SolidStart we will provide it via Solid's Context API using the `Provider` export. The Provider also needs the `query` function from `@solidjs/router`:
6464+To make use of the `Client` in SolidStart we will provide it via Solid's Context API using the `Provider` export. The Provider also needs the `query` and `action` functions from `@solidjs/router`:
65656666```jsx
6767// src/root.tsx or src/app.tsx
6868-import { Router, query } from '@solidjs/router';
6868+import { Router, action, query } from '@solidjs/router';
6969import { FileRoutes } from '@solidjs/start/router';
7070import { Suspense } from 'solid-js';
7171import { createClient, Provider, cacheExchange, fetchExchange } from '@urql/solid-start';
···7878export default function App() {
7979 return (
8080 <Router
8181- root={(props) => (
8282- <Provider value={{ client, query }}>
8181+ root={props => (
8282+ <Provider value={{ client, query, action }}>
8383 <Suspense>{props.children}</Suspense>
8484 </Provider>
8585 )}
···9090}
9191```
92929393-Now every route and component inside the `Provider` can use GraphQL queries that will be sent to our API. The `query` function is provided in the context so that `createQuery` can access it automatically without manual injection.
9393+Now every route and component inside the `Provider` can use GraphQL queries and mutations that will be sent to our API. The `query` and `action` functions are provided in context so that `createQuery` and `createMutation` can access them automatically.
94949595## Queries
9696···135135```
136136137137The `createQuery` primitive integrates with SolidStart's data fetching system:
138138+1381391. It wraps SolidStart's `query()` function to execute URQL queries with proper router context
1391402. The `query` function is automatically retrieved from the URQL context (no manual injection needed)
1401413. The second parameter is a cache key (string) for SolidStart's router
···165166166167export default function TodosPage() {
167168 const params = useParams();
168168-169169+169170 const queryTodos = createQuery(TodosListQuery, 'todos-paginated', {
170171 variables: {
171172 from: parseInt(params.page) * 10,
172173 limit: 10,
173174 },
174175 });
175175-176176+176177 const result = createAsync(() => queryTodos());
177178178179 return (
···203204```
204205205206Available policies:
207207+206208- `cache-first` (default): Prefer cached results, fall back to network
207209- `cache-only`: Only use cached results, never send network requests
208210- `network-only`: Always send a network request, ignore cache
···247249 const handleRefresh = () => {
248250 // Invalidate the todos query using keyFor
249251 const key = keyFor(TodosQuery);
250250- client.reexecuteOperation(client.createRequestOperation('query', {
251251- key,
252252- query: TodosQuery
252252+ client.reexecuteOperation(client.createRequestOperation('query', {
253253+ key,
254254+ query: TodosQuery
253255 }));
254256 };
255257···437439438440const createTodoAction = action(async (formData: FormData) => {
439441 const title = formData.get('title') as string;
440440-442442+441443 // Perform mutation
442444 const result = await client.mutation(CreateTodo, { title }).toPromise();
443443-445445+444446 if (!result.error) {
445447 // Revalidate multiple routes if needed
446448 await revalidate(['/todos', '/']);
447449 }
448448-450450+449451 return result;
450452});
451453```
···453455#### Choosing Between Approaches
454456455457**Use urql's `keyFor` and `reexecuteOperation` when:**
458458+456459- You need to refetch a specific query after a mutation
457460- You want fine-grained control over which queries to refresh
458461- You're working with multiple queries on the same route and only want to refetch one
459462460463**Use SolidStart's `revalidate` when:**
464464+461465- You want to refresh all data on a route
462466- You're navigating to a different route and want to ensure fresh data
463467- You want to leverage SolidStart's routing system for cache management
···543547```
544548545549The `createMutation` primitive returns a tuple:
550550+5465511. A reactive state object containing `fetching`, `error`, and `data`
5475522. An execute function that triggers the mutation
548553···576581 const handleSubmit = async (formData: FormData) => {
577582 const title = formData.get('title') as string;
578583 const result = await createTodo({ title });
579579-584584+580585 if (!result.error) {
581586 return redirect('/todos');
582587 }
···623628624629const handleUpdate = async () => {
625630 const result = await updateTodo({ id: '1', title: 'Updated' });
626626-631631+627632 if (result.error) {
628633 console.error('Oh no!', result.error);
629634 } else {
···641646642647const handleUpdate = async () => {
643648 const result = await updateTodo({ id: '1', title: 'Updated' });
644644-649649+645650 if (result.error) {
646651 // CombinedError with network or GraphQL errors
647652 console.error('Mutation failed:', result.error);
648648-653653+649654 // Check for specific error types
650655 if (result.error.networkError) {
651656 console.error('Network error:', result.error.networkError);
···661666662667## Subscriptions
663668664664-For GraphQL subscriptions, `@urql/solid-start` re-exports the `createSubscription` primitive from `@urql/solid`, as subscriptions work identically on both client and server:
669669+For GraphQL subscriptions, `@urql/solid-start` provides a `createSubscription` primitive that uses the same SolidStart `Provider` context as `createQuery` and `createMutation`:
665670666671```jsx
667672import { gql } from '@urql/core';
···696701 <div>
697702 <h2>Live Updates</h2>
698703 <ul>
699699- <For each={todos()}>
700700- {(todo) => <li>{todo.title}</li>}
701701- </For>
704704+ <For each={todos()}>{todo => <li>{todo.title}</li>}</For>
702705 </ul>
703706 </div>
704707 );
···739742 fetchOptions: () => {
740743 const event = getRequestEvent();
741744 const headers: Record<string, string> = {};
742742-745745+743746 // Forward cookies for authenticated requests
744747 if (event) {
745748 const cookie = event.request.headers.get('cookie');
···747750 headers.cookie = cookie;
748751 }
749752 }
750750-753753+751754 return { headers };
752755 },
753756});
···757760758761### When to Use Each Package
759762760760-| Use Case | Package | Why |
761761-|----------|---------|-----|
762762-| Client-side SPA | `@urql/solid` | Optimized for client-only apps, uses SolidJS reactivity patterns |
763763-| SolidStart SSR App | `@urql/solid-start` | Integrates with SolidStart's routing, SSR, and action system |
763763+| Use Case | Package | Why |
764764+| ------------------ | ------------------- | ---------------------------------------------------------------- |
765765+| Client-side SPA | `@urql/solid` | Optimized for client-only apps, uses SolidJS reactivity patterns |
766766+| SolidStart SSR App | `@urql/solid-start` | Integrates with SolidStart's routing, SSR, and action system |
764767765768### Key Differences
766769767770#### Queries
768771769772**@urql/solid** (Client-side):
773773+770774```tsx
771775import { createQuery } from '@urql/solid';
772776···775779```
776780777781**@urql/solid-start** (SSR):
782782+778783```tsx
779784import { createQuery } from '@urql/solid-start';
780785import { createAsync } from '@solidjs/router';
···788793#### Mutations
789794790795**@urql/solid** (Client-side):
796796+791797```tsx
792798import { createMutation } from '@urql/solid';
793799···797803```
798804799805**@urql/solid-start** (SSR with Actions):
806806+800807```tsx
801808import { createMutation } from '@urql/solid-start';
802809import { useAction, useSubmission } from '@solidjs/router';
···818825### Migration
819826820827If you're moving from a SolidJS SPA to SolidStart:
828828+8218291. Change imports from `@urql/solid` to `@urql/solid-start`
8228302. Wrap queries with `createAsync()`
8238313. Update mutations to use the action pattern with `useAction()` and `useSubmission()`
···22export * from '@urql/core';
3344// Context exports
55-export { type UseClient, type UseQuery, type UrqlContext } from './context';
66-export { useClient, useQuery, Provider } from './context';
55+export {
66+ type UseAction,
77+ type UseClient,
88+ type UseQuery,
99+ type UrqlContext,
1010+} from './context';
1111+export { useAction, useClient, useQuery, Provider } from './context';
712813// Query exports
914export { createQuery } from './createQuery';
···1217export { type CreateMutationAction } from './createMutation';
1318export { createMutation } from './createMutation';
14191515-// Subscription exports - re-exported from @urql/solid (no SolidStart-specific changes needed)
2020+// Subscription exports
1621export {
1722 type CreateSubscriptionArgs,
1823 type CreateSubscriptionState,
1924 type CreateSubscriptionExecute,
2025 type CreateSubscriptionResult,
2126 type SubscriptionHandler,
2222- createSubscription,
2323-} from '@urql/solid';
2727+} from './createSubscription';
2828+export { createSubscription } from './createSubscription';
24292530// Utility exports
2631export { type MaybeAccessor } from './utils';