{
  "id": "348b4703edfcd980bc5aba3f",
  "source": "solid:signals",
  "type": "github-document",
  "title": "data-mutation",
  "content": "---\ntitle: \"Data mutation\"\n---\n\nMutating data on a server is a common task in most applications.\n[Solid Router](/solid-router) provides [actions](/solid-router/concepts/actions) to manage data mutations effectively.\n\nSolidStart builds upon the capabilities of actions, extending their scope to provide a comprehensive, full-stack solution for data mutations.\n\nThis page does not cover the foundational concepts from Solid Router.\nIf you are a beginner, we highly recommend starting with the [actions documentation](/solid-router/concepts/actions).\nYou can also find many practical examples in the [data mutation how-to guide](/solid-start/guides/data-mutation).\n\n## Server functions and actions\n\nServer functions allow an action to run exclusively on the server.\nThis enables performing sensitive operations—such as writing to a database or working with sessions—directly within the action.\n\n```tsx\nimport { action, redirect } from \"@solidjs/router\";\nimport { useSession } from \"vinxi/http\";\nimport { db } from \"./db\";\n\nconst logoutAction = action(async () =\u003e {\n\t\"use server\";\n\tconst session = await useSession({\n\t\tpassword: process.env.SESSION_SECRET as string,\n\t\tname: \"session\",\n\t});\n\n\tif (session.data.sessionId) {\n\t\tawait session.clear();\n\t\tawait db.session.delete({ id: sessionId });\n\t}\n\n\tthrow redirect(\"/\");\n}, \"logout\");\n```\n\nIn this example, the entire `logoutAction` runs on the server.\nIt safely accesses the session to retrieve the `sessionId` and performs a database deletion without exposing this logic to the client.\nThe `redirect` then navigates the user back to the home page.\n\n## Single-flight mutations\n\nWhen a piece of data changes on the server, the new data needs to be fetched so the UI doesn't fall out of sync.\nTraditionally, this is done in two separate HTTP requests: one to update the data, and a second to fetch the new data.\n\nSingle-flight mutations are a unique feature of SolidStart that handles this pattern in a single request.\nThis is enabled when two requirements are met:\n\n1. The action that updates the data must execute on the server using server functions.\n2. The data that the action updated must be preloaded.\n   If the action performs a redirect, preloading needs to happen on the destination page.\n\n```tsx title=\"src/routes/products/[id].tsx\"\nimport {\n\taction,\n\tquery,\n\tcreateAsync,\n\ttype RouteDefinition,\n\ttype RouteSectionProps,\n} from \"@solidjs/router\";\nimport { db } from \"./db\";\n\nconst updateProductAction = action(async (id: string, formData: FormData) =\u003e {\n\t\"use server\";\n\tconst name = formData.get(\"name\")?.toString();\n\tawait db.products.update(id, { name });\n}, \"updateProduct\");\n\nconst getProductQuery = query(async (id: string) =\u003e {\n\t\"use server\";\n\treturn await db.products.get(id);\n}, \"product\");\n\nexport const route = {\n\tpreload: ({ params }) =\u003e getProductQuery(params.id as string),\n} satisfies RouteDefinition;\n\nexport default function ProductDetail(props: RouteSectionProps) {\n\tconst product = createAsync(() =\u003e getProductQuery(props.params.id as string));\n\n\treturn (\n\t\t\u003cdiv\u003e\n\t\t\t\u003cp\u003eCurrent name: {props.data.product?.name}\u003c/p\u003e\n\t\t\t\u003cform\n\t\t\t\taction={updateProductAction.with(props.params.id as string)}\n\t\t\t\tmethod=\"post\"\n\t\t\t\u003e\n\t\t\t\t\u003cinput name=\"name\" placeholder=\"New name\" /\u003e\n\t\t\t\t\u003cbutton\u003eSave\u003c/button\u003e\n\t\t\t\u003c/form\u003e\n\t\t\u003c/div\u003e\n\t);\n}\n```\n\nIn this example, `updateProductAction` updates the product within a server function, and `getProductQuery` is responsible for fetching the product data.\nNote that `getProductQuery` is preloaded on the route.\n\nWhen a user submits the form, a single POST request is sent to the server.\nAfter the action completes, `getProductQuery` is automatically revalidated.\nBecause it's preloaded, SolidStart can trigger the revalidation on the server and stream the result back to the client in the same response.",
  "url": "https://github.com/solidjs/solid-docs/blob/HEAD/src/routes/solid-start/building-your-application/data-mutation.mdx",
  "metadata": {
    "path": "src/routes/solid-start/building-your-application/data-mutation.mdx",
    "repo": "solidjs/solid-docs",
    "repo_url": "https://github.com/solidjs/solid-docs.git",
    "size": 3796,
    "source_type": "github"
  },
  "hash": "dde180ad28632637e14e123b82c7b2bafa8b952f4e08db2d07f8f2de7135bbe6",
  "timestamp": "2026-02-23T11:43:00.193857292+01:00"
}