spotifyovercastrssapple-podcasts

elm-pages 2.0

elm-pages v2 is here! We discuss the latest features, including pulling in data with the new DataSource API.
August 2, 2021
#36

Transcript

[00:00:00]
Hello Jeroen. Hello Dillon. Today after 35 episodes we talk about Elm Pages again.
[00:00:07]
After 35 episodes and actually after our first episode was about Elm Pages 1.0 and about a year
[00:00:16]
ago actually a little bit over a year ago now and the last I checked episode 1 is actually our most
[00:00:23]
downloaded episode. Oh that's not true. Oh no it changed yeah I think you might be right yeah I
[00:00:30]
think you did some good marketing recently. Maybe I must have. Let's double check. Oh yes so Evan's
[00:00:38]
open source episode that we recorded with Evan Ciplicki is number one but number two getting
[00:00:45]
started with Elm Pages our first episode. Yep and Elm UI is one download below. That's true. So it's
[00:00:54]
a it's very frail very fragile number two spot. That's true you can you can place your vote by
[00:01:00]
listening to one of those two episodes. But if you're listening to this episode well it kind of
[00:01:07]
counts towards Elm Pages so if you want to support Elm UI then you should stop listening. Yeah that's
[00:01:14]
true that's true although you still downloaded it so we're looking at download counts. Oh that's
[00:01:20]
true yeah you're you can't do anything anymore. Yeah sorry. Just share Elm UI more yeah or share
[00:01:27]
Elm Pages more. Share this episode. So I listened I actually listened back to the original Elm Pages
[00:01:34]
episode a little while back to just sort of like look at you know take stock of where things have
[00:01:41]
gone and compared to what's changed with 2.0 and actually our 1.0 episode not to try to gamify the
[00:01:50]
system of getting more downloads there or anything but it's still relevant. We talked a lot about
[00:01:55]
just kind of jamstack concepts and and why that's an interesting fit with Elm but the architecture
[00:02:01]
with 2.0 has changed dramatically so I think we'll get into some of the details there which I think
[00:02:07]
are very interesting. All right maybe let's start with just saying what Elm Pages is because some
[00:02:13]
people may not be aware they may they might be rushing towards the Elm Pages one episode but
[00:02:19]
let's let's redefine it here. So Dillon what is Elm Pages? Okay so at its core Elm Pages is a
[00:02:28]
platform for pulling in data and pre rendering it to a set of static pages that you can deploy with
[00:02:36]
this CDN like Netlify for example. So what I mean by pulling in data is there's this concept in Elm
[00:02:44]
Pages 1.0 it was called static HTTP data meaning that you could pull in data from APIs and have it
[00:02:51]
there when your page pre rendered. When you built your application? When you build your application
[00:02:57]
and it outputs for your blog posts it outputs an HTML page for each of those etc etc for all the
[00:03:05]
different pages so you could pull in data from for example from the elmradio.com website. What that
[00:03:12]
does it's an Elm Pages application and it actually uses the Simplecast API which is our sort of
[00:03:19]
hosting provider for for the audio and we use API calls from Simplecast and fetch metadata about
[00:03:28]
where the mp3s are hosted and actually some some other metadata about the size of the files and
[00:03:35]
stuff that the RSS feed needs. Generate an RSS feed all using pure Elm code generate the the pages
[00:03:43]
for each episode and it's using API data and that's available at the pre rendered HTML and
[00:03:51]
it's also available when your Elm application hydrates so it loads the HTML which has been
[00:03:57]
pre rendered if you have something like Twitter or Slack basically scraping to get those nice social
[00:04:05]
previews they're going to be able to get that because it's pre rendered so the core idea is
[00:04:12]
that like to get those nice social previews and stuff sometimes you need data from different
[00:04:18]
sources and Elm pages gives you the ability to get that data before init even runs in your Elm
[00:04:25]
application. So for pre rendering... Just to clarify so you said that it generates a lot of HTML
[00:04:31]
files and RSS files and I'm guessing kind of whatever you know that you wish for? Exactly
[00:04:38]
it's just it it doesn't specifically generate anything except what you define including RSS
[00:04:45]
feeds and all of that that's you know some Elm code that you write to output a string to a file
[00:04:50]
path and when you run your build it generates that. All right but so you generate HTML files
[00:04:57]
but you also generate JS files so you it's not just static files and static contents it is also
[00:05:05]
like just regular Elm applications that you can interact with just the way you're used to with Elm.
[00:05:12]
Exactly right yeah you have a full fledged Elm application once the page loads that starts by
[00:05:20]
you know loading the pre rendered HTML and that's available for social media previews that need to
[00:05:27]
scrape that but then you get a full Elm application and in fact it it takes over and does single page
[00:05:34]
app navigations from there when you when you load a new page so it's not fetching HTML to go to a
[00:05:41]
new page it's running as a continuous Elm application. Yeah so it's downloading the the
[00:05:46]
HTML file the renders it and then when you say it hydrates it replaces all that by a native Elm
[00:05:55]
application. Exactly and when you transition between pages you can even have a shared model
[00:06:00]
exactly like Elm SPA and that design was inspired by Elm SPA's design there and that shared model
[00:06:08]
will persist as you do page changes because it's a continuous single page application from from
[00:06:13]
there and so for this sort of so there's a different life cycle for Elm pages where there's
[00:06:19]
a build step normally Elm pages normally Elm applications don't have a build step but Elm
[00:06:25]
pages gives you a build step so you get this pre in it so when you when it pre renders a page it
[00:06:33]
calls init for that page but it does not call update so it renders the initial in knitted
[00:06:40]
version of any given page. And that's where we'll be rendered in or sent to that HTML file that will
[00:06:47]
be yes pre rendered okay. Exactly right but before init even happens Elm pages is going to resolve
[00:06:55]
your data sources so the data sources could be in Elm pages 2.0 it can be not only an HTTP data
[00:07:02]
source so you could do like for example for the listing page for for the Elm radio website it goes
[00:07:10]
and fetches an API request to get all the listing of all episodes and then for each of those it
[00:07:18]
makes a follow up HTTP request so you can do data source dot and then and you can do follow up data
[00:07:26]
source requests from that initial data that you got so it opens up all sorts of possibilities and
[00:07:33]
that that will be resolved by the Elm pages platform before init is called and your page is
[00:07:39]
pre rendered at your build step or in the dev server. So all of the data is fetched and then
[00:07:44]
condensed somehow into one big giant data structure or multiple I don't know yet we'll go into that
[00:07:50]
later and that will be potentially available to the pages init function. That's right you can pull
[00:07:58]
it in you can use it in init update and you also have that data in your view as well as in your in
[00:08:05]
your head function which is where you can kind of put your SEO meta tags to say the Twitter card
[00:08:10]
previews or JSON LD structured data you know you can pull in all sorts of metadata but you have
[00:08:17]
access to the resolved data sources when you render those. So what is the benefit of having
[00:08:23]
that build step? Right so one of my one of my favorite benefits from from having like a pre
[00:08:31]
rendered Elm site is that so we've we've talked about the idea of parse don't validate a lot which
[00:08:38]
is like you know one of my one of my favorite kind of design principles that I think about often and
[00:08:44]
with Elm pages because there's a build step so you can like parse don't validate with a subsection
[00:08:51]
of your data in your Elm app you can parse don't validate for a model for a page so you can say
[00:08:57]
hey when I go to this page I need I need to have this data but if something's wrong with the data
[00:09:05]
and I do you know I do this parsing then I can parse it into something that could potentially
[00:09:10]
fail right that's sort of what parse means so that's a really powerful pattern but you have
[00:09:16]
all these states in your application you try to sort of pull them to the top so you don't have
[00:09:22]
shotgun surgery checking for things repeatedly and having you know not knowing if you have a
[00:09:28]
good state all over your code. So that's when you're actually doing that logic you have the
[00:09:33]
data that you need and you don't need to do any branching anymore. Exactly but you do need to
[00:09:38]
branch at least at the top level because you can't guarantee that things will be in a good state so
[00:09:46]
you need to check it at some point at runtime but when you have a build step you can actually parse
[00:09:52]
don't validate and turn that those two tracks of the success track and the fail track you can turn
[00:09:59]
the fail track into a build failure so you can parse it into either a build failure which will
[00:10:06]
give you an a nice error message when you run Elm pages build or if you're in the Elm pages dev
[00:10:11]
server when you're on that page it'll even hot reload as you change your code and as you change
[00:10:17]
you know files that it might depend on like markdown files that it might depend on it will
[00:10:23]
tell you that there's a problem so for it like let's take an example so we haven't mentioned yet
[00:10:28]
but data sources can in Elm pages 2.0 can include a file data source so you could read like a
[00:10:34]
markdown file so if you wanted to ensure that you have a title you know you could you could
[00:10:40]
either extract the title by parsing the markdown and checking that it has an h1 tag or you could
[00:10:47]
get the title from like front matter like a little yaml thing between the triple dashes
[00:10:54]
that's called front matter at the top of markdown files so you can you can access those using using
[00:11:00]
the data source dot file module in Elm pages 2.0 and you can fail if so so you can do data source
[00:11:09]
dot fail or you can pass in a decoder to this this front matter data source and if the decoder
[00:11:17]
fails or if you were to call data source dot fail or decode dot fail or whatever at any point that
[00:11:25]
turns into a build failure so you don't have data sources don't give you a result that may have an
[00:11:31]
error they give you a build error and you run that build and if the build succeeded that's the
[00:11:37]
okay version if it didn't succeed that's the error version and you get that in your dev server or in
[00:11:41]
your build step so that I think is huge because you know we love guarantees and we do there's no
[00:11:48]
way for Elm to guarantee that all your data is valid and that all your HTTP requests succeed and
[00:11:55]
that the server is available and well behaved and gives you a good response or even you know a a
[00:12:01]
REST API may return HTML for some reason and you don't know until you do it but since Elm pages
[00:12:10]
has a build step you actually do it so you do know before your site goes live so you can parse
[00:12:16]
don't validate at build time not at runtime with some of these bits of data that you pull in during
[00:12:22]
the build step yeah so with the example of the the block with a title and description if one
[00:12:28]
markdown file doesn't have a title yes you will get a build failure if you exactly if you've
[00:12:34]
requested that one would be required yes so you can you can just write your markdown file if it
[00:12:41]
doesn't have a title because you forgot to write one you have a build failure and in your code
[00:12:45]
which does all the rendering which does all the logic you can just go ahead and say okay I have
[00:12:51]
a title exactly and otherwise you will have an Elm compiler error yeah exactly so you get the
[00:12:57]
nice benefits of parse don't validate turning it into the nice data type that you want that
[00:13:02]
represents that everything went well but you don't even have to worry about the failure case and this
[00:13:07]
is actually like it's a very nice workflow as well when so like it sort of changed my workflow where
[00:13:15]
if I depend on some API data you know like if if I'm pulling in a listing of items from like a
[00:13:23]
content management system CMS or you know whatever it may be my process has changed where I'll start
[00:13:29]
by doing an HTTP data source and then I'll do decode fail and what that's going to do so let's
[00:13:38]
take an example let's say we're building a blog but the blog is hosted with a with a content
[00:13:45]
management system so we're using an API to get a listing of all blog posts so so we want to create
[00:13:52]
a blog index page so I would start by making the request to that API and then I would just do decode
[00:14:00]
dot fail and what's going to happen then is when you're looking at that blog index page in your
[00:14:06]
browser with the Elm pages dev server running it's it's going to tell you hey I got this HTTP
[00:14:13]
data but the decoder failed and here's the JSON data if you think about what you would have to do
[00:14:20]
to get that workflow in a in a vanilla Elm application there are a lot of steps involved
[00:14:26]
so you would have to you would have to say in init here's an HTTP request to perform here's a
[00:14:34]
message to to call back to you know when you receive the HTTP response in the update function
[00:14:42]
you have a clause to handle that message you have something in your model that tells you that you've
[00:14:48]
got that response oh and by the way it's gonna need to you probably want to wrap that with a
[00:14:54]
remote data type because it could be loading or could be an error and then well you're gonna need
[00:15:01]
to handle all of those different loading and error and success states in your view if there's an error
[00:15:06]
state you're gonna have to turn that error into a nice printable string and don't forget to like
[00:15:13]
wrap it in a pre tag so you can like debug it in real time and now you can go do that process if
[00:15:20]
you didn't miss any steps along the way there easy peasy we're used to it I guess but it's a lot of
[00:15:26]
work so that's I've just become addicted to this process now with Elm pages of this lifecycle where
[00:15:32]
I just say so so the way a data source is wired in is you have these page modules so you would have
[00:15:38]
something called like source page blog dot elm and that would map to the slash blog route in your app
[00:15:48]
and that's going to have a top level value so just like you have init update subscriptions you're
[00:15:54]
going to have data and that data is just going to be a data source and so for the data source we
[00:16:01]
would do you know data source dot http dot get we'd write our data would be the content the the result
[00:16:09]
of the data source data would be representing the data source of what you're going to fetch
[00:16:15]
okay so that's what that's what data is and then in your view init update if you have those you can
[00:16:23]
you can do it just with them with it with a view you don't need an update function but you you get
[00:16:30]
that data so whatever type your data is there's a so you're going to have a type alias data often
[00:16:38]
it'll be like a record could be a custom type if you wanted to but you're going to have some type
[00:16:42]
called data with a capital d and you're going to have a top level value called data with a lower
[00:16:48]
case d and that lowercase d data is where you define your your data source of what you're going
[00:16:56]
to fetch and the and the top the capital d data is the data type you're going to get back so of course
[00:17:06]
if you you know if you're adding more bits of data that you're expecting to receive that data type is
[00:17:13]
going to change you add fields to the record or whatever it may be but there's no message there's
[00:17:17]
no update clause there's no case statement checking whether it's loading or error or whatever so that
[00:17:23]
workflow feels so nice to just say you know data equals data source dot http dot get give it your
[00:17:30]
url and uh and then in your view function you're just like oh here's the here's the data i asked
[00:17:36]
for it's it's just there or if it's not there the dev server or the build command are telling you
[00:17:42]
i tried to make this http request and something went wrong yeah so earlier you said that whatever
[00:17:48]
is returned by the init will be rendered i guess by yes by being called by the view function
[00:17:54]
my mental model was like okay so the init function returns a temporary model until something has been
[00:18:00]
loaded because you still need to to do all the fetch commands handle the update and in the view
[00:18:07]
render an intermediate state and then the render state state but you would pre render the intermediate
[00:18:13]
state but with elm pages you would actually render the completed view for the completed data
[00:18:20]
so you render more than what you would get with a normal application exactly because the elm pages
[00:18:27]
platform gives you this core concept of a data source that it's a declarative way to describe
[00:18:35]
the data your page depends on statically now um you still have an it an update which can perform
[00:18:41]
commands and if you wanted to get real time data you can do that in those places with regular http
[00:18:49]
but the elm pages platform takes care of all the details of resolving that before your init
[00:18:55]
or view function gets called for the first time that's just part of the platform and so so yeah
[00:19:02]
you don't uh i think of it as just declaratively describing data rather than like imperatively
[00:19:09]
saying go and do this here's the intermediary model state along the way as you get up this data
[00:19:16]
you get you know or you know it's it's a lot more like just defining a task and resolving it and you
[00:19:22]
can pull in all the data you need and once that's all resolved you just have that data available
[00:19:29]
so at the beginning you mentioned that elm pages will build a set of html files and javascript
[00:19:34]
files and whatever and those are already have all the content that they need as we've seen now and
[00:19:40]
you deploy this to a cdn so that means that if your um cms is down the server is down because
[00:19:49]
of an outage or something then you can't build because all those htp requests will fail but if
[00:19:56]
at some point you have failed you have built and the cms is down but the yes the pages application
[00:20:03]
is released and deployed yes then you don't need to depend on cms and everything is smooth even
[00:20:10]
though the cms is down exactly that's right and so like i think one of the things people people
[00:20:16]
sometimes wonder about you know data sources and that sort of thing i mean it um you know we've
[00:20:20]
kind of talked about how it's convenient but then what about like you know wait a minute so you're
[00:20:27]
fetching this data at the build step but then i have i have to make sure i get that data before
[00:20:33]
i load a page because it's hydrating an elm application right so that seems a little odd
[00:20:38]
and and that's true you do need to um you do need to get that data so like if if um you go to the
[00:20:45]
uh the root page it gives you the pre rendered html everything loads up it hydrates into an elm
[00:20:52]
single page application and then you click to the blog page right and now all of that data that you
[00:20:58]
gathered to to get the listing of all of your blog posts from your cms where does that come from
[00:21:03]
because it's a single page elm application so is it hitting your cms or what is it doing as you said
[00:21:09]
it's not hitting the cms which means that even if the cms were to go down that page of the listing
[00:21:16]
of blog posts would still be there yeah i guess you could still request from the cms new data but
[00:21:23]
you would have to do that manually yourself you don't have to that's right yeah exactly if you
[00:21:28]
wanted to for some reason um with the cms in in most cases you're probably going to be using data
[00:21:34]
sources to get that data but but absolutely in some cases you might want real time data to check
[00:21:41]
if a live stream is ongoing on twitch right now or to get the number of likes on a blog post or
[00:21:49]
something like that so the cms gives you that data from the in the data source the data source
[00:21:56]
gets that data and that data ends up in a json file and so all of the data that that uh blog
[00:22:03]
index page depended on ends up in this json file and elm pages what it does is it fetches that
[00:22:08]
json file for you before it goes to that page so so it gets and if you hover over a link you can
[00:22:16]
look in your network tab and you can see when you hover over a link that it's going to go and fetch
[00:22:21]
the data that it needs because it usually takes between one to 200 milliseconds to um between the
[00:22:29]
time your your cursor enters the region of a link and the time you click it because you usually
[00:22:35]
don't click it at the far edge you click it towards the middle and humans are slow even if
[00:22:39]
you try to click it fast you're probably not going to do it faster than 100 milliseconds and it turns
[00:22:44]
out that's actually like enough lead time to in most cases make it feel pretty instantaneous to
[00:22:50]
have that data available so that when when um the user clicks on the page it's ready and it does the
[00:22:57]
single page transition quickly so do you have a json file for the whole application or for each
[00:23:03]
page it's split by page yeah exactly yeah it's split out by each page so it lazy loads as needed
[00:23:11]
for a page when you go to that page it gets the data it needs is that the only data that is being
[00:23:16]
fetched no more js no more css it it is and i mean i would love to to have like code splitting but
[00:23:25]
uh there are some reasons that i can't really do that because the way the elm compiler works it
[00:23:31]
would um i saw this as a as a bone as a good side i wasn't like oh it should split it up i was like
[00:23:39]
it would be cool jason it would be cool i would love to be able to do the um to do the code
[00:23:45]
splitting feature but there are some limitations that i can't really hack it but i would love if
[00:23:50]
that feature were something i could make use of in the future but for now i mean the bundle sizes are
[00:23:56]
are pretty reasonable so that's okay but yeah it only fetches that json file and then now the reason
[00:24:04]
i think it might seem strange at first right because like wait a minute so it's still making
[00:24:10]
these htp requests right so what's the point besides this sort of convenience and you know
[00:24:16]
having this data available at pre render which we talked about i think there's an additional
[00:24:20]
benefit which is kind of like you were hinting at if your cms is down your site is still up
[00:24:26]
but what if the htp request fails to get that json file that it needs for your data sources
[00:24:31]
for that page because that one is also hosted somewhere that can go down it's hosted somewhere
[00:24:37]
that could go down but guess what so is the rest of your application so the uptime characteristic
[00:24:43]
characteristics they're going to be tightly linked together so if you're the odds are if
[00:24:48]
you're seeing a page you're going to be able to get that data and also you're hosting it on a cdn
[00:24:54]
whatever that stands for content delivery network something like that cloud delivery yeah maybe
[00:25:00]
content delivery network so the idea of a cdn is that you have dumb hosting where it's just giving
[00:25:06]
you files it's not going through the complication of talking to a server and that server is handling
[00:25:13]
multiple requests and it has your application logic and it has to go read something from a
[00:25:20]
database it's just here's a file here you go and in fact since it's so simple it's just reading
[00:25:27]
files why don't we distribute those files across a lot of networks across the world so we can serve
[00:25:33]
it to you from the closest network so if you're in japan we're not going to serve it to you from the
[00:25:39]
east coast of america and vice versa we can serve it up from the nearest data centers because it's
[00:25:44]
just literally giving you a file that's on the disk so it can do that extremely efficiently that's
[00:25:50]
like serving from the edge so anyway there are benefits to that not to mention that you can do
[00:25:56]
data source dot and then so you can get the listing of all of these things and then you can go get
[00:26:01]
follow up htp requests for each of those and that data is all kind of aggregated into this json file
[00:26:09]
so even though you wrote and then and did all these follow on requests when it builds it it's
[00:26:14]
all just there so it just goes and grabs it it doesn't need to wait for that waterfall of requests
[00:26:20]
so um so i think that's pretty cool also um the uh so elm pages you will probably notice if you
[00:26:28]
if you play around with elm pages that there's this module called optimized decoder so ilyas did some
[00:26:36]
incredible work on that uh yeah ilyas van pier is he dutch i think he's from belgium oh cool okay
[00:26:44]
or is dutch and uh well i'll leave the correct pronunciation to you but uh but yeah so i don't
[00:26:51]
remember we told this story the last time uh we talked about on pages but yeah i i um i saw
[00:26:57]
ilyas's json decode exploration package and noticed that it it can warn you if you have unused json
[00:27:05]
data so if you if you have some json in a in a response and you don't consume it then it it tells
[00:27:12]
you and gives you a warning and i'm like that's interesting because i've been thinking it would
[00:27:17]
be really cool to keep track of the json that's used and not and strip out the unused json data
[00:27:23]
and i i was just i just messaged ilyas and said i wonder if that's possible and then literally like
[00:27:28]
that same day he's like oh i played around with it and you totally can and here it is
[00:27:34]
nice which i thought was incredible but yeah so that's the backbone of the optimized decoder
[00:27:39]
api so what it does is it um when you're running it at at build time it's going to go to the extra
[00:27:45]
effort which uh is a little bit more expensive than running a vanilla json decoder it's going
[00:27:50]
to go to the extra effort of keeping track of which json data in in the json blob that you've
[00:27:57]
consumed using a decoder so if you do decode decode dot field name now it knows that that
[00:28:03]
field has been consumed if you do you know decode dot index one it knows that array index was consumed
[00:28:10]
and it actually will null out any data that it didn't need to consume for example so it's it's
[00:28:15]
pretty sophisticated although it's also pretty simple which is why elm is incredible because it
[00:28:22]
has this purity and so you can make these kinds of optimizations so that's uh it's doing that
[00:28:28]
work in the build step in the in the runtime when the user is running it in their browser
[00:28:34]
it just runs a vanilla json decoder for the performance so you don't incur the cost of running
[00:28:41]
that optimized decoder but in the build step it figures out which json fields you used and strips
[00:28:47]
off any unused fields which is pretty nifty so that that comes for free it strips out the
[00:28:52]
unused fields from the json that you download when you hover a link when you go to a new page right
[00:28:59]
um from the json in a data source so which ends up being that json so um and it will actually um
[00:29:08]
uh it will actually merge together if so if you made um if you had a data source doing an
[00:29:14]
http request to the same url two different places and you consumed one field from one of those data
[00:29:22]
sources and another field from the other data source and you did data source dot map two and
[00:29:27]
got those two pieces of data together it's actually going to handle that correctly and
[00:29:31]
just merge it into a single data source with the consumed data you which you're welcome because it
[00:29:37]
was a lot of work no i mean i did it because i couldn't couldn't help but but build these features
[00:29:44]
because i i get really excited about them but um but yeah it it just it just works as far as you're
[00:29:50]
concerned but there are all these optimizations happening under the hood yeah so there's one
[00:29:54]
thing that we haven't touched on upon is that data sources are agnostic right yes to where they came
[00:30:01]
from yeah um you can have data sources for files data sources for http but what you get is data
[00:30:09]
source of data and where it came from or how you got it or how it was transformed in the meantime
[00:30:15]
doesn't matter so you can combine things and if you are if you have a blog where you have a lot
[00:30:22]
of markdown files and you are migrating them one by one to a cms you could you could have one data
[00:30:30]
source for all the files one data source for the cms and then combine them maybe having one tick
[00:30:36]
priority over another maybe and but then the rest of the transformation is uh we don't care where it
[00:30:43]
came from we can keep that data like okay this data source came from http this one came from files
[00:30:49]
we can keep that data because we can map we can end them all those data but we don't have to care
[00:30:55]
and that is pretty nifty yeah i i agree that's that's my favorite part i mean that that's my
[00:31:01]
favorite part of elm pages to me that's that's the heart of elm pages is is the the data source
[00:31:06]
concept and the engine of resolving them and optimizing them but like you say it's if you have
[00:31:12]
a data source of list of blog posts that's that's all it is right when you're using that all you care
[00:31:19]
about is that you have a list of blog posts you don't care where it came from elm pages doesn't
[00:31:23]
care where it came from it'll take care of resolving and getting the data that as you
[00:31:27]
describe where you need to fetch it from from uh you know grabbing it from files and from cmss
[00:31:33]
you can even do data source dot succeed and just get some data in there as uh as our listeners
[00:31:38]
probably know we we like using succeed because succeed it's a key to success it's the key to
[00:31:45]
success t shirts are on the way really no not really i lied not yet but they could be
[00:31:52]
so yeah that's that's the beauty of it yeah so data sources some come from files i come from
[00:31:57]
http yes but once it's run yeah it actually come from json files that's right that's true so
[00:32:03]
exactly that's right yeah so even like so when you get uh front matter using a data source what's
[00:32:10]
actually doing is it's so what what elm pages is really doing under the hood is it's sort of like
[00:32:17]
this this runtime for for an elm build step and that runtime is using node js so it's using node
[00:32:26]
js to read files right elm can't read files and it reads those files if you say you want to read
[00:32:31]
a file and you want to read its front matter what it's doing is it's um it's actually uh parsing
[00:32:37]
that front matter and that yaml into json and then it gives that to you so you can do a json
[00:32:41]
decoder so you don't have to worry about doing yaml parsing or any of that you just get json
[00:32:46]
and in fact you can use an optimized json decoder because if there's some yaml in the front matter
[00:32:51]
that you don't use then it's just going to get stripped away if it's an unused fail field uh and
[00:32:58]
so this is one of the really big changes in elm pages 2.0 also is that really um elm pages
[00:33:06]
there's less to it now it's all just sort of data sources that's all it is that's how you read files
[00:33:11]
that's how you get a listing of files that's how you um define routes that's that's what you do for
[00:33:19]
everything and and so if you understand data sources well then you understand elm page as well
[00:33:23]
that's the one concept that you really need to invest in understanding to understand elm pages
[00:33:28]
yeah what i'm imagining is that a lot of the code that you wrote before and that you put in in it
[00:33:35]
update message and stuff is now put into the data sources so like you you could be a data source
[00:33:42]
expert now yeah totally yeah that's right so like with with elm pages 1.0 there were like a couple
[00:33:51]
of additional concepts and it's it's pretty cool because i actually like removed a lot of code
[00:33:57]
going you know migrating from from the 1.0 code base to the to the 2.0 internals a lot of code
[00:34:04]
went away you mean from projects that use the elm pages or inside elm pages uh well both but uh but
[00:34:12]
i'm speaking about the internals which i think is really cool because you can do more with it but
[00:34:17]
the internals are actually less complex because it's just using this concept of a data source to
[00:34:22]
do more things so does that mean that it's easier for contributors to to help out uh probably so so
[00:34:29]
so one thing that is sort of on my mind for data sources is the idea so so we've got we've got
[00:34:36]
different types of data sources we've got htp data sources which we've talked about you you
[00:34:41]
give an htp you know you describe an htp request to perform and a decoder to use and you've got
[00:34:48]
that data you can do uh file read data source so you can do data source dot file and you can
[00:34:56]
do the data source dot file dot only front matter and give it a decoder to get the title and
[00:35:02]
description from a blog post for example you can do data source dot file dot body without front
[00:35:08]
matter and it will give you everything but those things between the triple dashes at the top of the
[00:35:14]
file so you you can you can read in these files and uh there's also a data source dot glob api
[00:35:22]
which allows you to depend on data that is just describing which files are on the file system so
[00:35:28]
if you wanted to go to a folder and say hey i want i want a page for every uh or you know do an do an
[00:35:35]
index page of blog posts and instead of being hosted on a cms it's local markdown files in your
[00:35:41]
blog folder and so you could do uh data source dot glob of um you know of effectively blogging
[00:35:49]
slash star dot md and then uh that data source is going to be you know a list of strings of those
[00:35:56]
um of those files but so basically what what a data source is is it's a way of having you know
[00:36:04]
having this data available for the sort of pre init phase that it's it's there on initial render
[00:36:10]
for the pre rendered html it's there for the head as we've talked about but it's really just like
[00:36:15]
as you said it's just json data and you can map it all together and you've got got that data when
[00:36:21]
you go to a new page one of the things i've been thinking about is a sort of um having a mechanism
[00:36:27]
for defining custom essentially like a javascript port where you have some json data and if you
[00:36:35]
think about what a port is in elm you send json out and you receive json back through ports that's
[00:36:42]
what ports are in elm that's actually not that different than what a data source is a data source
[00:36:47]
under the hood is sending json to describe hey here's um here's this file i want to read or
[00:36:54]
here's this glob pattern and then it sends back data and under the hood it is using ports with
[00:37:00]
the elm pages runtime but you don't have to worry about that step don't tell anyone and uh so well
[00:37:07]
what if you could write custom ports and say hey when when this message comes in just like you
[00:37:16]
write a javascript port send this data back so maybe you want to say here's a an npm package
[00:37:22]
that i have installed and it you know knows information it's like a database of time zones
[00:37:28]
that conveniently there were a million of them to choose from an npm and i wanted that or i want to
[00:37:33]
run a shell command that generates this svg image and so you can take that that json is the input
[00:37:41]
and the output is you know conceptually you're deterministically um giving the same data for a
[00:37:48]
given input right just like an http request to an api even if that's technically not true you have
[00:37:55]
to conceptually think of it as like declaratively representing a single resource so you can say
[00:38:01]
hey you know you're deterministically representing a single resource so anyway that's that's something
[00:38:07]
on my mind is a sort of using that same data source mechanism as a way to send back json data
[00:38:13]
from these sort of javascript ports so that you could do things like running shell commands or
[00:38:19]
whatever custom things you needed to do to get that data yeah yeah the the issue with ports is
[00:38:25]
to to get a result always just like with http you're right expected to get a result at some
[00:38:32]
points yeah but because you have a build step you could potentially say okay if i haven't got
[00:38:37]
anything after x seconds you you make a build failure exactly and you can create an abstraction
[00:38:44]
too where you say like hey here's um you know you're gonna get a single port that port gives
[00:38:50]
you some json data and you respond to that json data however you define so you you have a tag or
[00:38:58]
whatever you could use lmts interrupt and um and and return you know have this contract with yourself
[00:39:05]
that if i get this type of data i'm gonna do this type of thing and so you could basically have just
[00:39:09]
like an async function that gives back data and it's going to be run at the build step and once
[00:39:14]
your lmap is out there being used by a user it's not doing any of that because it's already resolved
[00:39:19]
it in the content json so we talked about deploying to cdn because what you build gets deployed to
[00:39:26]
your cdn can you briefly go about how that works and how complex that is sure yeah so you essentially
[00:39:33]
so lm pages 2.0 uh there is an init command so you could just do you know npx lm pages init if uh if
[00:39:42]
lm pages is uh if 2.0 is published by the time this is released then it would just be npx lm pages
[00:39:48]
init if it's not then i believe in you dylan you can do it i believe in me too yeah i've got four
[00:39:53]
weeks you listen and know whether he succeeded or not that's true yeah uh so but yeah well i'll i'll
[00:40:03]
put the instructions regardless in the show notes so then you've got a skeleton lm app lm pages
[00:40:09]
application and uh you know if you're deploying it to netlify you can npm install the netlify
[00:40:15]
cli and then netlify init to get a netlify.toml configuration file that's going to have a command
[00:40:22]
for the command i think it npm installs for you lm pages uh apps are going to require an npm
[00:40:29]
install because because lm pages is an npm dependency and then um and then you do lm you
[00:40:35]
know lm pages build and it generates the files to a dist folder um in your netlify config you can tell
[00:40:42]
it that the folder to publish is your dist folder and then you push that up to netlify and it's gonna
[00:40:47]
run lm pages build and publish the dist folder and now you've got an lm pages app okay i imagine you
[00:40:53]
still need to sign up for netlify maybe pay the free tier is quite generous so if you're building
[00:41:01]
a hobby project chances are you you won't have to pay but there are lots of good hosting providers
[00:41:06]
out there and netlify i've been very very happy with yeah that's what i use also for my plugin and
[00:41:11]
i don't think i've paid anything except the domain name obviously all right so lm pages 2.0 is
[00:41:18]
simpler than lpages one for the people who are using it already uh will the migration be difficult
[00:41:24]
or do you have any tips on how to do that yeah that's a good question so well so there are a few
[00:41:31]
concepts that maybe we should um introduce first that we haven't talked about yet so with lm pages
[00:41:36]
2.0 they're um so very similar if you've used lm spa then these patterns are going to feel very
[00:41:43]
familiar um i got a lot of inspiration from ryan's approach to this so there is a uh source slash page
[00:41:51]
folder page with a capital p so if you have a page dot blog dot elm you know page dot blog module
[00:41:59]
like like we described before it's a file based router so page dot blog corresponds to slash blog
[00:42:07]
page dot index corresponds to the root page slash and you can do a dynamic uh route segments and so
[00:42:16]
you could do um page dot blog dot slug underscore and that would correspond to slash blog slash
[00:42:24]
sometimes they write it as colon slug meaning that it's a dynamic segment that could it's a
[00:42:29]
placeholder could be anything so slash blog slash hello so the way that that that works is first of
[00:42:36]
all um you can use elm pages add so you could say elm pages add blog with a capital b and that's
[00:42:44]
going to add source page slash blog dot elm you could do elm pages add blog dot slug underscore
[00:42:52]
and that's going to give you the uh the route corresponding to slash blog slash colon slug
[00:42:59]
so that's that's the first thing to know between elm pages 1.0 and 2.0 is that whole setup is
[00:43:06]
different that there's a file based router and so in 1.0 the routes were uh based on files in your
[00:43:15]
content folder usually they were um markdown files and uh so if you had uh content slash blog slash
[00:43:22]
hello dot md then you would get a corresponding route blog slash hello yeah okay that's what i
[00:43:28]
have in my blog as well and that is not going to be the case in elm pages 2.0 right so you can
[00:43:35]
build that functionality using the building blocks with 2.0 or you can do anything else you could uh
[00:43:41]
have your blog post coming from a cms with with uh 1.0 you couldn't um there wasn't a way to
[00:43:48]
have a data source determine which static routes you were going to have so in version one yeah you
[00:43:55]
had static htp yes to get data from external resources and you had the file based routing
[00:44:02]
right but it was marked down file based routing so it was a one to one mapping between a a url
[00:44:10]
and a file whereas in elm pages 2.0 it's a one to one mapping between a route and a module
[00:44:17]
and when i say route i mean blog slash dynamic slug is a route not blog slash hello that's a url
[00:44:26]
it's a page so in 1.0 one file in your content folder markdown file usually was one url in 2.0
[00:44:35]
it's a module page dot blog dot slug underscore and that's that route which actually gives you
[00:44:42]
multiple pages and so if you wanted to translate that to elm pages 2.0 so in elm pages 2.0 you have
[00:44:50]
these page modules very similar to uh these page modules in elm spa so if you're defining a pre
[00:44:57]
rendered route which is what we've been talking about this whole time and spoiler uh that's not
[00:45:05]
the only thing it's it's sort of in an alpha phase but um i i do have some sort of alpha phase
[00:45:11]
functionality for doing sort of serverless and on demand on demand routes which we can get into
[00:45:17]
that's a whole nother can of worms all right but let's just focus on pre rendered routes for now
[00:45:22]
which is the ones that are uh the html is pre rendered at build time and so um so to do that
[00:45:29]
you've got so you've got a top level page which is just like your your main in a in a regular elm
[00:45:36]
application but it's the page for each page module so each page module exposes this top level lower
[00:45:42]
case p page value so if you do page dot pre render you give it head which lets you um you know do the
[00:45:50]
seo data that we talked about you give it data that we talked about and that data is going to
[00:45:55]
be the data source it resolves that is available before init and then you've got routes so routes
[00:46:02]
are the uh the routes that you're going to pre render so for a blog post where does that route
[00:46:07]
come from so now how would you how would you describe routes if only there was some declarative
[00:46:13]
way to describe some data you needed to gather to define your routes yeah if only we had a some kind
[00:46:20]
of data source yeah if you could like get some source of data declaratively yeah so it uses the
[00:46:27]
data source api so a route is a data source of list of route params so um now route params are
[00:46:36]
the route params are completely based on your page module's name because it's a file based
[00:46:42]
routing based on the name of the module so so for our example of page dot blog dot slug underscore
[00:46:49]
the route params are a record with lowercase slug equals string with no underscore so
[00:46:57]
those dynamic segments are translated into into fields in your route params record if there are
[00:47:05]
no dynamic route segments then the route params are empty like for page dot blog so the routes
[00:47:11]
you just do a data source of of those route of a list of route params so for example
[00:47:16]
uh we could say routes equals data source dot succeed and then a record slug equals hello
[00:47:24]
and now when you go to you know when you run the dev server elm pages dev and go to go to the
[00:47:31]
browser open it up go to slash blog slash hello it's going to be rendering your page if you go to
[00:47:37]
slash blog slash getting started with elm pages it's going to give you a 404 page and it's actually
[00:47:43]
uh i i put a lot of love into that 404 page to to actually like give you feedback saying hey this
[00:47:49]
matched this route but it didn't match any of the routes for this type of page the pre rendered
[00:47:56]
routes and that's why i'm showing you a 404 uh and then it's going to list out the routes which
[00:48:01]
we only defined hello as a route yeah only the dev server right only the dev server but yeah
[00:48:07]
i've seen a screenshot and it looks pretty cool again about trying to give the best air feedback
[00:48:13]
to the user because there's so many things that can go wrong like what data sources are you
[00:48:20]
fetching how is it mapped what is the resulting data source yes and you don't you know as a user
[00:48:27]
you you don't trust the tool if the tool doesn't give you feedback you're not going to trust it
[00:48:32]
it doesn't matter there's no way to earn a user's trust if you don't give them feedback you can't
[00:48:37]
just say trust me i'm doing the right thing because if you're not giving them feedback
[00:48:42]
feedback creates trust and if if the uh if the dev server is always right and has no bugs in it
[00:48:49]
and is very consistent and reloads anytime configuration changes and pages change or whatever
[00:48:55]
it actually doesn't matter if it's not giving feedback you're still not going to trust it so
[00:48:59]
yeah i i i really like that as a user i like using it and getting that feedback this is how you know
[00:49:05]
that dylan actually cares about you user like what he just said that was his his heart that's
[00:49:11]
just spreading his love it's a love letter that was that was my love letter to the user um yeah
[00:49:17]
that's how you create routes now if you wanted to create routes to match the v1 behavior of elm
[00:49:25]
pages what you would do is um so v1 there was the content folder so you you would create a glob
[00:49:32]
pattern to um to match the content folder so so now the way the glob works you do you can do i
[00:49:40]
don't want to get too bogged down by it but you can look at the api docs for it and i think the
[00:49:46]
the docs are pretty helpful but you can do glob dot match on a literal like content slash then you
[00:49:52]
like content slash then you can do glob dot capture to pull a piece in so it's sort of this
[00:49:58]
um it's very similar to the elm parser api um the parser api has you know pipe equals and pipe dot
[00:50:06]
and those are those correspond to glob dot match or a glob dot capture is the pipe equals that
[00:50:13]
eats the thing and glob dot match is equivalent to pipe dot which ignores ignores the thing yeah
[00:50:21]
so anyway you you create a glob pattern you can extract the information you want from it so if
[00:50:26]
you just want to get the slug you can if you want to get the full path you can get that but so you
[00:50:31]
get that glob pattern and you if you were to take uh if you were to just capture the slug part so
[00:50:38]
that means for content slash you're just going to match that for the you're going to do a wild card
[00:50:43]
that you capture the star part and then the dot md part you're just going to match which means
[00:50:49]
you match against it but you don't get that data what that means is you've got the slug yeah so
[00:50:56]
you're building a glob pattern like just the way you would type it in a terminal like uh content
[00:51:01]
slash star star or star slash no content slash star dot md and so you're building a glob and
[00:51:10]
you're also saying this this here is what i'm actually caring about i care about the star part
[00:51:16]
maybe i care about the content part maybe i don't um and then then you have a you transform that
[00:51:22]
to a data source exactly then you yeah then you say to data source that's right you can do glob
[00:51:27]
dot to data source and that kind of finalizes the glob gives you the data source and yeah and again
[00:51:32]
you know what you're describing there that's that's parse don't validate so you get just the
[00:51:36]
data you want rather than just saying here's my glob give me the list of matching files which you
[00:51:41]
just built up but then you have to strip off the stuff afterwards again that you already sort of
[00:51:47]
you had it in this nice neat format where you just could have said i want this data well you
[00:51:52]
can just do that so then you can uh you can map each of those so you could do like data source dot
[00:51:58]
map and then parentheses list dot map rep prams and that would turn each of those into the rep prams
[00:52:04]
because the rep prams is a record you know it's a record constructor that takes a single string
[00:52:12]
that's gonna that's gonna be your slug so now you've just defined a glob data source that's
[00:52:17]
gonna correspond to all of the files in the content folder now you hinted at the double star
[00:52:26]
and you can do a recursive wildcard and so if you if you really wanted to just exactly match
[00:52:35]
the elm pages v1 behavior you could use that to create a glob pattern that matches every nested
[00:52:43]
file in the content folder and and that's going to be all of your routes and you could actually use
[00:52:51]
the um uh so elm pages the file based router we kind of hinted at this last time with ryan that
[00:53:00]
uh elm pages has this sort of uh special feature of the splat routing so if you wanted to if you
[00:53:07]
wanted to truly have exactly the behavior that elm pages one had for its for its routes where
[00:53:14]
the content folder is directly mirrored in the urls in your application that's what you would do
[00:53:19]
you would create a splat route so you can do elm pages add all uppercase splat splat is in all
[00:53:25]
uppercase the other dynamic route segments are capital not all uppercase so all uppercase splat
[00:53:32]
and you could do double underscore which is going to be an optional splat which means it's also going
[00:53:38]
to match the top level root route okay what does splats mean what does it come from there are
[00:53:45]
different terms for this sometimes people um sometimes people use the term like rest params
[00:53:51]
like in a you know in some programming languages you can have a variable number of arguments var
[00:53:57]
args and then you you get those as an array uh netlify's redirect routes use the term splat to
[00:54:05]
say whatever comes after this just capture it give it give it to me in a list so there are different
[00:54:10]
terms that are used for it but splat is just like you know uh similar to like the um like you know
[00:54:16]
ecma script javascript calls it spread sometimes spread operator dot dot dot uh it's basically just
[00:54:23]
like give me everything that comes after this yeah and i'll i'll handle it somehow yeah exactly
[00:54:29]
i'll i'll slurp up all those values so that's um that's what splat does is for the um so blog dot
[00:54:38]
slug underscore is gonna match exactly one segment after blog so if you do blog slash hello slash
[00:54:47]
world it's not going to match that but if you did a splat route then it's going to match it's it's
[00:54:54]
going going to match anything so you can you can actually do you could do like page dot blog dot
[00:55:00]
all uppercase splat underscore and that would match blog slash hello world it wouldn't match
[00:55:08]
slash blog because we did a single underscore so it's a required splat the double underscore
[00:55:15]
is an optional so it's the same with um like for example in the elm pages 2.0 docs i have a route
[00:55:22]
that is um docs it's page dot docs dot section underscore underscore the reason i do that is
[00:55:30]
because if you go to if you go to slash docs slash what is elm pages then it shows you the what is
[00:55:37]
elm pages docs section but if you go to slash docs i actually also want that to show you what is elm
[00:55:44]
pages so i want the same page module to be responsible for rendering and showing the
[00:55:50]
metadata and everything so i want to use the same page module for both of those routes whereas in
[00:55:55]
the case of like page dot blog that's a totally separate page listing blogs compared to page dot
[00:56:01]
blog dot slug underscore so i want those to be separate page modules so that so that's the
[00:56:06]
optional double underscore at the end of a segment okay so i imagine that if if somehow um two routes
[00:56:13]
or two modules cover the same route like yeah uh then you have a build failure well it's actually
[00:56:20]
gonna just uh it deterministically will match routes and you can shadow routes and the more
[00:56:27]
specific one will take precedence so like for example if you had you you could have splat routes
[00:56:34]
and you could also have a blog route so if you have like a top level splat that's gonna match
[00:56:40]
slash about slash you know 2021 conference event slash whatever you could handle all of those with
[00:56:48]
splat however you're getting wherever those pages and their data lives but then you could also
[00:56:53]
specifically have a um a blog page page dot blog and that that takes precedence because that is a
[00:57:02]
specific route that you defined so um yeah so you so the route that you that it parses into and by
[00:57:09]
the way there's a there's a route module that's generated so so elm pages just like lmspa you you
[00:57:15]
get a generated route module that has this route custom type and you can use that to like uh
[00:57:20]
programmatically link to pages so the specificity is deterministic and it doesn't depend on which
[00:57:28]
routes you've defined so like for example if you had a splat route and you said for that splat
[00:57:34]
route you're going to handle a route of blog but then you also have a blog route page dot blog
[00:57:41]
well the the blog route is just always going to match and it doesn't depend on whether on whatever
[00:57:48]
else any other routes have so the the the routes that you'll parse into is deterministic based on
[00:57:53]
the specificity of routes yeah but i probably should specifically if you have two matching
[00:57:59]
routes i should give a build error for that specific case but but in terms of um like i think
[00:58:05]
this is just a helpful concept to keep in mind that the uh what what a route matches is not based
[00:58:11]
on uh the specific routes you have it's based on the specificity of the page modules so you know
[00:58:19]
what a route will decode to regardless of which routes are pre rendered or exist in your app if
[00:58:26]
that makes sense distilled is not yet in on pages right it is oh it's it's fully stable so uh i've
[00:58:33]
seen you talk about the concept of distilled uh data can you explain what that is yeah so in
[00:58:40]
frameworks like nextjs and a lot of these javascript based static site frameworks or jmstack
[00:58:47]
frameworks the way that you get data to the page is you would say like in nextjs you'd say get
[00:58:54]
static props and then you have an async function you make http requests you read files you glob
[00:59:02]
you whatever all these things that data sources do again at build time yeah that's right so with
[00:59:07]
nextjs it it's going to do some fancy sort of static uh transformation of the your code and it
[00:59:15]
actually splits apart the parts of the code that it's going to run on the server and that it's
[00:59:21]
going to run on the client and get static props is going to be run on the server or whether that's
[00:59:27]
a build server or a serverless function or whatever it may be and so um so get static props
[00:59:35]
you get all this data and then you you give it a serializable json object and that's the data that
[00:59:43]
gets sent to the page so if you wanted to split out data you could do whatever complex work you
[00:59:49]
wanted to to do http requests and read files and then you could just say oh here's this prop the
[00:59:56]
number of blog posts is 5000 but you could just say blog post count colon 5000 now that's the
[01:00:03]
data that shows up on the client bundle right yeah it doesn't matter whatever other data came
[01:00:08]
before that with the data source api and elm pages it's actually keeping track of what data
[01:00:16]
you depended on and just pulling in that data for all your data sources for that page right
[01:00:22]
yeah and it puts it into the json file right exactly strips down a bit but it strips it down
[01:00:28]
exactly so if you are depending on some json fields and not others it's going to take care of
[01:00:33]
only having the data you depend on in the bundle which is great but sometimes if you want to count
[01:00:41]
count count the number of posts you don't want all of that data so there are many many cases
[01:00:47]
where where you might want this you know i i've been um building like a digital garden for myself
[01:00:55]
that uses back references and so the back references track every single uh every single
[01:01:03]
post that refers back to the current post and so you know that can now that what that means
[01:01:11]
is that it's like a it's like a glob data source to list out all the posts and then it's a follow
[01:01:18]
up you know data source dot and then for each of those uh do a data source dot file dot and then
[01:01:24]
read the file if i were to just let that data uh show up in the bundle then it would be pulling in
[01:01:31]
50 plus pages of markdown files or however large the the number of files grows to which is not good
[01:01:36]
and it's not not needed because all i need is i need to know for each page does it refer back to
[01:01:43]
this page or actually i don't even need to know that i just need a list of pages that refer back
[01:01:47]
so it could be three three strings a list of three strings rather than 50 markdown files with all of
[01:01:55]
their contents so with the distil api that's that's what that's for and it's the distil api
[01:02:03]
lets you work in more of this way that that like next js get static props works where you just say
[01:02:11]
here's the data make sure this data is there for the page to render with and so distill so i made
[01:02:17]
like a couple of distill helpers distill codec and distill serialize codec and those are for uh
[01:02:25]
mini bills codec package and the siri and martin stewart's serialize package elm serialize and you
[01:02:33]
know the the reason they're codecs is because the way to still works is you need to teach the data
[01:02:40]
source how to turn that into some json that it's going to include in the json for that page so you
[01:02:46]
need to encode it you need to teach it how to encode it to put it into the json file and you
[01:02:51]
need to teach it how to decode it to take it out of the json file it turns out codecs are really
[01:02:55]
good for that although actually it doesn't really matter because it's always going to encode it and
[01:03:03]
run the decoder so you're actually never getting the data before it went through the encode decode
[01:03:09]
cycle so if you did it in a non reversible codec fashion it actually doesn't matter because you're
[01:03:15]
you're not going to see the data without being encoded and decoded whether it's in the dev server
[01:03:21]
or the build or whatever that's probably what you want in most cases so um but you can just use the
[01:03:26]
low level distill if you want to provide a function to encode the json and a function to decode to
[01:03:31]
json for whatever reason but one really cool thing about distill is that so for one thing uh
[01:03:37]
you know if you wanted to get that list of back references you could do you know distill codec or
[01:03:42]
distill serialized code so it's you know data source dot distill codec or data source dot distill
[01:03:46]
serialized codec and then you give it a unique key so we could say like back references in this case
[01:03:54]
and then that's just a string and then we give it a codec since the the data source that we arrived
[01:04:01]
at in the chain up until this point was a list of string it was data source list of string then we
[01:04:07]
just need a codec of type list of string so we could just say codec dot list codec dot string
[01:04:13]
or serialized dot list serialized dot string depending on which package you want to use there
[01:04:17]
and that's it now it is now it's going to strip down just that data to a list of strings so if
[01:04:23]
you look in your json for that page that's what you'll see also uh any computation that came
[01:04:29]
before that is not performed in the client side in the browser it's only done in the build step
[01:04:35]
which is also cool so if you wanted to compute some fibonacci number and then distill that into
[01:04:41]
an int you could do that and it wouldn't actually run the fibonacci code in the browser so that
[01:04:47]
opens up some use cases and it's a good thing to have in your toolkit so if you if you're noticing
[01:04:52]
large json files that that's what you'd want to reach for and i'm thinking about ways to to give
[01:05:00]
some some nice feedback to tell you if your json files are getting large just to as a feedback
[01:05:06]
mechanism so i might do that in the dev server server and or the build command that'd be cool
[01:05:12]
yeah so um i've asked this question in during the first episode also uh but when would it make sense
[01:05:19]
for someone to choose elm pages over a regular elm project i think it's worth you're addressing
[01:05:24]
you're addressing this question i don't know if your answer changed well certainly uh the the
[01:05:32]
things that you can do with elm pages 2.0 are a lot more flexible and it's it's just generally
[01:05:38]
become more mature but i mean if you're not if you have no use in pre rendering pages then you
[01:05:47]
know why would you pre render pages if you if you're not using data sources then why would you
[01:05:54]
use elm pages you know that that's sort of my thinking on it is like if you're like oh wow data
[01:05:59]
sources that's great now i can have this data there and um i can think about this this data
[01:06:05]
being there for this page without having to go through the whole update message cycle and all
[01:06:11]
of that and it's declarative data and that that abstraction works really well for this use case
[01:06:16]
then elm pages might be a good fit if if it's like i don't really need this data source thing
[01:06:22]
then what then why are you using elm pages that's that's sort of my rule of thumb yeah if so if you
[01:06:27]
don't have any data to pre render yeah you use a regular elm application yeah or elm spa might be
[01:06:34]
a great fit yeah so um yeah so you know that that's gonna tend to be like content sites and
[01:06:39]
now i i really do believe that um content sites deserve good social previews that's just something
[01:06:46]
i i believe like to me it's super anti climactic if if i put some love into like writing a blog
[01:06:53]
post or something and then share it on twitter and it's like incremental elm.com slash blog slash
[01:06:59]
whatever can you please stop pointing fingers at me please i want the love i put into the
[01:07:08]
posts to be reflected in like a polished looking social preview and same for a marketing page or
[01:07:15]
a restaurant you know restaurant menu you know site or a film festival site or whatever it might
[01:07:23]
be like these sort of um content based sites i i think deserve nice previews and also like i think
[01:07:30]
you can leverage like elm pages at its core is giving you this tool for for pulling in this data
[01:07:39]
into nice typed elm data that you can use on your pages and like i just think elm is a very good
[01:07:46]
tool for that like elm has an incredible type system it's so nice like transforming data and
[01:07:53]
passing data around and parsing data right that's like that's what's amazing about elm like any like
[01:08:01]
even somebody who's not sold on elm is like yeah i really like doing that sort of thing with elm
[01:08:06]
you know that you hear that sometimes like well that's sort of what what data sources are really
[01:08:12]
good at is letting you use data that way like there's no graph ql abstraction because we've
[01:08:17]
had something much better than a local graph ql database for getting files and stuff we've got elm
[01:08:23]
and elm's type system and elm's feedback mechanisms so i'd much rather use that now that said i i
[01:08:30]
absolutely use graph ql and elm graph ql to like fetch data from cmss like uh like sanity or
[01:08:36]
contentful that expose graph ql apis because why not do you have a graph ql data source yeah uh
[01:08:44]
well um so uh elm graph ql uses like vanilla json decoders not optimized decoders and you can use
[01:08:52]
that with um with um with elm pages um you just have to use these unoptimized requests but they
[01:09:00]
are optimized in a different way right exactly right yes exactly because graph ql already sort
[01:09:08]
of does this data splitting by returning exactly the data you requested so it would it would be
[01:09:13]
unnecessary for that so yeah okay yeah so that works quite nicely so i i can i'll share a little
[01:09:19]
link to like a snippet that i have for just performing and decoding that using a data source
[01:09:25]
but it works works very nicely but why but why would you use an abstraction like that i think
[01:09:32]
that you know frameworks like gatsby js for example use this graph ql abstraction because it's
[01:09:39]
a typed way of getting data but elm i couldn't ask for a better way of dealing with types data
[01:09:44]
than elm so yeah one of the principles of elm pages is to let elm shine and so anyway if you
[01:09:52]
if you find that declaratively describing the data that your page depends on and transforming
[01:09:58]
that and having it available on page load is a useful abstraction then chances are elm pages
[01:10:04]
will probably be a pretty good fit yeah i think just marketing sites in general if you if you
[01:10:10]
want to reuse like the same uh ui elements uh yeah can be a good fit even if you don't have
[01:10:16]
any content because at least we'll get um uh pre rendering and therefore better seo metrics yeah
[01:10:24]
so that's useful even if you don't have any data sources to to fetch from you can yeah do uh data
[01:10:31]
source dot succeed to have to have static data sources right yeah or just uh hard code the data
[01:10:36]
into your views or whatever it might be yeah absolutely that's that's true that's true right
[01:10:40]
but if you don't need pre rendering or data sources then probably not what you need yeah
[01:10:45]
but yeah i remember that we talked at one of my previous company about using elm and one of the
[01:10:50]
concerns was seo so elm pages somehow solves that yeah yeah like you don't need seo you know you uh
[01:11:00]
if it's like internal user authenticated pages no yeah yeah then you don't need it it's not going to
[01:11:06]
help you out there so seo is you know i mean one one rule of thumb that people sometimes use for
[01:11:12]
jamstack sites being a good candidate for jamstack is do do people see the same content when they go
[01:11:18]
to the page and you can sort of enhance it with some user specific content if somebody's logged in
[01:11:24]
but they're seeing an ecommerce page and they can see their shopping cart items but otherwise it's
[01:11:32]
the same exact page for everybody and has the same inventory for everybody or whatever it may be
[01:11:36]
and and those things really need to have seo and you want to have good first paint times as well
[01:11:42]
okay i think it's time to to close so elm pages is a project that takes data sources of any sort
[01:11:51]
and builds static html files rss feeds css files javascript files and therefore elm applications
[01:12:02]
that you deploy to a cdn and if at some if at any point you have something that wasn't as expected
[01:12:10]
you get a build error and during the elm application you still have elm for all the
[01:12:16]
nice things that it has is that a okay summary i'd say so yeah that's a great summary now there
[01:12:24]
are several things we didn't get to touch on today so we might need to do an elm pages 2.0 part 2
[01:12:30]
episode uh just to bump up our uh percentage of downloads for elm pages related episodes a little
[01:12:37]
bit but um take that elm ui uh we didn't talk about sort of uh the the api routes and you know
[01:12:48]
file generation part of it we didn't talk about serverless and on demand which is more alpha so
[01:12:53]
maybe when that stabilizes we can revisit that but yeah that uh that's really the heart of elm
[01:12:57]
pages i think we covered it pretty well and you you put a lot of effort and love into the dev
[01:13:03]
experience also we didn't talk too much about it but from what i can see without having tried it
[01:13:08]
too much it really looks like you put a lot of love into that so that's thank you yeah yeah no
[01:13:15]
that's that's true i um i'm really pleased with the architecture in fact like the whole exploration
[01:13:22]
of elm pages 2.0 began with trying to um uh sev forno who's been like really awesome just like
[01:13:31]
discussing all these ideas of directions elm pages can go with me um was sort of saying like hey i
[01:13:38]
wonder if elm pages could do serverless rendering i think that's where the elm pages 2.0 exploration
[01:13:44]
started because that ended up being a giant nerd snipe which uh i i welcome it was incredible and
[01:13:50]
uh i ended up building that and saying like oh you actually can and actually now that i have this
[01:13:57]
mechanism for give me a single page and i will render that page instead of doing like full
[01:14:04]
builds and rendering everything well hey that's really cool for a dev server because we can pre
[01:14:09]
render pages in the dev server and we can do everything in this sort of just in time fashion
[01:14:14]
rather than uh so you know in in the style of tools like vt and snowpack just very rapidly
[01:14:21]
doing the minimum amount of work to give you hot reloads and stuff like that and so anyway yeah the
[01:14:26]
the the architecture um i'm very pleased with and and i've tried to make the performance really
[01:14:32]
noticeably fast and it's it's feeling really nice to work with all right so how do people get started
[01:14:37]
with the elm pages uh check out the docs there's a fresh doc site for 2.0 and join the elm pages
[01:14:45]
channel on slack i'm always happy to answer questions there also i'll link to some uh sites
[01:14:52]
using elm pages 2.0 and some code bases uh i haven't upgraded uh elm radio to 2.0 yet but i
[01:15:00]
will soon but incremental elm and the elm pages doc site are in 2.0 so there's those are some
[01:15:06]
code bases you can take a look at too what is the link for the elm pages documentation well assuming
[01:15:12]
that it's published uh by the time this episode goes live uh that would be elm pages elm pages
[01:15:19]
dot com slash docs all right well all right i still have plenty of questions like i know
[01:15:24]
well i think we're out of time yeah yeah i think uh well let's let's revisit this one uh
[01:15:31]
when we've got some new stuff to talk about here that sounds good
[01:15:34]
all right well until until next time until next time