forge42dev / remix-toast Goto Github PK
View Code? Open in Web Editor NEWServer side implementation of toast notifications in Remix
License: MIT License
Server side implementation of toast notifications in Remix
License: MIT License
login.tsx
return redirectWithSuccess( '/dashboard/expenses', { message: 'you are login', description: 'Yes indeed you are logged in', }, { headers: await createUserSession(user), } );
root.tsx
useEffect(() => { if (toast?.type === 'error') { notify.error(toast.message); } if (toast?.type === 'success') { notify.success(toast.message); } if (toast?.type === 'info') { notify.info(toast.message); } }, [toast]);
Maybe I'm missing something, but how can I set auth cookies when we run redirectWithSuccess
?
const headers = new Headers();
headers.append("Set-Cookie", await setCookie(AUTH_COOKIE, '...'))
headers.append("Set-Cookie", await setCookie(AUTH_EXP_COOKIE, '...'))
return redirectWithSuccess("/login", "You are logged in!");
I thought there would be a third parameter that is compatible with Remix's default redirect
.
return redirectWithSuccess("/login", "You are logged in!", { headers });
Is there a way to set toast and non-toast headers in one-go?
Good day,
Your documentation for Sonner Toast package indicates that a <ToastContainer/>
should be used. I suppose it should be <Toaster/>
instead?
im not sure if it's an issue with the sonner library, I haven't tested it yet.
I'm using the sample project in the source code and I'm still getting the issue. (https://github.com/Code-Forge-Net/remix-toast/tree/main/src/test-apps/cloudflare)
1.click the "click me"button (it works fine)
2.change the url(http://localhost:3000/test) to (http://localhost:3000/),and redirect it.
3.click the "click me"button again, the style of the toast is invalid.
It would be nice to provide a way to edit this config so users aren't stuck with this hardcoded cookie name and secret. I'm looking at trying this out in the Epic Stack and this seems to be the only blocker at the moment
const Route = () => {
const data = useLoaderData<typeof loader>();
console.log('data.toast', data.toast);
In this setup, I see output in terminal data.toast { message: 'Welcome back!', type: 'success' }
when the page loads, but client-side it is always data.toast undefined
. I believe client-side is needed for this to work. What am I missing?
I need it client-side because I need to call toast.create
, e.g.
const Route = () => {
const data = useLoaderData<typeof loader>();
console.log('data.toast', data.toast);
useEffect(() => {
if (data.toast) {
toast.create({
description: data.toast.message,
title: data.toast.type,
});
}
}, [data.toast]);
toast.create
comes from https://park-ui.com/docs/panda/components/toast
Hi I followed the initial steps to get the toast going with sonner see below, but it is not working.
Expected behaviour:
Toast to work when being called.
What is happening:
Toast gets called on refresh twice, and doesn't get cleared, if I refresh it continues to get called.
Is something else missing?
from route
// ... imports
export const action = async ({ request }: ActionFunctionArgs) => {
return jsonWithError(null, 'There are errors in the form')
}
from root
// ... imports
export const loader = async ({ request }: LoaderFunctionArgs) => {
// ... otherHeaders logic
const { toast, headers: toastHeaders } = await getToast(request)
return json(
{
toast
},
{
headers: {
// ...otherHeaders,
...toastHeaders
}
}
)
}
export default function Home() {
const { toast: serverToast } = useLoaderData<typeof loader>()
useEffect(() => {
console.log('serverToast', serverToast)
if (serverToast?.type === 'success') {
toast.success(serverToast.message)
}
if (serverToast?.type === 'error') {
toast.error(serverToast.message)
}
}, [serverToast])
return (
<html lang="en">
<head>
<Meta />
<title>Basic Example With Remix Toast</title>
<Links />
</head>
<body>
{children}
<Toaster />
<ScrollRestoration />
<Scripts />
</body>
</html>
)
}
using
devDeps
@remix-run/dev -> 2.8.1
@remix-run/eslint-config -> 2.8.1
deps
@remix-run/serve -> 2.8.1
@remix-run/react -> 2.8.1
@remix-run/node -> 2.8.1
sonner -> 1.4.0
Edit: Just wanted to say congrats with the lib though, fantastic explanation on the blog.
It is on your blog, but not in the repo
Hi @AlemTuzlak, thank you for the wonderful project!
I was wondering if it is possible to show a toast without utilizing the redirect helpers.
For example, when deleting an item from a list of items I utilize a fetcher and avoid a redirect in accordance with suggested practices. I want to show a toast to the user when the action returns. Is this possible?
Thanks!
Currently remix-toast
heavily depends on json
and redirect
response utilities. With the new SingleFetch, Remix recommends moving away from response utils and start using the ResponseStub.
What would be the correct path to update the usage of remix-toasts
to new singleFetch? Would the API need a change to accept the ResponseStub?
Any chance of getting an optional description
field in ToastMessage
? This will allow descriptions in Sonner.
See here: https://sonner.emilkowal.ski/toast#api-reference
I believe it would require an additional field here: https://github.com/Code-Forge-Net/remix-toast/blob/main/src/schema.ts#L3
export const toastMessageSchema = z.object({
message: z.string(),
type: z.custom<"info" | "success" | "error" | "warning">(),
description: z.string().optional()
});
Thanks!
Hi,
Thanks you for this great library.
I was thinking if you'd be up for adding JSON utility classes just like you did for redirect.
The use-case is that sometimes you don't wan't to redirect, just send back some data and show a toast.
That should be fairly easy to implement.
What do you think?
Hey! Thanks for this, I've been playing around with it and it's working nicely.
I did notice that the secret seems hardcoded and I can see in the source code that it could complicate the import of the library if the secret is a passable string as you'd need to initiate the cookieFactory creation.
I thought about looking for a specifically named ENV var and then gracefully falling back to the default value, but that is not simple either, for example, Cloudflare (which is my preferred platform) doesn't have the node process.env.
Maybe this can be done so that you can do as now, but use defaults, and if you want to control both the secret and other values such as the session name, then you'd have to first call an initiator, passing in the values.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.