- Go to Gatsby and retweet it. Okay, I think we've got
ourselves a livestream. So, this is cool, this is exciting. I am happy to have you on today. So, do you maybe just
want to introduce yourself and tell us a little
bit about who you are, what you do, all that good stuff? Oh, wait, hold up one quick second. It looks like my sound is not working so let me fix this real quick. Output, streaming with desktop audio. Can you give me a quick mic check? - Yeah, sure, can you hear me now? - All right, yes, all right, we've got audio now, so, please, let's start that all over again. So, Espen, thanks for being on today. Do you want to give us a quick overview of kind of who you are and what you do? - Yeah, sure. So my name is Espen and I work as a developer at Sanity.io. I've been here for
about two or three years and, yeah, we make sort of a hosted API and backend store for
host structured content and then we make a
headless collaborative CMS that connects to that so you can add it to all the content that you put into our API. So, yeah, it's been pretty fun. We launched about a year ago, or more, quite, just about
over a year ago in November and, yeah, we just launched
our new Gatsby source plug-in, so just getting into sort
of hooking everything up and trying to get everything working to the Gatsby ecosystem. - And that's what we're
gonna play with today. So, our goal today is,
Espen is gonna teach me how to build a site using
Sanity's Gatsby plug-in. The site we're gonna
build is a portfolio site, so it's going to be an
image of the project and a little bit of description about it and we'll put that up on a page, and then we'll also create
individual portfolio pages. So, kind of a here's a
list of all my projects and then here's an
individual project list. And so this will be kind of a fun way to put it together because
we get to take advantage of what sounds like, so I don't quite understand this yet because I've never used Sanity before. I'm actually gonna sign
up for my Sanity account as part of this livestream. So I'm very excited to learn how it works and I guess the best way to do this would be to get started. So, while I do this part, it's probably gonna be a lot
of watching NPM install things so let's get it rolling, and while this is installing, do you want to talk to
us a little bit about what this is doing? - Sure, so what you just installed is sort of the CLI package that allows you to interact with the Sanity project, set up new projects and all that kind of good stuff. And once that was installed, it set up your running Sanity image, which sets up a new Sanity project. And since you haven't signed in before, it'll ask you to create an account and accept our terms
of service, of course. Once that's done, you can go
back into the browser here and, yeah, set up a new project. Just give it sort of the essentials. What this is actually doing is setting up a project on your, like a JavaScript project on your laptop, which is actually running
the CMS, so to say. We call it the contents. So that differs from a
lot of other headless CMS' in the way that we actually
allow you to customize and set up everything on your laptop and then you can build it to a static bundle of JavaScript and HTML and host that, yeah, pretty much anywhere. But we also allow you
to host that at Sanity, Sanity's like studio host as well. - And so, can you talk
me through a little bit, like these options here? So, the project name I understand. The dataset, does that matter or is that just something
behind the scenes? - So the dataset is
sort of like a database, so you can have multiple databases. Sometimes you want different
aspects of a project and sometimes you just want
the different environments for production, staging
and that kind of stuff. - Got it, so in-- - So that's why we recognize production as the first thing just
to get up and running. - Cool, works for me. And we, today, are gong to
make this world readable, so people can try out the code. - So the visibility is actually useful if you make a request directly to our API, like just a single page
application and then you can make CORS requests directly from your website into that. So that's a good setting for most public websites or as if
you make a Gatsby site it's pretty much up to you because you can just enter a token
in our source plug-in and just expose the data
that you actually want. - And so this is going to, when I run this output path, it's
gonna take over the folder that I create, or like
so it'll take this over? - Mm hmm. - Would it make sense, so I just kind of a practical question here. So if I'm gonna build a
Gatsby site in this folder, I probably don't want to also have my Sanity code or is there a pattern that you recommend for this, like
the backend and frontend? - Well it's sort of up to you. We've done a couple of minor flow things but I think the easiest
way to do it right now is just to separate the studio
from the Gatsby frontend just to make it more clear
what actually runs where. - And this is you call this Sanity Studio? - Yeah. - Cool, I'm gonna go with that. This is a, for the sake of
learning let's go clean, yeah? - I'd probably start with the blog schema but just because it gives you a couple of sample schemas to start from. Starting from a clean
thing is kind of hard if you haven't done any
Sanity projects before. - Okay.
- we're gonna make that easier but for now it's a kind of a clean slate so you're stuck reading the
documentation for awhile. - Sure, sure, okay. - So this will now actually
run Yarn behind the scenes or MPM basically to install the actual project dependencies. So as you'll see, once it's bootstrapped, it has all the things that
you're probably used to from other Javascript and note projects, like your package stays on file and a bunch of dependencies. - Okay, and-- - And it'll also have a Sanity JSong file, which is the sort of
our main manifest file for defining which project ID and datasets and all of that kind of
good stuff that you want. - Okay, okay, so let's look at there. Let's use this. All right, so here is our generated file. So we've got the name, licensed it to me, that's cool, Sanity start,
Sanity check, and cool. Cool stuff going on here. - Yeah, these dependencies are
sort of plug-ins to Sanity. Sanity is build around this idea of being super customizable, at
least that's our end goal. So everything is like
all the different tools that you can use inside of Sanity are just plug-ins that you install
so it's pretty extendable. - And so my goal here, like I don't need to do anything, right? I just Yarn start and we're good to go? - Yeah. - Okay.
- And that should now start a, oops. Oh, it doesn't have the same (crosstalk). - Oh, it's because I, so I should have- - Oh, you used NPM instead of Yarn. - What is it, Sanity CLI.
- Sanity CLI, yep. - So that's a question. One of the things that I usually do, just to avoid that problem, is I would install the
CLI as a dependency. Because that way it doesn't
need to be global, right? And it would just work? - Yeah, you can do that, it's just the show Sanity image command
and sort of needs it to be global at this point - Ah, gotcha.
- just to be able to run that first thing. But you can expose the
CLI locally, if you want, just to be able to not have to do this. - Okay, let's do it one
more time, yarn start and now we do have the Sanity command. - Mm hmm. So this will actually setup a web server and starts compiling a
bunch of stuff with Wiffet and then it should give you
a hero that you can go to. It should be a local host 3333. - Okay. - There we go. - I'm gonna re-up on
coffee here real quick. So we've got the site up and running, this is great news. All right, so so far, so painless. I went off script by
using my preferred yarn versus MPM but I think
that's to be expected for a nerd like me. So cool, oh, okay, cool. So now I'm in the Studio and I'm going to authenticate, I
assume I want to authenticate the same way that I did, okay. - Yep, this is just to give you a session. That's why you have to login again because the previous session was for the CLI and now you have to login
to the actual project. - Okay and so if I go click on-- - This is like the different content types that are available with
the default blog schema. You selected one of the
templates that doesn't have any data so you're not actually seeing much at this point. You can start creating a
new poll server or whatever, if you really wanted to. - Well how would you go if--
(crosstalk) Should we take a look at
how the schema is defined so that we can play with
setting up our portfolio? I guess that's just--
- I guess you can just click New Post just to see what the actual interface looks like. - Okay.
_ it's responsive so now the pain's collapsed,
give you some more space so once you actually start
entering some data here, it'll start creating a draft
for you to, behind the scenes. - Oh man, just give me
one of these babies. - So this is like a default blog post. - Oh, and this will
generate it for me, cool. - Actual. And author is like a reference. So you'll actually have to
create it over the first - Gotcha.
- in the input thing. But what we can do is feel
free to import some images. - Cool. - Uh, yeah, I guess we
can get started on-- - Oh, this is slick, I like that. Wait, does this have a vignette feature? - What's that? - Is this like the area
of focus that I'm setting? - Yeah, we have a sort of a plug-in that allows you to, this
actually sets some metadata on the actual usage of that image so that if you use this
in a proof and you can give it to different like
Corporate Square, Landscape, Panorama, you can just give it a width and height of what you actually want it to be and we'll try to fit everything within that. - Ah, that's so cool.
- Like the circle, the circle defines sort of the focus area. - Like in the crop, yeah,
- other ones it's the actual crop, yeah. - Oh man, this is super cool. Oh, okay, so let's see. We've got some questions about
the quality of the stream. Maybe I'll just ask, is anybody having any trouble with the screen? If you can just post in the
chat if you're having issues. We've got one compliant,
a couple of people saying it's okay. Sorry Henri, I think it's you (laughing). So hopefully he is able to get that fixed because it's aways great to
have Henri Alberica in the chat. Okay, so this is awesome. I love that image editing feature. That's kind of making my day right now. The rest of this looks like stuff that we probably don't care about since we're building a portfolio, right? - Yep, yep. - All right. - So I guess we can start editing the schema in order to fit your content model. - Yes. So if you go into your editor now. Yeah, there should be
a folder called schemas and within that, if
you're to to schema.js. - I'm gonna hide this so
we can see it, schema.js. - This is sort of the one that defines which content types are available. As you can see, all our content types, schema types are just Javascripts. So you can actually use
Javascript to generate the schema, which is kind of cool
because it allows you to make pretty dynamic content structures without having to actually
type everything out in JSong. And it also allows us to use
different type schema builders. Some people prefer to
use the GraphQL notation for defining schemas
since some people prefer to just use JSong to try in these. So in this case, we've imported a bunch of different content types and then within the create schema function we actually add those to the declare box. - All right, let's look at one of these. Let's look at post. So this is just a JSong object. - Yep, so the first thing in the very top is just a name and a title and a type. And the type, it can be a string or if it's a top level type,
it's usually a document. A document is basically just an object but it basically says that it lives as a document as you would think of it if you inserted it into say Mongo DB, you would have a document for the main content types you have. - Okay. - So it will allow you to
have different documents and those documents can
reference each other. So you can have a blog
post would be one document and a author will be another and they can refer to each other by actual like hardly enforced. Hardly enforced? That's not the right way of saying it. Strictly enforced references
within the backend. So you can make sure
that if some blog post references a author, you won't be able to delete that author if there's something that is using it like a
proper database would. - Okay. So if we want to create a new one, let's maybe think through this. So the portfolio is going to be images, a title, description. Do we need additional
schema, do you think, or do we stick with kind
of atomic portfolio? - Uh, well I'd say the main thing would be a project or a work. This is how I would think of it. - Projects.
- The items within a portfolio are projects so project, yeah. - Okay, let's do it. We've got a project and I'm going to pull these side-by-side so
that I can reference this. So I'm gonna do an export default and then you said the
main things that I need are a name, a title and a type. So if I want to set, I will do project, project, and this is a document. - Mm hmm.
- Okay. So then it looks like in here, we're defining all of the fields. And then is this just
something that I just need to go to your docs to know what the available types are? - Yeah. The most common ones are
basically just the same as you would expect from JSong. Basically it's like string and numbers and all that kind of good stuff. But yeah, there's a couple
of more advanced ones, like image and slug and file
and a couple of other ones. And those are, you'll have
to go to the docs for those. - Okay. So let's think on this here. We're gonna need a title, an image, and a slug, and a description. So we can go with the title,
probably set the slug in there, and do an image, and a description. Are there any other fields? Should we set up a cross-reference
to an author just to-- - Yeah. - Yeah, let's do it. - That's already defined so you can use-- - We'll use the existing author. Let's see, we'll just
do this exactly as is. So an author, call it the author, and it is a reference, which means that we need to set it up like so. - Yeah.
- Okay. And our image, ohh, are
there other options? - There are. Our image pipeline is
actually quite extensive so if you upload images, you can extract all sorts of metadata from the image. Things like exit information
and pellet information. It can generate, like it
generates a low-quality image placeholder for you. So it inserts a basic STE
IV version that's scaled to 20 by 20 pixels into
the actual data model. Which is kind of nice because it hooks in really nicely with
things like Gatsby image, that actually can use that feature without having to pull down the image and then scale it on the
client or during the build. - So there's a question in the chat about how to change the start
port for Sanity Studio. Is there a flag for that? - Uh, yeah, there's I think
it's Sanity start dash dash port or you can actually set it
up in the Sanity JSong file. I don't quite remember what the, I think there's a server section of the Sanity JSong file which can actually set it permanently for the Studio. Th only thing to keep in mind is that if you change the port
number you'll have to add a CORS entry. Like a cross origin
resource entry to alLow it to talk to our API from that port number. - Okay. - You can do that using Sanity CORS at and then it should be go
low slash slash local host port something. - Okay. Cool. All right, so now there's
something going on here that I haven't seen yet. So we've got fields and
then we get down to preview. So can you talk a little
bit more about what this is? - Yeah, so this is like an optional thing. It basically allows you for lists, it allows you to pick
which yields should be used for the different places
within that preview. So we do some optimizations
to be able to load a whole lot of documents within a list and then we fetch the data
that you actually need for showing that. So if you want to show
the year that a project has been published or was created, you could select those fields and then use the prepare function if you want something very custom
to actually format those to a subtitle. So in this case, it's selecting the author and then saying I want the subtitle to be by JSong or Jason, sorry. But it's totally optional. It will work out of the box just as it is but it's a nice feature
to be able to change the list views in order to
make them more interactive. - Okay, so I think what would be fun, let's get some data in,
get some projects built and then let's come back to this because I think I know what you mean but I think it'll be much
easier if I can just see it. - Yeah, yeah, it's much easier if we have some data to play with. - Okay, so I've saved
my project and so now I want to go to the
schema and I'm going to, do I still need blockContent, right? - Uh, yeah for now unless
you remove the post. - Well I put this in to match up with the content over here. - Well, to make it simple
you could actually start by just making the
description a text instead. - Text? - blockContent is our way
to represent rich text and be able to embed things, like images and like structured links. Not just as strings but as
references to other documents and you can make all kinds of
custom annotations and stuff. But it creates a JSong
representation of that text so it's a big harder to get started with. So if you just want a simple text without any formatting, you'll probably want to just use text. - Okay.
- It's just like a presentation format for a string, just a longer string basically. - Okay, let's start here
and then depending on how far we get, if we
have time, let's come back and play with this too because that seems pretty interesting. All right, so we've got the schema so I'm gonna take these out but
we're gonna keep the author. So we want to import project from project and then we'll come down here, swap this one out for project and we'll get rid of this and this. Do I need to do anything else here? - No, that should be it. - Okay, so I'm gonna save that. - Yep, save it. - Now does this mean that it's done? It did the whole reload and I don't have to stop and start? - Yeah, that's right. It live reloads when you change the schema so as you can see, you now
have a project in (crosstalk). - Oh, it did it before
I even did anything. - Yeah, it has a yeah. - All right, so let's
add a couple of authors and we'll just generate. Maybe I've got an image that we can use. Let's see. Perfect. Let's drop this on here. This is so cool. I can't get over how cool this is. Yeah, I love it, all right, saving that. And then I don't think we're actually gonna use this today but let's
do that, publish, all good. All right, so then we can go back to a project and here we go. All right, this is pretty slick. So we've got the title,
we've got the slug, project screenshot, and the description. So these are all the pieces that we set up and then we've got this link
to assign me as the author. So let's go over here and we'll just get a couple of project screenshots. So let's do just this and what else? Let's see, shout out to Gant Labord for this ridiculous site
that we built together. It's a machine learning project where you can upload a photo of somebody and determine whether or not it is me or Kyle Shevlin, which is one of the-- - What you can actually do there is if you just copy it to Clipboard you can actually just paste
it into the image field. You don't have to save it first. - Wait, for real? Oh, that's cool.
- Yeah. - So my screenshot is
not setup to handle that so I'm just gonna do
it this way (laughing). Let's see so let's drop one here. We'll do lengstorf.com. - And what's also
important, not important, but I think it's cool to note that this whole interface is real-time so if you have someone else, like if you publish this Studio or deploy this Studio somewhere, people can edit in real-time. There's no locking,
everything is real-time using very fine grain patches. - That is so super.
- So that's quite unique as well. - Yeah, I feel like that's something that it would be so hard to
demonstrate how cool that is just because we don't have, do you have an instance
where it would be possible to share that because that sounds-- - Unfortunately not right
now but I could probably, we could deploy the Studio and I could, you could give me access
to it and I could login just so we can see that
it works in real-time. - Yeah, okay, so let me finish. I'll just put that in. Got it hooked up to me so let's publish. And now if we look at
projects, cool, all right, so we see that. So how do I publish this? Let's maybe just do that. - Yeah, so you basically just, it's up to you if you want to deploy it somewhere else but the easiest way is to just deploy it to Sanity Deploy. - Sanity Deploy. - So it will ask you for a host name and that's on our dot
Sanity dot Studio host. - Okay, set it up as Gatsby. - Now it's building the
same thing as you just saw but in production mode so it'll take a little while longer because it has to actually minify and then
it'll put that on our host and it should be available. So while this is building,
you can actually go to the, if you go to the management
console of Sanity, which is at manage dot Sanity dot io, you can invite me to the project and I will be able to
collaborate with you. - Okay, so let me get logged in here - Yep.
and that's the one. - Then team.
- Team and who should I-- - Espen at Sanity dot io. - Okay. All right. Oh so this might be a good chance while you're accepting that to just kind of ask about your free tier. So it looks like here I'm
signing in as a developer. Now is this a trial or is this
a forever free kind of tier? - It's forever free. It's fairly generous and
it also allows you to if you go over these quotas, you can add your credit
card in and you'll just pay for the overage,
which is something that not everyone catches on their first read. You don't have to pay for the next plan but you can just pay for
the additional API requests or bandwidth or whatever you choose. So I'll get back to
this one we talked about the Gatsby plug-in but if you're using the Gatsby plug-in here, you're using extremely few API requests. It's basically just two requests per build and then whatever else is just bandwidth. So it should be good,
for most Gatsby sites, I should be pretty much free. - Awesome. Well this is, okay so
this is pretty slick. So you got set up? - Yeah, I got set up. I'm in the Studio now. - So what would the easiest thing to be? - Like if you go into the project and then scroll down to
the description maybe. I can start. - (laughing) Oh, this is amazing. So now if I'm in here and I start, oh, but it does fight
over the cursor position. - Yeah, right now it does that. - Got it. - It uses quite a, like you can type in
slightly different places, it should work then. It uses, what's it's called, diff match patch, which is formed by a value rule for applying text tips. - So as long as you are
editing a different line. - Yeah, then it works pretty well. And it also works, this is a sort of simple example. I can replace your image, if you want. I don't want to do that. But yeah, it's kind of
cool if you're doing the full rich text experience then you can actually collaborate on different paragraphs and insert images and work on all kinds
of structured content. - Yeah, yeah. - It's slightly more pleasing. We're also working on right now you can actually see
that where my cursor is so we're working on
that feature right now. - Got it.
- So it'll be there in not too long being like
a presence feature. So your avatar will pop up over the field that's being edited. - I like that. Okay, so let's see, let me add one more. And we will drop in this one and then maybe do you want to add one as well while we're doing this? Like create an author for yourself. - Yeah, I'm doing that right now. - Perfect. I can't not set this focus highlight, I love it so much. I feel like this is gonna be my major takeaway for today. This is my whole reason to use Sanity is so that I can choose
the focuses on my images. (laughing) - My avatar is not on these pages. - Okay, let's find me and
look how cool that is. So in the background,
without refreshing the page now I can see your avatar as an author. - Yep.
- That is real slick. Okay, and then if I click in here. - Yes, we're pretty proud
of the real-time aspect is actually quite unique and everything within the Studio has really been built around that idea. So you can make your own
custom input components for more complex use cases and making those real-time is actually quite simple. You basically just make
these small patches that describes just the minimal thing that you actually want to change and then behind the
scenes that will just be sent to the server and everyone will just reflect that state. - Yeah, this is great. Okay, so let's see. We've got this setup. You've got your author selected. Should we add an image for this? - Yeah, let me take a
screenshot of something. - Yeah, it doesn't need
to be anything important I don't think. Let's see here. Lots of love for Sanity
in the chat right now. - Oh, that's good to hear. - Yeah, yeah, it looks
like Newt is in there answering all the questions,
which is much appreciated because it's hard to split
the attention (laughing). - I wouldn't be able to keep
up with the chat unfortunately. Okay, I've got a project screenshot up. - Oh, that's so cool. I just watched that
upload in the background. - Oh, that's good. - Man, this is an awesome tool. Okay, so now we've got data. We've got data, it's
living on the internet. Want to build a site with it? - Sure.
- All right. - That's like the logical next step. - Okay, so let's do this to start. We'll go over, I set up a portfolio. So I'm just gonna run a Gatsby new and we'll use the default starter so I'm just gonna instantiate it here. And what this should give us, assuming all goes well, let's roll. Rebuilding Sharp is
always my favorite part of building with Gatsby
because it's always kind of like the wild card. You don't know if it's gonna work today. It's the joy of bundling
external binaries in your code. - Is that part of the default
starter or what is that? - It's part of image handling. So we use Sharp under the hood, which is built in, what
the hell is it built in? I can't remember. So we have to just bundle it with it's kind of like SAS, a third party, like a different language
that gets bundled in and then we use a node adapter for it, which is very cool but it also is-- - So with Sanity you
can actually skip that because we support all the transformations on our own Studio. - Let's play with that today because that sounds like fun. All right, so I've got to say we have a site, it is up and running. I'm actually gonna stop it here and we'll run it through the, let's run it through this one instead. So I've got this and we'll
do the terminal stuff in here so that it's a little easier to see. So right now we've got
a pretty general setup. We're using Helmet for SEO. We've got the file system set up so that we can source our images, plug-ins for image handling, and then some progressive web app stuff. The manifest and an
optional offline plug-in. I'm not gonna turn that on today because we'd just have to work around it in development anyways. So that's it, we've got a
pretty bare bones setup here. If I want to get started with Sanity, what's my first step? - You'll want to use the
Gatsby source Sanity plug-in. - So let's find this. We've got Gatsby source Sanity and these don't look like they're gonna be problems for us on this
meeting so let's take this and I'm going to yarn
add Gatsby source Sanity. And let's read about it while we go. So my options are, my project ID. Now is that going to be the-- - Yes, you can either find it at-- - This one? - No, it's like a numeric thing so you can either go
through the Sanity dashboard manage thing there, and it's
- Here? - Yeah, there's the project ID. Or you can also find it in your Sanity JSong file within the Studio. - JSong within the Studio.
- It should have both. Yeah, it should have both of those, project ID and dataset. You need both of those. - Got it, okay. So let's pull this to the side then and we will pull this to this side and we'll go to Gatsby config. You know what, we're not gonna use it so why don't we drop this. Ahh, we'll have to back things out so let's not do that. Resolve Gatsby source Sanity and then the options were-- - Project ID and datasets. - And a token but we're not using this because we set it to public, right? - Yeah, you don't need that. - Got it. So let's take this and we need this and this and I have the video hiding it but so this is the project
ID and the datasets. So I just found this in the Sanity.JSong, bringing it over project ID and dataset and make sure that my JSong is valid and I think we're-- - So there's one more
thing I think we should do. Because Sanity uses schemas
that are user-defined, we try to help you get the slightly more sane schema within the Gatsby. - Okay. - Because sometimes if you
don't have a value in a field, like let's say you
don't have a description for a blog post or a project and you try to use that
GraphQL will complain if you haven't defined that. But using our GraphQL API we can sort of tell Gatsby that those fields exist so you get a slightly more
predictable experience. So what you can do is actually if you go to the terminal and from the Studio folder just
do Sanity GraphQL deploy, that will deploy a GraphQL
schema for that dataset. - Oh, yes, I do want a GraphQL playground. - Yep. And that will just allow
Gatsby, like I said, to be able to introspect
types that are available, that kind of stuff. So this is just (crosstalk). - So let's poke around here a little bit. So we've got the project, title slide, image description. Cool, very cool. - Yep, it's pretty much
the same that you defined but there's also like document attributes, such as ID and created apps
and all that kind of stuff that we add by default. - I'll just throw this in the chat in case anyone wants to play in the API. - Sure. - Do me a favor and don't, do we have mutations in here? No, okay.
- No. - Good deal. I was thinking, do me a favor,
don't add a bunch of data. - I should tell everyone that this is, the GraphQL implementation
is in beta right now so there might be dragons fighting. - Okay, but so now that we've implemented that GraphQL API, does
that just means that when the Gatsby source Sanity fires up it's gonna use that instead? - Yep.
- Gotcha. - Well not instead but
it'll just be able to more reliably figure out
which fields are present. - Okay, so if I run yarn develop, I am hoping, if all goes well, uh oh, we've got problems. - Whoops. - What is it? What happened? - Did you install the plug-in? - I thought I did. I'm not sure. - Or it's something about Sharp. - This is my favorite, my favorite. Okay, we're going to-- - You can just remove it because you don't really need it for this. - All right, so I'm gonna get rid of this and then I have to back
a couple of things out so bear with me while I do this. Let's see, we're not
using it in here at all so I just need to get into the pages and let's drop image
and that should be good. Make sure we don't use it here. Okay, I just want to make sure I'm not using the images anywhere
so that we don't break it. We can drop this entirely
because we're not using it. Make sure that it's not
included anywhere else, let's see, and that we're
not querying any images. So that's all good. Let me run that one more time and then we'll go yarn develop. Come on now. Let's also just remove
it from package.JSong because we don't need it. And we're not gonna use, or do we use Gatsby image with-- - Yeah, I guess the images are good, yeah. My dog is craving attention. - That's good. Well but now the dog's on screen you've got to do introductions. - Oh yeah, this is Kookles. She's a miniature Schnauzer. - Oh, it's always good to get a little dog action on a stream. Like I feel like, this is
what I'm really lacking. I don't have any pets and I just need the ability to just put a pet on screen and be like you be cute while I solve the rest of these problems. - Yeah, it's a good distraction. You just have to train them so they appear at the right time. - One more time. How are you possibly broken? There's not even anything. Okay, so this is the curse of
doing anything live, right. Let's get rid of the
yarn lock and the cache and let's try that one more time. - Would it be easier to just see the terminal outputs in terminal? - The problem is more
that it's trying to load-- - I just don't understand
why it's trying to load that. - Yeah, so I just blew
away the node modules and also our cache to make
sure that whatever is, something locked up basically,
and it's one of the issues with the versions need to
be 100% exact with Sharp or else things don't cooperate. So you know, let's hope for the best here. Much better. Okay, so I'm gonna
assume that was probably like a package lock and I was using Yarn and not NPM and so there's
all sorts of things that can definitely
get confusing later on. So let's jump out into the GraphQL schema. Let's dump this and let's try, let's just play. What do we got? I want to look at my Sanity projects. So let's look at Sanity
projects and then let's go edges, node, and what's in here, I'm gonna hit options space so that I can just look through things. So let's get down to I got a title, I saw a description in there,
we've got a slug in there, and oh wait, the slug looks
like it needs some options. - Yeah, we've reserved
some room for the slug type being slightly more complex. We'll add like a history
of slugs at some point so you don't accidentally use a slug that's used somewhere else in the past but hasn't been implemented yet. - And let's see, we're gonna do fluid. And so now this API is
gonna match the Sharp API? - Yeah, so you can do just
a fragment for it I think but I'm not sure that
works within GraphQL. - Yeah, fragments don't work in GraphQL so I'm just gonna grab the source for now. And we can see we've got the title, description, slug, and the image. And if we just grab this
image for the fun of it, we can see that it did, in fact, work. And if we were to change
this to the source set, for example, we would
see there are lots of different images, and
like here's a small one, so that we can, where did it go, here, get a smaller version of that image. So it's really nice. It's a great way to build content, makes it much more accessible to people, especially on smaller screens and on lower bandwidth networks. Like if you're using 2G,
you don't want to download a megabyte of giant image
for a 300 pixel wide screen. So this is an API that is,
I'm really excited to see, just supporting natively because this makes life really, really easy versus something like having to
download all the images and run image processing
on your local machine and so on and so forth so
this is really cool to see. And with that I think what that means is we can jump in and let's start by building out a portfolio page. And I'm gonna do that by making this a little bit bigger and let's get a query. And we're gonna pull
in GraphQL from Gatsby. We can drop this right in here. And where would I find
the fragment reference? Is that in the plug-in? - It should be in the Read Me. - Using images. - Yeah, there we go. - Fixed and fluid. - More down there, there we go. - Okay and do these support
things like traced SPG and stuff like that or is that like-- - It supports the low
quality image placeholder, the basic STE IV thing. It doesn't support
traced SPGs at the moment because that's not built
into our active pipeline. - Yes, okay, perfect. - So at some point we might support that but we'll probably have
to download the image and do that image
manipulation on the client. So we haven't bothered with that yet. - Sure. Okay, cool, so this is our query, which means that in here
we're going to get data. And inside of our data we
can do something like this, my portfolio. I'm going to get rid of the rest of this and we will do, let's see
what's the semantic way to do something like this? It's going to be a list of
projects and links to 'em so I guess we can just do a list and we'll start by let's do a data dot all Sanity
project dot edges dot map and then that's gonna give us a node and I'm gonna rename that to project so that I have a little more clarity on what I'm actually accessing. And so in it we've got
the project dot title, dot description dot slug. So let's do li set at key of
project dot slug dot current and inside of it for now let's grab just the project dot title. And what this should give us if I save and refresh the page out here,
we get our list of projects. So that's pretty slick
right out of the gate and we can expand this a little bit. Let's do, let's import
Gatsby image, Gatsby image and that means that down
here we can do the image and we'll do fluid
equals project dot image dot asset dot fluid. Did I get that right?
- I think so, yeah. Project dot image asset fluid, yeah. All right and then the alt is going to be the project title. Always got to set your alt tags. And let's set a description down here. And it's not HTML, it's just text so we can do a project dot description. And what we will eventually do is link but we're not quite there yet so we'll just put that in
as a placeholder for now. And there we go. We're getting lazy loaded
images that we have, it's fluid by default. That is pretty slick. So let's-- - Can you inspect the
image and just check if, I think it should also be able to, I think it should out of the box now use the web P version
since you're using Chrome. - Let's find out. It is using-- - Oh, I'm not sure what the right-- - Format Web P. - Well it's in the source
separate list so yeah. - Yeah, so it is definitely, let's see, which one is it using? Current is format Web P. Yep, yep, we're getting the right one. - Oh, there it is, okay, sweet. - Cool, very cool. So that's pretty slick, man. That is a painless setup,
especially let's see, just checked the comments real quick. Nope, looks like, yep Newt's
got it all in control in there. (laughing) All right so let's play for a second with just some really basic styling. So I'm going to do CSS and JS to avoid having to install a styling library. And maybe that's, let's see if I can right flex box on memory. Align, is it items or content? Align items,
- Items. - space between and then down here we can do style and let's see flex will be one and 45% and maxWidth will be 45%. And what is it for this? I think we need to set padding of zero. Let's try it. How did I do? CSS by memory. - Oh!
- Yeah, that is not half bad. I will take that.
- That was impressive. (laughing) Well done. I would have failed so hard on that. - Let's go font size. We'll make this big but
not huge, 24 pixels. Yeah, I'll take that. Let's add a little bit of margin but otherwise I think
we're gonna leave that be because this is not a
livestream about styling things. So I'm gonna take that. That's acceptable. We'll, I'm gonna add a
little bit of margin to it. I can't, okay, this is the last
thing I'm adding, I promise. Okay, that's good. I just couldn't handle it. - So can I show you one other feature before we go into the page building? - Yeah, please do. - We have one more really cool feature for the source plug-in called watchMode. So it will be kind of cool if you could try to set that up just to
showcase how that works. So if you go into the Gatsby config and set, so in the options
set overlayDrafts to true. - Ohh, secret options. - Well, they're documented actually. Just further down from
the Getting Started thing. - Gotcha. - And also set watchMode to true. And we also want to add
a token so we have to go into the management console for a bit. - Okay. - And under, this is kind
of weird, go to the settings and then API on the left
and then under tokens you can add a read token. Just give it Gatsby or something. Then copy this and paste that in as token in the config. - Okay.
- All right. We'll save that and-- - Turn it off and on again. - Yep. So if you go to the frontend now, it's up and running. - It's up and running. I've got this one here so let's, nope, that's not what I wanted. I want this one. This one here. Let's go side-by-side. - If you just, yeah, if
you just keep that there I can actually start
editing my react-markdown. I can't actually see this. - That is, holy shit, that's amazing. (laughing) That is really cool. So this is definitely really awesome. I'm just entirely
impressed by that actually. - I can actually just change, let me just change to see your image. - Oh, come on. - And see that it works for
basically everything in here. And this is using the
same real-time principles that we have in the Studio. So it's just a listener
that is never using any additional API requests. He's just using, it just has a listener that's listening for changes to documents and then basically updating
those within Gatsby when it changes. So it's really cool. - That is real cool. I just realized that I
said I was gonna stop. I can't, I have to fix one more thing. - Keep going. - Um, why are you not? Oh shit. Where's my flex wrap? Come on. What, why? Okay, I have clearly
forgotten how this works so I'm just gonna let it go. (laughing) So yeah, eventually I'll figure out how flex box works but let's, it just gets better. Each little feature that you show is like one more amazing thing going on. So let's build some pages then. Let's make these visible here. So let me show, let's go to Gatsby config or Gatsby node and we are going to do a couple of things here. The first is I'm going to try to remember from memory how all of this works, which is probably gonna end poorly for us but we can give it a shot. So the first thing we want to do is we want to run our query so we're gonna do a result. So this needs to be async. And we're gonna await GraphQL and we also, wait, no, we can do it like this. So what I need to make
this work is actually a little bit simpler than what we needed for the first one. All I actually need is the slug because the slug is going
to generate the pages and that gives me the ability to then do a query on the page
template that we have yet to create. So I'm getting my result
and then I'm going to get projects by parsing this result. So we're gonna do results
dot all Sanity project dot edges dot map and we'll do node and we'll just return that node. And so what this little bit of code that I just wrote does is it turns each of our projects into an array now of just the slug and the current. And that's gonna make it a
little easier to loop over. So then I can do a projects dot for each because that is not
going to return anything. And for this one, we're
going to do actions dot create page and can
I do this from memory, path equals project dot slug dot current. Template we need to create and context we want to include the
page slug dot current. So all of that being true we need to build our template. And so this template
that we're gonna build is going to live in source
and I just created templates. And inside of templates
we're going to call this project dot JS. Inside of project dot JS
we're gonna grab react and we're going to import
GraphQL from Gatsby. And we'll do a bunch of
other stuff here in a minute but for the time being,
let's see constant query equals GraphQL and the
query that we want for this is going to be a little bit different. So we want to do sanity
project and we're going to get it by slug equals and we'll just hardcode one for now. Actually, no we won't. We'll do this the right way. So it's going to be slug, the
slug is going to be a string and we're going to make sure
that the slug equals it. And then down here we're
gonna get the title and we'll start with that. So let's set up a query
variable and the slug that we want is, let's
see I remember this one. So let's prettify that and run it. And that gives us our project and if I do let's say the description, we get it and then we want the
image and that was asset and we're gonna use the
fragment but we don't have that right now so I'm just
gonna grab the source. And then we don't actually
need the slug on the page because we've already gotten
it in the form of this and also we're just not
doing anything with it. So if we grab this and we drop it in here, the reason that I set the
slug in Gatsby node's context is that anything that we
pass in this context object is going to be available to the
GraphQL query as a variable. So by setting that we
can say that whenever you create a page, pass
along this variable and then we can grab it and use it here. So let's then export our default, which is gonna be a react component. That's gonna have some data and for now we can just do a kind of a simple setup. Let's do a div, we're gonna do an H1. It's gonna have the
data dot Sanity project dot title and let's do
the description too. And I'm taking a couple of shortcuts here. Like I'm not checking to make
sure that things are set. Like if there's a potential that the description could be left
empty and we wouldn't want that to break our layout. So in a production app, I
would want to check that. For the time being, I'm going to save this and then I'm going to
go in here and I'm just gonna point to it. We're gonna go to source,
we're gonna go to templates and we're gonna go to project. And now assuming, let's see
I already made one mistake. So projects and then we go
to our projects for each. Let's see how well I
did going from memory. So we can take this, yarn develop. Did I get it on the first try? - I think so. - (laughing) Nope. - Oh, nope. - Let's see, where did it go? I screwed something up. Can not read property edges of undefined. So exports creates pages. What did I do wrong? All Sanity project dot edges. Oh, I bet it's result dot data. Only console log this just in case. - Yeah, because there's a
result of error as well I think. - Yep, yep, yep. All right so let's kill that
and try it one more time. And what we should see here is let's see-- - Yeah, (crosstalk). - Created a page with a
component that doesn't exist. Which means source templates project-- - I think it needs to be an absolute path. - Oh, that's right. Well, we almost did it in one try. Let's do constant path equals require path and we're gong to do a path dot resolve and try it again. I did set the absolute path. Gatsby portfolio's source
templates project dot JS. Did I screw this up. Templates, project dot JS. Oh,
- Oh it's some pages. - No, no it's not. Source, templates. Source templates project dot JS. - What happens if you click on monthly. - Takes me right to it. - That's weird. Oh, have you actually ,
I don't know if you've ordered any default. Could that be it? Oh, you have, okay. So that's not it. - Am I missing something obvious? - Maybe someone in the comments? - Yeah somebody save me. Save us from ourselves. What are we doing wrong here? Maybe we can just start here. Maybe I broke something. No, you definitely exist. Sanity Gatsby portfolio. - Oh, you don't have to get stumped but I think it's a component. - It's source templates. - No, I mean the key. I think it's-- - Oh, is it just me not knowing how, it's probably me not knowing
how things work, isn't it? - Yes, yep, yep, people bailing me out. Okay, cool, thank you for teaching me how to use the product
that I'm supposed to be teaching you how to use (laughing). Sorry everyone. - I was just doing a presentation
on this the other day so that's why I remembered. - Okay, so you've got that, take this. Try it one more time. This is it, it's gonna work. We created pages. - Yay! - Yeah. All right, let's give this a shot. So we haven't linked to anything yet but I didn't mean to close that, I want this. Let's try just going to lengstorf.com and it does work. So that's cool. So now we can actually make
this look like something. And let's do that as quickly as possible. So we're gonna import layout
from components layout, swap out this for the
layout, and that's gonna go a long way for us. And then we can get image. Gatsby image. And we can, let's put it right at the top. I think that's gonna look nice. Let's go image fluid equals Sanity project image asset fluid and
then we'll set an alt of the data Sanity title
and we will also set a link. It's gonna auto import? Yes, it is, to our homepage
and call that back to home. And something broke
and the reason it broke is because I didn't use the fragment. So we didn't send it enough
data to actually do anything. So let's do that. There we go. We've got our project. I'm not gonna bother styling
this because that's not what we're here for but
you can see we've got live editing happening right now, which is awesome. We're able the go back to the home page. We've got new projects that have been added since we started. This is pretty awesome. So let's make these linkable and to do that we're just gonna
go back to this home page. We've already got Link imported so we're just gonna use it. And we have the slug already so we can just grab that out. And in these we've got our project. So we've got the project
slug current going here, which means we can just do
things like nope, not that. We're gonna do this. And out here we'll add that link broke it, what did I break? Broke that, okay. So now we've got our link and if I go to the homepage, got to refresh because I broke things, these are now linkable, right. So we can do the same thing over here. What's going on? I think I accidentally opened
something on the other side. Let's go over here and
let's add that local link. So we've got a link to
project slug current and we can see, let's see project details, that seems like a good one. Here, so now we can see
our project details, we can go back. You can see the project
details for Sanity, we can go back. So this is pretty slick. We're let's see how far,
about an hour and 15 minutes into this and we've managed
to set up a database, add some data to it, build
a full portfolio site. We've got real-time editing,
we've got image management, lazy loading, all this good stuff. This is pretty awesome. So I think we can probably
stop with the Gatsby part here unless there are any questions. Looks like there are no questions. So now would be a good time. We've got about 15 minutes left. If anybody wants to jump in
with questions in the chat, please do and Espen
and I can answer those. In the meantime, I'd love to go back and play with some of these more advanced features in the Studio. So let's dig in here and
maybe you can show me how to update like the
previews, for example. So if I've got my, see I
want to open the project. So to do a project I
just do preview, right? - Mm hmm. - Let's pull this side-by-side again so we can look at the example. I'm gonna open up the post. And so the preview shows me, and so the select is just
what shows up in there? - No, it's just like which
fields you want to select. So there's a couple of placeholders for title, subtitle, and media. And then if you want to,
so if you just need to map the field directly
to one of those slots then you can just use select. But if you want to, yeah, like that and then you can say like subtitle is forward of name, for instance. - Okay. - And if you then get a
syntax thing going on there. - Oh, cool, got it. And so we can, well let's
just skip that for now. Let's just do this, we'll
save it, we'll go visit. Where's the local one? Here. And then-- - Is the server still running? - Is the server still running? That's a great question. Sure isn't. - So just restart or reload Studio. You can do that right now. It'll just stall until it actually loads. - Oh, that's cool. - Yeah, so you can use
the prepare function that was in the other example
to do more like complex stuff. Like say date formatting using moment or I don't know combine different sources, different fields to create a more, like one thing I did for a project is to create sort of the media field. For recent items I could
make it just a color that was green and the older it got the more like opaque the color got. That's one way of doing it. That's like just the author
below as the subtitle. And if you want the image back then you'll just have to add media screenshots. I can't remember the name of the field. - Just image. - Image, yeah. - So add image back? Now we've got our images. Let's play with this prepare function. So that is, so here's preview. So I'm gonna go to prepare, selection, and do const. Okay and let's do, is this gonna fail for me if I try to do res spread? - No, it should work. - I think positive affirmation
is an important thing. So let's, nope, I broke it. So what did I do wrong? Let's hide this. Okay. Did it give us an error
when that went wrong? - That's weird. - Subtitle. - Oh, because the actual
selection is the result. So the author will actually
be in the subtitle field in this case because you
selected author dot name to the field called subtitle. - Author dot name to the field called-- - Yeah, because that's the original one. - Oh, oh, I understand. Let's just switch it back. - So it's just like a shortcut. If you don't need to
use the prepare function then it's a simple way to ping it. - Ah, that is, that's super cool. So I mean I guess this
is more of a toy thing than it is like a supercritical thing, at least for me in my case. But it's very cool that you have control over things like that because I can see a lot of cases where that
would be really useful. - Yeah, that's just like the most basic of customizations you can do. Or you can also do things like customize the actual navigation structure. So right now it's very
coder grammar-oriented in the way that the
content types are shown in the first pane and
then just like the actual document of that content
type in the second pane. And then the document is
being edited in the third. But you can actually define these using a builder's syntax that we made. So you can make more
complex more workflow things like show me all the things
that are waiting review or show me all the stores
in my company that's within this state. So you can list all the different states and then make sub-selections
and queries based on that. So there's a lot of-- - Is there an easy way,
how can we show that? So let's assume that anything that was written by me needs to be reviewed. How would we add that functionality? - It's gonna take probably
like 15, 20 minutes I would say because you need to actually implement this using, actually there's some documentation on it. It's called Structure Builder. So if you go to docs
dot Sanity dot io other. - Structure here somewhere. Structure Builder. - Yeah, it's one of our
experimental features but it's working quite nicely now. So you can see an example
there for how to use that. You could also just create a new project, like a Sanity project and use
one of the other templates. And one of those should have
a default structure set up. - Oh cool, so you just
create a structure here. - Mm hmm and then you just
tell it where you want to implement it and then you
use this builder's syntax that's on your screen right now. And that allows you like
very fine grain control. You can say which item should be there. If you want to run a
query, you can do that. You can tell it to list
items that should be possible to perform on something. You can even override the
action that should be handled when you click on an item. So you can make things like you can actually implement like
a build Gatsby site document for that particular view. I've used that to make conditional builds on Netlify, for instance,
so that I can build different parts of the site. I can split the site up
into different Gatsby sites and just figure out
specific goals using that. So it allows you to
get really nitty gritty into how you want to build it but there's tons of ways to do that. You can even make recursive structures. You can build a tree structure. - This is super slick. So I can see so many
different ways to use this. Like if you're in an agency and you want to give your clients a Bespoke feeling CMS without having to actually build a CMS. Or if you've got like a content team and you just want to make their process as simple as possible with
no bells and whistles. Yeah, there are a lot
of ways that I can see this being extraordinarily
helpful for people. - Mm hmm, yeah, that's the end goal is to be able to not
say no to any features that a client might request from the CMS and you to be able to customize basically every aspect of the Studio. And we're working on
figuring out the high level abstractions that makes
that easy to work with. Because right now we've made the structure is like the first pass at what we think that would look like. Like a high level abstraction
of what I can make a more fine grain control
of the navigation structure. And then we'll work from there to add more features down the line. - So this is, I mean this is great. I think we're just about out of time. So what would you recommend
as a next step for people if somebody wants to go do more? I mean I think the obvious one here is go install Sanity, give a shot to kind of building your first little project and get a feel for how it works. But what's next? How can someone go deeper? - We made quite a cool example
using Gatsby and Sanity if you go to get org docs
org slash Sanity dash io. No dot com, Sanity dash io. A typo there. - Right, I can spell. - There should be one called example company website Gatsby Sanity combo, yep. - Okay. - And then actually I would--
- I think I saw this go through (crosstalk) - That's a quite a cool
example that, sorry? - I think I saw that get
posted in the chat earlier but I was throwing it in there anyways. - Yep. It allows you to, it gives
you basically sort of the same things that we set up now. A portfolio, a company, information, different authors, all
that kind of good stuff, but it also gives you the
concept all out of the box. So that should give you a kickstart in getting started with a
couple of other aspects of it, like real-time bits and as
well as the rich text editing. - Very, very cool. So it looks like, we lucked out with Newt handling the chat for us
and he did a great job of answering questions. So thank you very much
for doing that for us. To everybody who watched,
thank you so much for coming and participating in the chat, for watching the stream. And do you have anything
that you want to part with? I posted Espen's Twitter in the chat so please go follow him. Go check out Sanity. Please reach out to me on Twitter if you've got questions and I'll post the source
code of the portfolio that we built today later and I'll tweet a link to that some time today. Any parting words, Espen? Just give it a try, let us
know what you like and dislike. And sign up at our Slack on Slack dot Sanity dot io. Would love to hear any feedback. Just trying to make the
product better everyday. So yeah, let us know. - Awesome. - And thanks for allowing me to, yeah, set up a your portfolio site with you. - Yeah, of course, thanks
so much for being here. Later, when you've got more, there were some other
features that we talked about that weren't quite ready to demo yet that I would love to play with. So when those get stable,
let's do another one of these. - Oh yeah, that'd be fun, yeah. - Awesome. All right, thanks so much. We'll see you soon. - Thanks, see you.
Great video! I could follow along pretty well