Skip to content
qt

Basics

Three ways to invalidate

query-tags works with Server Functions, oRPC middleware, and raw API handlers. Pick your style — the SSE event is the same.

What to watch for

  • All three patterns result in the same SSE invalidation event
  • The client doesn't care HOW the server invalidated — it just reacts to matching tags
  • oRPC middleware is zero-boilerplate — invalidation happens automatically on success
View Source
SF

Server Function

TanStack Start createServerFn with explicit invalidateTags call

export const addTodoServerFn = createServerFn({ method: "POST" })
  .handler(async ({ data }) => {
    const created = await createTodo(data.name);
    await tagInvalidation.invalidateTags({
      tags: [appTags.todos()],
    });
    return created;
  });
oR

oRPC Middleware

Automatic invalidation via middleware — zero manual calls

export const addTodo = baseProcedure
  .use(orpcMiddleware.invalidateOnSuccess({
    tags: [appTags.todos()],
  }))
  .handler(async ({ input }) => {
    return createTodo(input.name);
  });
// invalidateTags called automatically on success!
AH

API Route Handler

Direct invalidation from a custom API handler

export async function POST(request: Request) {
  const body = await request.json();
  const created = await createTodo(body.name);

  await tagInvalidation.invalidateTags({
    tags: [appTags.todos()],
  });

  return Response.json(created);
}

Live: Tagged query (all patterns feed this)

    Try it (via Server Function)

    This demo uses the Server Function pattern. The SSE event is identical regardless of which pattern triggered it.