{"id":13810485,"url":"https://github.com/ciscoheat/sveltekit-flash-message","last_synced_at":"2025-04-04T07:06:51.114Z","repository":{"id":54926831,"uuid":"522726337","full_name":"ciscoheat/sveltekit-flash-message","owner":"ciscoheat","description":"Send temporary data after redirect, usually from endpoints. Works with both SSR and client.","archived":false,"fork":false,"pushed_at":"2024-07-30T13:07:44.000Z","size":448,"stargazers_count":265,"open_issues_count":4,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-29T10:11:05.946Z","etag":null,"topics":["cookies","flash-messages","session","svelte","sveltekit"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/sveltekit-flash-message","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ciscoheat.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-08T22:30:52.000Z","updated_at":"2024-10-26T07:32:26.000Z","dependencies_parsed_at":"2023-02-10T23:31:05.976Z","dependency_job_id":"66c3836a-c835-4d68-b8c9-722d36819fc9","html_url":"https://github.com/ciscoheat/sveltekit-flash-message","commit_stats":{"total_commits":62,"total_committers":1,"mean_commits":62.0,"dds":0.0,"last_synced_commit":"e34e6fb7b07b619e103e4cb626334d985760fdd8"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ciscoheat%2Fsveltekit-flash-message","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ciscoheat%2Fsveltekit-flash-message/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ciscoheat%2Fsveltekit-flash-message/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ciscoheat%2Fsveltekit-flash-message/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ciscoheat","download_url":"https://codeload.github.com/ciscoheat/sveltekit-flash-message/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247135144,"owners_count":20889421,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cookies","flash-messages","session","svelte","sveltekit"],"created_at":"2024-08-04T02:00:55.986Z","updated_at":"2025-04-04T07:06:51.089Z","avatar_url":"https://github.com/ciscoheat.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# sveltekit-flash-message ⚡\n\nThis [SvelteKit](https://svelte.dev/docs/kit/) library passes temporary data to the next request, usually in [form actions](https://kit.svelte.dev/docs/form-actions) and [endpoints](https://kit.svelte.dev/docs/routing#server). It's useful for displaying a success or failure message after a POST, which should not always be displayed at the form, rather as a message on the page that the request was redirected to.\n\nSince it's a temporary message it's also known as a \"flash message\", especially known from PHP apps, since it's easy to add this functionality with PHP's built-in session handling. With SvelteKit it's a bit harder, but this library was made to alleviate that, encouraging well-behaved web apps that [Redirects after Post](https://www.theserverside.com/news/1365146/Redirect-After-Post).\n\n## Installation\n\n```\npnpm i -D sveltekit-flash-message\n```\n\n```\nnpm i -D sveltekit-flash-message\n```\n\n## How to use\n\n### 1. Add the flash message to app.d.ts (Typescript only)\n\nIn `src/app.d.ts`, add the type for the flash message to `App.PageData` as an optional property called `flash`. It can be as simple as a `string`, or something more advanced. It has to be serializable though, so only JSON-friendly data structures. For example:\n\n**src/app.d.ts**\n\n```ts\n// See https://svelte.dev/docs/kit/types#app.d.ts\n// for information about these interfaces\ndeclare global {\n  namespace App {\n    // interface Error {}\n    // interface Locals {}\n    interface PageData {\n      flash?: { type: 'success' | 'error'; message: string };\n    }\n    // interface PageState {}\n    // interface Platform {}\n  }\n}\n\nexport {};\n```\n\n### 2. Wrap the load function of a top-level +layout or +page route\n\nIf you're not using any [load functions](https://kit.svelte.dev/docs/load), this is a simple step. Create a `src/routes/+layout.server.ts` file with the following content:\n\n**src/routes/+layout.server.ts**\n\n```ts\nexport { load } from 'sveltekit-flash-message/server';\n```\n\nBut most likely you already have a top-level `load` function, in which case you can import `loadFlash` and wrap your load function with it:\n\n**src/routes/+layout.server.ts**\n\n```ts\nimport { loadFlash } from 'sveltekit-flash-message/server';\n\nexport const load = loadFlash(async (event) =\u003e {\n  const data = { someOther: 'data' };\n  return data;\n});\n```\n\n**Note:** There cannot be any additional `load/loadFlash` calls in routes below, as the flash cookie is deleted when it is found the first time.\n\n### 3. Display the flash message\n\nImport `getFlash` in a layout or page component to display the flash message. `getFlash` will return a store that you'll use to access the message:\n\n**src/routes/+layout.svelte**\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { getFlash } from 'sveltekit-flash-message';\n  import { page } from '$app/state';\n\n  const flash = getFlash(page);\n\u003c/script\u003e\n\n{#if $flash}\n  {@const bg = $flash.type == 'success' ? '#3D9970' : '#FF4136'}\n  \u003cdiv style:background-color={bg} class=\"flash\"\u003e{$flash.message}\u003c/div\u003e\n{/if}\n```\n\n## 4. Send flash messages\n\n### Server-side\n\nTo send a flash message from the server, import `redirect` from `sveltekit-flash-message/server` and use it in [load functions](https://kit.svelte.dev/docs/load#redirects) and [form actions](https://kit.svelte.dev/docs/form-actions#anatomy-of-an-action-redirects).\n\n**Note:** With SvelteKit 2, you don't need to [throw the redirect](https://kit.svelte.dev/docs/migrating-to-sveltekit-2#redirect-and-error-are-no-longer-thrown-by-you), just call `redirect`. If you're still on SvelteKit 1, `throw` the function call.\n\n```ts\nimport { redirect } from 'sveltekit-flash-message/server'\n\n// The most specific: Redirect with a specific HTTP status to a specific location.\nredirect(\n  status: number,\n  location: string,\n  message: App.PageData['flash'],\n  event: RequestEvent | Cookies\n)\n\n// Makes a 303 redirect to a specific location.\nredirect(\n  location: string,\n  message: App.PageData['flash'],\n  event: RequestEvent | Cookies\n)\n\n// Makes a 303 redirect to the current location.\nredirect(\n  message: App.PageData['flash'],\n  event: RequestEvent\n)\n\n// For compatibility, the sveltekit signature can also be used, which will send no flash message.\nredirect(\n  status: number,\n  location: string,\n)\n```\n\n#### Form action example\n\n**src/routes/todos/+page.server.ts**\n\n```ts\nimport { redirect } from 'sveltekit-flash-message/server';\n\nexport const actions = {\n  default: async ({ request, locals, cookies }) =\u003e {\n    const form = await request.formData();\n\n    await api('POST', `/todos/${locals.userid}`, {\n      text: form.get('text')\n    });\n\n    redirect('/', { type: 'success', message: \"That's the entrepreneur spirit!\" }, cookies);\n  }\n};\n```\n\n#### Endpoint example\n\n**src/routes/todos/+server.ts**\n\n```ts\nimport type { RequestEvent } from '@sveltejs/kit';\nimport { redirect } from 'sveltekit-flash-message/server';\n\nexport const POST = async ({ cookies }) =\u003e {\n  redirect('/', { type: 'success', message: 'Endpoint POST successful!' }, cookies);\n};\n```\n\n#### Setting without redirecting\n\nIf you want to display a flash message without redirecting, as an error message when validation fails for example, you can use the `setFlash` function:\n\n```ts\nimport { fail } from '@sveltejs/kit';\nimport { setFlash } from 'sveltekit-flash-message/server';\n\nexport const actions = {\n  default: async ({ request, cookies }) =\u003e {\n    const form = await request.formData();\n\n    if (!form.get('text')) {\n      setFlash({ type: 'error', message: 'Please enter text.' }, cookies);\n      return fail(400);\n    }\n  }\n};\n```\n\n### Client-side\n\nIf you want to update the flash message on the client, use `getFlash` in any component:\n\n**src/routes/some-route/+page.svelte**\n\n```svelte\n\u003cscript\u003e\n  import { getFlash } from 'sveltekit-flash-message';\n  import { page } from '$app/state';\n\n  const flash = getFlash(page);\n\n  function showMessage() {\n    $flash = { type: 'success', message: 'Updated from other component!' };\n  }\n\u003c/script\u003e\n\n\u003cbutton on:click={showMessage}\u003eShow flash message\u003c/button\u003e\n```\n\nThis will of course not set a cookie for the next request, it'll only update the flash message on the client.\n\n## Client-side fetching and redirecting\n\nThe flash message will update automatically on redirect or navigation, but when using [fetch](https://kit.svelte.dev/docs/web-standards#fetch-apis), you must call `updateFlash` afterwards:\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { updateFlash } from 'sveltekit-flash-message';\n  import { page } from '$app/state';\n\n  async function submitForm(e: Event) {\n    const form = e.target as HTMLFormElement;\n    const body = new FormData(e.target as HTMLFormElement);\n\n    await fetch(form.action, { method: 'POST', body });\n    await updateFlash(page);\n  }\n\u003c/script\u003e\n\n\u003cform method=\"POST\" action=\"/test\" on:submit|preventDefault={submitForm}\u003e\n  \u003cinput type=\"text\" name=\"test\" value=\"TEST\" /\u003e\n  \u003cbutton\u003eSubmit with fetch\u003c/button\u003e\n\u003c/form\u003e\n```\n\n`updateFlash` can take a second parameter, which is used to run a function **before** updating, so navigation events will pass through before showing the flash message. This is useful when you want to redirect based on the fetch response:\n\n```ts\nasync function submitForm(e: Event) {\n  const response = await fetch(new URL('/logout', $page.url), { method: 'POST' });\n  if (response.redirected) {\n    await updateFlash(page, () =\u003e goto(response.url, { invalidateAll: true }));\n  }\n}\n```\n\n## Toast messages, event-style\n\nA common use case for flash messages is to show a toast notification, but a toast is more of an event than data that should be displayed on the page, as we've done previously. But you can use the `flash` store in an [$effect](https://svelte.dev/docs/svelte/$effect) to handle this:\n\n**src/routes/+layout.svelte**\n\n```ts\nimport { getFlash } from 'sveltekit-flash-message';\nimport { page } from '$app/state';\nimport toast, { Toaster } from 'svelte-french-toast';\n\nconst flash = getFlash(page);\n\n$effect(() =\u003e {\n  if (!$flash) return;\n\n  toast($flash.message, {\n    icon: $flash.type == 'success' ? '✅' : '❌'\n  });\n\n  // Clear the flash message to avoid double-toasting.\n  $flash = undefined;\n});\n```\n\n## Flash message options\n\nWhen calling `getFlash`, you can specify options, which will be inherited for the current route and the ones below.\n\n```ts\nconst flash = getFlash(page, {\n  clearOnNavigate: true,\n  clearAfterMs: undefined,\n  clearArray: false,\n  flashCookieOptions: CookieSerializeOptions\n});\n```\n\nYou can also use `initFlash`, if you don't display a flash message in a certain layout but still want to set options for the routes below:\n\n```ts\nimport { initFlash } from 'sveltekit-flash-message';\nimport { page } from '$app/state';\n\ninitFlash(page, {\n  clearAfterMs: 10000\n});\n```\n\n### clearOnNavigate\n\nIf `true` (the default), the flash message will be removed when navigating to a different route.\n\n### clearAfterMs\n\nCan be set to a number of milliseconds before the flash message is automatically set to `undefined`.\n\n### clearArray\n\nIf you specify `App.PageData['flash']` as an array, the library will concatenate messages into the array instead of replacing them. But if you always want to clear the previous messages for arrays, set the `clearArray` option to `true`. If your flash message isn't an array, this option will have no effect.\n\n### flashCookieOptions\n\nYou can change the options for the cookie being sent, like this on the server:\n\n```ts\nimport { loadFlash, flashCookieOptions } from 'sveltekit-flash-message/server';\n\nflashCookieOptions.sameSite = 'lax';\n\nexport const load = loadFlash(async (event) =\u003e {\n  // ...load function...\n});\n```\n\nAnd correspondingly, on the client (in a top-level component):\n\n```ts\nimport { initFlash } from 'sveltekit-flash-message';\n\ninitFlash(page, {\n  flashCookieOptions: { sameSite: 'lax' }\n});\n```\n\nAll options can be found in the [cookie npm package](https://github.com/jshttp/cookie#options-1). Default options for the flash cookie are:\n\n```ts\n{\n  path: '/',\n  maxAge: 120,\n  sameSite: 'strict',\n  httpOnly: false // Setting this to true will most likely break things client-side.\n}\n```\n\nThe name of the cookie, `flash`, cannot be changed currently, let me know if that's inconvenient. ⚡\n\n## Securing the flash message\n\nSince the flash message is transferred in a cookie, it can be easily tampered with, so don't trust its content. Treat it like you do with any user data - hanging from a ten-foot pole over a fiery pit. 🔥 So never use `{@html}` to display it, and if you need to persist it for some reason, make sure you validate it.\n\n## Together with Superforms\n\nThe sister library to sveltekit-flash-message is [Superforms](https://superforms.rocks), the all-in-one solution for forms in SvelteKit. You can use them together without any extra work, but there are options for closer integration, [found here](https://superforms.rocks/flash-messages) on the Superforms website.\n\n# Notes\n\n## When setting cookies in a response\n\nIf you're using `+hooks.server.ts/js`, or anywhere you have access to `response`, calling `response.headers.set('set-cookie', ...)` will discard the flash message cookie. You must use `response.headers.append` instead.\n\n## Redirecting in the load function\n\nIn SvelteKit, links are [preloaded on hover](https://kit.svelte.dev/docs/link-options#data-sveltekit-preload-data) for increased responsiveness of the app. This can have the side-effect of accidentally setting a flash cookie, if a flash message redirect is made in a load function, and the user hovers over a link leading to it, so it is preloaded. To prevent this, set the `data-sveltekit-preload-data=\"tap\"` attribute on links where a redirect could happen in the load function.\n\n# Migration guides\n\n## From 0.x to 1.x\n\nThe only thing you need to do when upgrading to 1.x is to remove all calls to `updateFlash` in `use:enhance`.\n\n```diff\n \u003cform\n    method=\"POST\"\n-   use:enhance={() =\u003e\n-     ({ update }) =\u003e\n-       updateFlash(page, update)}\n+   use:enhance\n \u003e\n```\n\n## From 1.x to 2.x\n\n1. Rename functions:\n\n- `loadFlashMessage` is deprecated and renamed to `loadFlash`.\n- `initFlash` is only needed for configuration, `getFlash` can be used directly in most cases.\n\n2. If you've added the `beforeNavigate` snippet that clears the flash message after navigation, it's now automatic and can be removed. (It can be prevented by setting the `clearOnNavigate` option to `false`.)\n\n3. If you're using the snippet for clearing the message after a certain amount of time, you can remove it and use the `clearAfterMs` option instead.\n\n## Feedback and issues\n\nPlease [open a github issue](https://github.com/ciscoheat/sveltekit-flash-message/issues) for suggestions, if you find a bug or have feedback in general!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fciscoheat%2Fsveltekit-flash-message","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fciscoheat%2Fsveltekit-flash-message","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fciscoheat%2Fsveltekit-flash-message/lists"}