Well, there we go.
You are done.
You can close your laptop if you want, but, don't maybe.
Cuz, actually if you'd like I would love some feedback and
at the bottom of the readme at the root there is a feedback form.
So please do submit feedback on the workshop.
And I am happy to stand around here for
however longer to answer any general questions about Remix,
about building for the web, whatever, I am at your disposal.
Yeah, Ryan.
>> One of the features that Next.js has is the image optimization component.
Does Remix have any?
>> Yeah, great question.
So Remix doesn't have anything specifically for that.
And so on my website I built my own, and it works great and I wrote about it.
The one cool thing that Remix has, so for me let's see where's that?
This one.
For me, I am using Cloudnary and so lots of my solution just use it
basically generates this ridiculous, look at this thing.
That URL to make like, wow.
But yeah using the source set and sizes properties of the image tag.
It's actually really cool, but
yeah using some of coronaries fanciness to serve up the right image.
And Remix, you could absolutely build your own support for
something like this using a resource route.
And in fact, Jacob on the Remix team has built something
that he's got a demo somewhere on GitHub.
Where he has a resource route that allows you to change dimensions and compress and
whatever else for this specific device.
It's actually really cool and there are packages that you can use to say here's my
user agent, give me the best image for this.
So yes, you could build it yourself.
Eventually, Remix may have something that,
a Remix image package that just does all that stuff for you.
Until then, my site is open source and
you can totally steal all of this stuff if you want to.
Yep, here it is, blurable image.
It's pretty fun.
If you wanna also use Cloudinary.
This isn't actually specific to Cloudinary necessarily.
All that I need is the image element and a blurred data URL.
So yeah, you could build this with anything else.
Yeah.
>> This is related to the SPA question.
If you have multiple disparate dashboard data sources you
need on a page multiple grids, how might you approach it?
>> Let me make sure I understand the question.
So they're saying you have a dashboard and
multiple widgets on that dashboard from different data sources.
Most dashboards that I'm aware of like that will persist filters and
different things that in the URL for very good reason.
Then you can make all your filters and your check box selections and stuff, and
then copy paste the URL and send it to somebody else be like here,
look at this view, whatever.
So it's useful from that angle.
And in Remix, your loader can reference all of those things and go say,
okay, so these query prams are for this data source.
Let me go get the data for that.
And let me go get the data for that.
You can run all those in parallel or in concurrently with promise.all.
And so just go resolve on that stuff.
Send it up and then when the user changes the filter and stuff,
you're gonna go revalidate and it'll go grab the up to date data for that.
That would be my first approach at that.
The one challenge that you can run into, if yeah, that is possible
to run into in that situation is, what if it's just a silly amount of data.
And so you've got like a bunch of widgets and you're just changing this one widget,
the search params for that.
And you only wanna reload the data for that widget.
Well, you're loading all the data for all these different widgets and
so yeah, there's, I could see a argument to say, well,
I just wanna load the widget or this one widget.
So that you're gonna use a hook called useFetchers.
And that is what we're gonna talk about in the advanced Remix workshop.
But that allows you to run specific data fetches for
specific components and stuff.
So that would be the next thing to try and and you could create resource routes for
each widget.
But I would totally start with just a single loader.
It keys off of the search params goes to get all the data and slurps it back up to
the client that would be the easiest most straightforward approach to them.
And so on the subject of SPAs, cuz somebody
did ask about spas and now I'm reminded of that.
Remix has kinda funny spot with the SPA versus MPA conversation.
So originally the web was all MPAs.
That's multi page apps.
So every page is talking to the server generated,
maybe it's cached on the CDN, but every single page is individual.
And we ran into some problems with that.
We talked about it a little bit with the progressive enhancement stuff where it's
just a nicer user experience to not have to reload every page, right?
So then we started to kind of combine the two where you'd have
the back end framework generate some HTML and
then you'd like sprinkle some JavaScript in right?
And that worked not for very long, [LAUGH] because what happens there if you have
to duplicate templates between whatever is generating the HTML on the back end,
and whatever is updating the HTML on the front end, which is gonna be like,
maybe it's Ruby on the back end.
And it'll be JavaScript on the front end.
And so you not only do you have template duplication, but
you also have no way to share that code at all.
And so they fall out of date out of sync and it just does not work very nicely.
So we pretty quickly went from and frankly,
still plenty of people are doing JavaScript script sprinkles.
And a lot of those back end frameworks are still trying to do things
through the back end framework that like kinda makes that work.
We've got like hotwire and life view and stuff like that.
But very quickly a lot of people moved over to just saying hey this is so
hard to make these two work together.
I'm just gonna throw away all that we'll just use the SPA that is a single
page app it's all JavaScript only the client and the back end is just an API.
And my front end just hits that back end.
And then I can do transitions, cuz we got this cool new history API thing,
push date.
And now I can navigate without having to go back to the server all the time.
And I know that I can only ever give a status code of 200 but I don't care.
And so for a long time that's the way I built web apps, and I liked it that way.
I did not like the template duplication.
I did not like running Java on my machine at all.
[LAUGH] And so I was happy with just doing it all front end SPA only.
What Remix is doing is it's remixing the two.
Remix is both, in particular because of progressive enhancement, but
also because of hydration.
So it's server rendered HTML and then it's rehydrated.
And from that point on it's a SPA so
it starts out as an MPA rehydrates, now it's a SPA.
And there are a lot of benefits to being in that position
where you get the benefits of the low content layout shift.
Because if you do a SPA, you have to load the JavaScript and
then you go load all of the data.
And typically, you don't wanna just show a white screen.
So you're gonna show a loading spinner.
And yeah, if you showed a white screen, that would be even worse.
So you show a loading spinner.
Then you load the data and then you update.
That's called content layout shifts, the content is there and then shifted.
So that's not a great user experience.
And so with Remix you get the MPA benefits of not doing the content layout
shift with the SPA benefits of being able to do client side transitions and
animated transitions even and all that.
So yeah anyway hopefully that answers the question to the person who's asking
about Remix and SPAs asking question >> Yes I was gonna say you
mentioned a few things that you guys are already thinking about it.
What else is next for Remix?
>> What's coming up?
>> Yeah.
>> So the defer API is gonna be legit.
So this is the lever that allows you to say, well,
I'm actually okay with content layout shift.
Because it'll help me get a better time to first byte.
And that's important for me, or more often it will be, well,
that particular endpoint is really slow.
And I'd rather show the user a spinner rather than making them wait for
the page in the first place.
And so we'll talk about that in the Advanced Remix Workshop.
We need to make some more examples of Server Sent Events.
Because we released support for that a couple months ago.
And not many people are using it, and it's actually really great for
real time use cases even multiple user like this really cool.
As far as what else is next, the Remix router
work that should be released very soon.
That is gonna open up a lot of these features to people whether they
want to use a server rendering framework or not.
So you'll be able to use error boundaries, loaders, forms, actions.
All of this stuff in a regular react app without having to switch over to
a server rendered and Remix compiled thing.
Which I think it's actually really, really cool.
It also means that we can make adapters for other frameworks or for
non-framework if you don't want to have a framework at all you could
just use the Remix Router itself and have a ton of awesome features.
That work is gonna be pretty transformative for the web, I think.
I hesitate to talk about this too much because we haven't released anything yet.
So but I will anyway.
We are evaluating, well we're working on making it so
that you can use Remix with your own build tools.
So rather than requiring you to use the Remix compiler in the package
JSON in of each of these projects you'll see it's like Remix watch,
and Remix Dab, all Remix specific scripts.
It's all using esbuild under the hood.
Esbuild doesn't support CSS modules, it doesn't support hot module replacement.
And so, we'd have to build those ourselves.
And so we're instead going to support potentially Webpack and
Vite and others so that you can just bring in the remix conventions
in compiler into your whatever existing bundler you have.
And get hot module replacement CSS modules and
vanilla extract and whatever else you wanna use.
So that work is ongoing and very promising.
So that's another thing that I think the ultimate goal here is Ryan and
Michael just wanted to make it so
that when they use their kids website that it's using React router.
It's not garbage, not their kids,
the website their kids about their kids school website.
Cuz they would like go to these websites, and man this is not a good experience and
then they open up the dev tools.
And see that it's react right in there I did this.
So the idea behind Remix is to make it so
that the user experience of the web is better.
And we can only do that if we can get people to migrate over from whatever
they're using to Remix which will provide the better user experience.
And so having a compiler agnostic build system,
I think is an important step in that direction too.
So I'm excited about that also.
And in the future, Ryan actually has a demo of this have a build lists,
experience or you don't have a build.
You can do that right now, even with TypeScript in Deno,
and Bun actually supports Typescript and JSX.
So you just write up a regular React app and Bun no build and
that's really cool because you can deploy in five seconds.
That'd be pretty rad I think, welcome back PHP upload file to FTP server.
I just think that's pretty cool.
So that is another thing, that's way in the future though,
if that ever does happen.
So anyway there you go.
[LAUGH] Thank you all so much for coming to the workshop,
it has been awesome to teach you remix.
I love Remix and I feel more excited about building for the web, than ever before.
Ten exercises is a lot, so you should pat yourself on the back and
feel good about yourself.
And I mean that there's a lot to learn and this material is open source and
available forever so feel free to go through it again.
It is intended to be self paced as well.
So, if you're like what did he say or what you've got the background and
fill in everything.
So I hope that you give Remix a try on an actual thing that you're working on.
I think that you will really love it and
it will help you build better web applications.
That's why I came.
So thanks everybody.
>> [APPLAUSE]