- Hello, everyone, and
welcome to another episode
of Learn with Jason.
Today we've got Shawn Wang.
Shawn, thanks so much for coming on.
- Hey, thanks for having me.
- Yeah, so today, we are
going to learn about Netlify
and specifically, we're gonna learn about
Netlify Functions and Identity.
Is that right?
- Yeah, hopefully, it's a lot to cover,
but hopefully we'll get it done.
- Okay, so um, do you wanna
maybe, I guess as a start,
like Netlify has a
whole suite of products;
and so I think the one that most of us
would be familiar with
is Netlify Build, right?
This is how we're
publishing our GitHub repos
onto the web, using Netlify.
- That's right.
So actually, we never
called it Netlify Build
until probably about
three or four months ago.
And essentially Netlify,
you know we rebranded
our offerings into three different things:
there's Netlify Dev, Build, and Edge.
And that's on your screen right now.
And so Build is, yeah and Edge,
so Build is the primary thing
that people know Netlify for,
which is our a build bot.
We help to run the build
processors to outside generators,
and then host them as
static sites, on our CDN.
So we're a CDN first hosting platform.
And then we released Netlify Dev recently
and that was the CLI developer
net, we can talk about that,
which is just running the local,
well, taking your entire
production environment
and running it locally, so you can test
before you actually push to production.
And then finally, Edge,
is something that we'll
be talking more about
in the future with sort of smart Edge,
it's called Edge Logic,
which is pretty similar to,
I can't really go into much detail,
mainly because I don't know
that much detail about it.
- That's how I, people are
like, "What is Gatsby build?"
And I'm like, "I would love to tell you,
"but I swear I don't understand
how the technology works."
(laughing)
- Basically, so you know that thing,
so you and I were at Gatsby days,
and people were asking about redirects
and how complicated some
redirect setups can be.
Currently, in Netlify, it's a static file,
where you define redirect
from this to this
with some status code
or some other kind of.
There's some flexibility in
how you do the placeholders
and stuff.
- Okay.
- But what we want to get into
is programmatic redirection,
so you can actually use code
to direct people back and forth;
and we're gonna be using some
web assembly on the Edge.
- Oh, well, that's pretty cool.
- So we're hiring for that (chuckles).
- So this is kind of,
but today we're actually
talking about add-ons,
not products.
And the first one that we're
gonna look at is Functions.
And so Functions is not like
a unique to Netlify thing,
but just the idea of serverless functions.
Do you want to, actually,
do you want to talk a little
bit about how those work
and then we can talk about how they work
at Netlify specifically?
- How Functions work?
- Well yeah, just in general,
because I feel like this is,
when you start talking about serverless,
it's a new mental head space to get into;
because it isn't immediately intuitive.
Because like of course
there's a server, right?
- Mm hmm.
Sure, so the way, for total newbies,
it's essentially, you
know, compute on demand.
Where previously you would
have a virtual private server,
or some sort of box, you
know, sitting somewhere,
like a digital ocean or something,
and you're paying per
month, like $5 or something;
with Functions, it's essentially
like compute on demand,
whenever it's being used, you get charged,
for example, per invocation.
And so it scales up and scales down
together with your usage.
And it's pretty good for Speccy loads
as well as stuff that, you know,
it's a side project, you
don't anticipate much usage.
We have a pretty generous fee here,
I think it's like a minute, or something.
Actually no, it's like
100 thousand per month?
Per week?
It's on the pricing page.
But I've never run into it.
But it's actually stateless
Functions to execute.
It's really good, in particular,
if you're hosting a Gatsby website
and you have some API keys
that you don't want to
disclose to your front end.
What you basically do, is
your stick your API keys
in a Function and then,
from your front end,
you just call the Function.
And that basically hides your token
and that's a really good first
use of a service Function.
- Interesting, yeah.
So if we have, probably we'll
do a proof of concept here,
with something simple
like newsletter option,
or whatever, but that's
kind of what you would want.
So if you have a static
site, like a Gatsby site,
and you want to make it do something,
on user interaction,
that needs to get stored,
or sent somewhere; you could just do that
directly through like a fetch call,
but that back end has to exist somewhere.
And so some hosted platforms, you know,
like if you're trying to sign
somebody up for MailChimp,
MailChimp's already
got the server running,
you just have to send
something to that server;
but if you were trying to
save like your own database,
like a good example of this is,
Kyle Shevlin did something
on his personal site
that I think is really clever,
where he did...
Is it .com?
He did a beard strokes.
And so when you get to
the end of the article,
if you want to tell him
that he did a good job,
you can stroke his beard.
- Stroke his beard!
- Right?
And so, in order to do this,
he needed a way to store this information.
Now I don't know how he built it,
but I bet we could rip
this feature off today
and build our own beard stroking,
or you know, whatever we want to make it,
and we could do that
through Netlify Functions.
We'll be able to send it
somewhere using a Function, right?
- Yeah, totally.
So one thing that is still
not a super smooth part,
it gets easier every year,
but one thing that it doesn't
do is have storage in it:
so it's only serverless compute
and it doesn't have serverless storage.
For actual storage solutions,
there are other options
that we can discuss.
And, in the Netlify world,
that is primarily provided
through add-ons.
And we have a bunch of other
add-ons that we can talk about.
- Sure.
- So yeah, it's not directly listed here,
but I can talk about
those, when we get there.
- Okay.
Well, so another thing
that you can I talked about
a little bit before, is Netlify Identity.
And so we've done a
handful of streams on here,
about how Identity works.
And so we've set it up with Auth0,
we've set it up with Okta,
and no matter how, and
they've both done a good job
of making this easy,
but still there's a lot
to think about.
Because OAuth is a complicated thing,
it requires like you gotta go to a server,
and then you gotta come back,
and then you gotta go back to the server,
and then you end up with a token.
Then you gotta store that token
and make sure that you use
it when you send calls.
And it's just a lot of things,
it's a lot of hoops to jump through,
if you're not really
familiar with that world.
And you have been working on something
that I thought was really cool,
and so maybe, I thought,
the first thing we could do
is let's just build a site,
and then let's hook that up:
let's set up Netlify Identity
so that we can log in
to this website.
- Yeah, totally.
And I think, this is
one thing about Netlify,
which I didn't appreciate before I joined,
but not I get more and
more excited about it,
is that it's not like that,
you can absolutely use Auth0
and Okta, and whatever,
with Netlify.
And Netlify tries to
stay technology agnostic,
but it tries to iron the path,
so to steam iron the path of, you know,
of common user problems.
And that's where I
position Netlify Identity.
It's not gonna be as full
featured as Auth0 or Okta,
because those are,
I mean they're entire
giant unicorn companies,
dedicated to the problem of OAuth.
But for most solutions,
Netlify Identity's gonna be good enough.
And for that trade off in complexity,
we get a much easier set up experience:
that's why I like Netlify.
- Yeah, cool.
So what I'm doing right now,
is I'm just setting up
a default Gatsby site.
We're gonna use the default starter.
I've got no major changes here.
So what I figured we can
do, is we can build a page
that we want to be authenticated.
Or even just some data that
we want to be user gated,
so maybe a profile widget or something.
And we'll be able to use,
like you built a package for this, right?
- A package for?
- For the wrapping Netlify Identity?
- Yeah, yeah, it's called
React Netlify Identity.
A very creative name.
- I think that's a good
name for a package,
it does what it says on the tin, right?
- Yeah (chuckles).
And my dream is to eventually
make it into a generic thing:
so React Identity.
So this is just a React hook.
So there's no UI bundle with this.
And, obviously, I'm a super lazy guy,
and when I wanna just
throw off on something,
I want the UI to come with it,
so that I don't have to code it.
So there's also React
Netlify Identity Widget.
And so those are two levels of extraction,
depending on how much sugar you want.
- Okay.
Well so, just to give us a
baseline of where we are,
I'm gonna run Yarn Develop.
And this is gonna get us,
just kind of where the site is by default.
And this,
should be running at localhost:8000.
Okay, we're waiting for
the site to start up here,
so it's just telling us to chill.
Okay, here we go.
Alright, so we've got a default starter.
Let me make that a little bit smaller:
that's kind of absurd.
And this is pretty straightforward.
So we've got a simple
page, we've got a page two,
and that's kind of what
exists, in this starter.
So the next thing that we want to do,
is I want to install
react-netlify-identity.
I guess I have to actually add it.
- Um so my question is,
do you want the widget,
or do you want the Identity,
or just the React hook?
- That's a great question, I don't know.
What's the difference?
- Let's do the React hook.
Uh, sorry, let's do the widget,
so you should have the
widget at the end: -widget.
- And do I still need this package?
- Sorry?
- Is it still the right?
- No.
It re-exports, yeah.
- Okay, so I'm gonna install this.
And then--
- No, uh.
It re-exports, so.
- Oh, not.
Okay, so what am I installing?
- So: yarn add
react-netlify-identity-widget.
- react-netlify-identity-widget.
Oh, got it, I understand.
- Yeah.
- Okay.
- I think we'll also need
Identity page plugin,
if that's what you want to do.
For Gatsby.
- So we've got a widget.
And what's the page plugin?
- Um, are you doing a dynamic page,
or are you just, no, no, no, no.
Not, this is a Gatsby thing.
- Oh.
- Are you doing a dynamic page
or do you just wanna do
a login on this form?
On this static page?
- I don't know, what do you think?
(laughs)
Like, we can go either way.
- Yeah, you know what,
let's keep it simple,
and let's just do this page.
So we got the Identity widget.
- Yes, it is now installed.
- Right.
And so now we have to just,
you know, import it somewhere.
- Okay.
Let's make the whole
site, we'll have to login
for the whole site.
So I'm gonna put it in the layout.
Okay.
And so what am I, what
do I want to import here?
- Right, so you're importing,
useNetlifyIdentity,
that's the hook.
Yeah, de-structured.
- And is this de-structured?
Okay.
useNetlifyIdentity.
- This is on the ReadMe, by the way,
you can just copy and paste.
- Oh cool, yeah, let's
take a look at the ReadMe.
So we're going to, oh, do
I need to get all these?
- Oh yeah!
I forgot about that!
I'm sorry.
- No, no, no worries.
That's what ReadMes are for.
- There should peer dependency warning.
- Honestly, there may have been,
I totally wasn't reading.
Um, yes there is.
So we're going to add all of these.
And then, so I'm gonna
get the useNetlifyIdentity
and the ContextProvider.
- And the CSS.
- And then the CSS.
Okay.
So I will just stick these up at the top.
And, what don't you like?
It's fine, it's fine.
Okay.
And then,
once we get down in here.
- So inside your layout component,
you have to useNetlifyIdentity.
- Okay, and am I doing this?
- There's a hook, yeah, so
you gotta change that into a
one of those things, yup.
- Okay.
And what comes out of it?
- Alright, so it's
const identity = useNetlifyIdentity
and then whatever your
deployed site thing is.
- Oh, so we need to deploy this
before we can do anything with it?
- Um, you don't have to, you just need
to link up those sites.
So if you open up your terminal,
and you go netlify init.
- Do I have Netlify?
No, okay, do I install this with Brew?
- Yeah, npm i -g netlify-cli.
- netlify-cli.
- Uh-huh.
- Yeah so, I have to make a confession,
I use Netlify all the time,
but I literally only use
one thing from Netlify.
I've always just used it
as like, it's kind of a CI.
You know like, I set it up
for a site and I let it rip.
And then I haven't dug into
any of the other features,
which is why I'm so excited
to have you on today,
because I feel like I'm foolish
for not using the Identity
and the Functions;
because they're just like
sitting there, easy to be done,
and I'm over here like
messing with AWS Lambda,
like a Luddite.
(laughs)
- The a thing about tech--
- I'm just kidding,
Nader Dabit, if you're watching.
- you know, once we
know how to do a thing,
and it's not a broken, like
there's very little incentive
to change your habits, so it's fine.
Oh, and just to be clear,
you don't have to use the CLI to do this.
This is just the way I prefer to do it.
It is really that much easier.
- Okay, so now I have Netlify.
- Okay, so now we're in the
repo that you're working on.
So all you just do is just netlify init.
- Okay, netlify init.
- Mm hmm.
And it just walks you through...
Whoa, oh, okay, it's asking you
to login for the first time.
- Okay, that makes sense.
- Alright, just head back to your uh--
- Close this window, back to the terminal.
- Um so, you're not linked to GitHub.
So actually I'm not sure if, yeah.
- Let's see what happens.
- Let's link it up to GitHub.
- Hit that button, oh and
it wants me to do stuff now.
Okay, so let me do...
How does this command work?
It's like, git create,
and then I'm gonna call
this netlify-gatsby,
or wait,
identity.
I don't know, that's
a bad name for a repo,
but I'm rolling with it.
(chuckles)
- Is this the hub functionality?
- Yeah.
I love hub, like I don't
know how I would exist
without hub.
Let me--
- You know how you're a bit guilty
about not using this the CLI?
I don't use hub to create my repos.
I go onto the website.
- I, oh my God, it's amazing,
it's like, I added a
couple of aliases for it,
and like all the tab completion and stuff,
and it legitimately changed my life
as an open source maintainer;
because so many things
that you can do fast.
Okay, so I have--
- Yeah, you can ping on
PRs and just review PRs
just by their PR number, which is awesome.
- For sure.
And so I have done almost all of this.
So now if I do like a git remote,
it'll show me that I have it.
So it did that.
Did I commit anything though?
So let me just add everything.
And let's figure out what's in here.
Good.
Good, good, good.
And we will just git commit.
I don't know, I forget
what we were working on.
We're just gonna commit as is.
No, that's gonna break, I can't do that.
We're gonna git reset.
Git status.
Okay, so we're not gonna commit that,
so let me just push.
Alright, so now, I've pushed code,
so if I run netlify init again.
It is already authorized.
And I'm going to
- So you're gonna create
reconfigure on your site.
- create reconfigure.
Okay.
And we will call this.
- Now just the site name.
Up to you, you can just hit enter
if you want a random site name.
- Uh, I feel like I'm
gonna need to link to this
from somewhere.
I still don't know.
- Alright, just name it the same thing.
- netlify-identity-functions.
That's bad, it's such a
bad name, what have I done?
I'll put it on my team.
Um.
What is this?
What is it doing?
- Why is it asking for your...
Oh, it's asking so it can
commit to Git for you.
- Oh.
- Why is it asking that?
- I don't know.
- This is new.
I'm always logged in, so this new for me.
- Yeah, maybe I need to do
some kind of an Auth thing.
Uh, whatever, let me pull it up.
I'll just grab.
Let's see, hold please.
- Damn, this is the real,
like first-timer experience right here.
- Yeah, like I said, I come
in completely unprepared
for these.
(laughing)
- You know, obviously I started
using this a long time ago,
so I don't even remember.
- Oh come on, what is.
Or hold on, now I gotta look up my,
Thank you for doing
this through GitHub,
- this is gonna be like
a first time thing.
- I am so upset.
- I never run into this.
- Alright, let's do this.
And.
- Okay, so this is yarn build.
- Yarn build.
- And for Gatsby, I think
the directory you deploy
is public.
Mm hmm.
Uh, yes.
And just hit enter.
- Yes.
- So, you used to have to set up,
manually set up Netlify tunnel,
and now we just write,
whatever you just wrote,
into a Netlify tunnel.
And now we create hooks for you
so that whenever you push,
it deploys to Netlify.
- Cool.
That's pretty awesome.
And then if I just do netlify open.
- Okay, so netlify open, yeah.
Yeah, you knew about that.
- Well I was just reading it.
(laughs)
it opened in my other browser,
so let me open it here.
- Okay, so now it's
deploying for the first time.
One thing that we should set up now.
Well it's gonna be--
- But we don't have to watch,
I just love, I just love seeing that:
that like I didn't touch
Netlify's site at all
and that deploy's like already running.
That always makes me happy.
So now I need to set up Identity, right?
- Now, so we're gonna go to Identity.
Yeah, well it's just one click.
So just Enable Identity.
- Oh, I just Enable Identity.
- Um, you know what,
we're gonna do some extra stuff as well.
So let's go to, actually no,
let's just leave it at this.
So the default Identity experience,
is just username and pass,
well email and password.
And we set up email
confirmation for people as well.
So we're just gonna do that,
but then Google Auth,
and GitHub Auth later.
- Okay.
- So let's head back to the code.
So we can grab this, yeah
we can grab this site right.
So
gatsby-netlify-identity-functions.netlify.com.
- Do I want the whole thing, or?
- No, just the .com.
- Okay.
- I should probably parse it
so it's somewhat resilient.
And stick that as a string into there.
- Okay.
So we're adding that.
And now I have an identity.
- Right.
So you're gonna use the provider.
IdentityContectProvider.
Yep.
- Okay.
- And stick that around your
layout or your children.
Do you have a children,
if you scroll down?
- I do have a children.
I'm actually wondering
if I wanna do this as a,
like wrapping the root element,
cause other wise this is
gonna un-mount and remount
on every page navigation.
Um.
I mean I guess it doesn't really matter.
- Let's see what happens,
and we can fix it.
- Yeah, it may matter, let's find out.
Okay.
And then do I need to
pass the identity into it?
- Uh-huh, value=identity.
- Value=identity?
- Yeah, that's just how
React's context works.
Okay, so now we've got it all set up,
and now we can use this thing.
- Somewhere.
- We also need to, yeah we
have to use it somewhere.
(chuckles)
- Oh wait, I wanna be able
to use it in the header,
so I'm gonna wrap more.
I wanna put it up here.
- Okay.
- So I'm gonna use it
instead of a fragment.
Okay, and then there was something else?
- And let's add in modals.
So the extra thing that ships
with React Netlify Identity
Widget, is a modal.
And that's the default export.
- Default export.
So I can just call it like Identity,
I can call it whatever I want then?
- Yeah, I call it IdentityModal,
that's exactly what's in the docs.
(chuckles)
- Okay.
And then?
- And then, just stick it at the bottom.
It's a portal, so it really doesn't matter
where you put it.
Just somewhere inside.
- Alright, then I'll just
throw it down at the bottom
so that I don't have to do any,
- IdentityModal
- any stuff.
Do I have to pass it anything?
- I'm sorry?
- Do I have to pass it anything
or does it grab it out of the context?
- Yeah, yeah.
So if you look at the docs,
what I have is a Boolean and so this,
right, yeah okay.
So if you look at the docs,
what I have is a Boolean,
and it's like, you just have true false.
Oh I have a suspense in there as well,
just cause why not, right?
(chuckles)
- Okay, so we've got this modal.
- So it's, yeah showDialog=true or false.
And then what happens
when you want to close it,
is you set it back to false again.
Or you can do other commands.
So here's a question of where
do you want to put state?
Do you want to put the
state in the top level?
Or do you want to control
it somewhere lower down?
My suggestion is, actually,
we should probably implement this modal
outside of this layout component
and inside one of your pages,
so that we can collocate the state.
- Yeah, let's, you know what,
let's toss it in the header,
so let's do that.
We will um...
We won't grab it from here.
And instead, we'll go into the header,
and so now I'm going to
import IdentityModal from
react-netlify-identity-widget.
And then here, I can, do I need to,
do I need to get like the
context consumer or something?
Here I can just use state, right?
Like I'm not doing anything magic?
- I'm sorry, I'm a bit confused.
You can use state, yeah you can use state.
Yup.
- Okay, so I'm just--
- Yup, there's no consumer,
cause the hook wraps the consumer for you.
- Okay.
So I'm able to showDialogue
and that needs to be a value,
so the value that--
- You can copy and paste from the docs.
- Yeah, I think, I try
not to copy paste to much,
because it's, like I
have a hard time learning
if I don't type something out;
and I think just kinda stepping through it
is also really helpful.
So we're gonna set up a
const of like showDialogue
and setShowDialogue.
And by default, we want this to be false,
so we're gonna initialize
a react state with false.
And make sure that we import useState.
- I always do the React.useState,
cause I can't be bothered.
- Oh, yeah yeah.
Man, I remember I used
to do that all the time
and then at some point I stopped.
And it left my brain so fast
that that was even possible.
It's really bazar how
quickly I just forget
how everything on the internet works.
(laughs)
So we have this showDialogue,
so I can use this now,
to say we've got the Identity Modal
and we're not gonna show it.
But, we do want to have
some logic to show it.
- Mm hmm.
So this is closing it from inside.
- So this is where we
need like a login button.
- Yep, you can take the button.
- Got it.
- And I call it setDialogue,
but whatever you wanna do.
- So here we have,
I'm gonna have to do some
gnarly inline styling here,
but we're gonna do a button.
Is this, wait, for accessibility,
should this be a button or a link,
to do a login home?
- I think it's a button.
- Is it, yeah?
Yeah.
- Cause you're not navigating anywhere.
- That's right.
- Just it does a thing.
- Is Amberley in the chat still?
Because she's our resident access--
- She was.
- We need the accessibility
chops here, Amberley.
I'm gonna start writing this
and then she's gonna
tell me that we're wrong.
- Is it a button?
(laughs)
Do you have a poll function on Twitch?
- Uh, I don't know actually.
That's a great question.
- Oh no, I typed all
caps and it warned me.
(laughing)
Message deleted by moderator.
- I need to chill that moderator out.
I thought that it would be helpful
and it's just been a pain in the ass.
I think I need to turn it off.
So we're gonna setShowDialogue to false.
- You're not the boss of me, Nightbot.
(chuckling)
- And then we're gonna say Log In.
And so we wanna show the dialogue
when you click that button.
And I'm going to need...
This is gonna look hideous.
But we can stop and restart the server.
So let's go yarn develop.
And as this gets running,
what we should see
is an un-styled button,
making our header all ugly.
There it is.
So now, if I click.
- Oo.
- That's pretty slick, that's pretty cool.
Um, but, nothing happens,
because we didn't set
up the onClose dialogue.
So here, I need.
- What do you mean?
- I just didn't add the prop.
So on here, I got the onCloseDialogue
and I'm just going to
setShowDialogue to false
when someone clicks that button.
And so now.
If I click, it goes away.
- Yeah, hit Escape.
Oo.
- Nicely done.
(chuckles)
Okay, and then, if I,
oh yeah, we've got keyboard nav.
- That actually comes from Ryan Florence's
React Reach Dialogue.
So I didn't have to do
any accessibility stuff,
it just comes with it built
in, which I really like.
- Yeah, I think the only
feedback that you're gonna get
is there's no active state on these tabs.
So yeah.
This is super cool,
man, this is great work.
And to sign up, so can I just sign up?
Like I can just pick a username
and a password and roll?
- Yeah.
- Alright, let's do it, I'm gonna.
- So it, by default, it asks
you to confirm your email.
Oh that, just like your first name.
- Yeah, that's reading comprehension.
Let's see.
What password can I make up?
- I don't know, doesn't matter.
(chuckles)
Just remember it.
- Oh no, here's what I've learned:
whenever I do something
easy, somebody in this chat,
is gonna start messing
with me immediately,
so I have to make sure that I'm like
actually secure in here.
I did one a while back, with Hasura,
and we didn't immediately set
up security on the database,
because we were like, "Oh, let's look
"at how some of this stuff works."
And then somebody just kept
changing all of our field values
to "secure your database."
Which (laughs).
- Hey, that's, I mean,
that's a friendly hacker right there.
- Yup, yup I--
- So by default, Netlify
sends you a confirmation email
but you don't have to
insist on a confirmation,
you can actually opt out of it.
I like that, because some people
don't want to confirm, right?
They'll just enter in a fake email.
So inside of the Identity tab,
if you go over to the Netlify
page on the top right.
You can go down to
Settings and usage I guess.
- Okay.
- And if you scroll down, there's a way
to opt out of the confirmation.
Scroll down, scroll down, scroll down,
down, down, down, down, down.
So there's open invitation, right?
Yeah, oh, um.
No, if you scroll up I think.
Oh, confirm, oh hang on.
Sorry, I'm like looking
at it through your screen,
and I don't know where it is.
- Do I want to autoconfirm yes?
- Right, so, oh.
So it just says no?
- Is that what I'm doing?
Well right now it's not auto.
- So autoconfirm turns is off.
Yeah, yeah, yeah.
So "Allow users to sign up
"without verifying their email address."
So right now it's emailed you.
And so it doesn't,
it has a flag on user object,
saying whether the user's confirmed or not
so that you can choose
to allow access or not,
based on whether the user's confirmed.
Or show like a reminder like,
"Hey you haven't
confirmed your email yet."
- And does this show up in the,
like I wanna just dump some context here.
So let's go into the page.
And I'm logged in now,
so if I wanna access this user object,
am I just calling useNetlifyIdentity or?
- useNetlifyIdentity, yeah.
- Okay, so I am going to
import useNetlifyIdentity
from Netlify here.
And then, here, I want to just dump it out
and see what we've got.
So we'll do one of these:
identity is useNetlifyIdentity,
and I need to find that URL again,
which was in here somewhere.
What I should do, is make this
into an environment variable,
so that I can use it in multiple places.
Then,
in here, I'm just going to do a dump.
So we'll just do a pre-tag.
Then we'll do JSON.stringify.
Set the identity in there, and then,
because we want it to look okay,
we're going to set the spacing.
- Yeah, the null 2.
Always the null 2.
- Do you know what the null is for?
I looked it up once, and
I've never remembered it.
And I don't think I've
ever set anything other.
- It's like your delimiter and all that.
- Okay.
Oh cool, alright.
So we have, whether or
not we're confirmed,
which is awesome.
And then, whether or not we're logged in,
which apparently I'm not logged in.
And that's because I, like am I,
do I need to run a check
to make sure that I'm
logged in?
Cause I did log in, but it looks
like it doesn't believe me.
- Are you logged in?
I'm sorry.
So you've reloaded
- I thought I was.
Right, but--
- But you haven't logged in yet.
Oh.
What is this?
Let's see.
So it's confirmed user.
Is logged in.
- So it says I'm logged in.
But it's not.
- Let me have a look
at the code.
So you should have an
object called Identity.user.
And you don't right now.
- Yeah, it's almost like it's
pulling a separate instance?
But, actually let me double check.
Did I?
I didn't put this outside of the layout,
no, it's inside the layout.
But I called useNetlifyIdentity
outside of the layout.
So that's probably what happened, right?
Cause it's outside of the provider?
- Um.
Sure.
But it's lazy, it's lazy in initialize,
so I don't feel like it matters.
- No, I think it has something to do
with hook's call order.
- Okay.
- Um, let's experiment here,
because I'm pretty sure,
pretty sure this is what's going on.
So, when we do...
Let's see, we're gonna grab this.
And drop that in.
And then I'm going to,
Indentity is
here.
And then we can just, actually no,
we need this.
Okay.
And then, we're going
to return that pre-tag.
- Faraz from the chat says we
should just try refreshing.
- I did.
So here's my theory,
my theory is, like providers in hooks,
need to be called from the same level.
And the layout is being called below,
where we were initially calling that hook,
so it was effectively
getting a different instance
of Identity.
And so, by putting it in here,
and then we'll import Identity,
from components/identity.
Then what I'll be able to do is,
we'll initialize it within the hook.
And so it will actually
be showing the data.
I hope.
Okay, am I logged in?
No, okay, so now I'm not logged in.
Okay, so let me log in again.
Oh, I hope I remember this.
- Email not confirmed.
Ah, so this was before we set the.
You can just sign up a new email.
(laughs)
Cause now it's gonna autoconfirm.
Or unless you--
- Actually I didn't, I
didn't change that setting.
Let me just go, um.
It's email.google.com.
Just gimme a second off screen
while I confirm my email address.
I am confirming.
Okay, I am confirmed and now
I am going to log in again.
Maybe I need refresh the page.
- So, yeah.
And again, this is something
that I recently coded,
so there may be edge cases
which I never thought about.
- Email not confirmed, why
don't you think I'm confirmed?
- It, so what I think it's doing,
so the confirmation step,
basically it requires you
to deploy this thing with
the Netlify Identity,
so that it captures the,
cause we email you a
link, you click the link,
and it has some token
to it for confirming;
and then we parse that token
and we parse the confirmation.
So that logic is not done,
because you haven't deployed this yet.
- Okay.
So now I am logged in.
And if I log in.
What, why, what?
Okay, so now it's not finding my info.
Um, so.
Do I--
- So the second JSON.
So the second JSON should
not require log in.
- Okay, I don't think
I actually saved this.
Allow users to sign up
without verifying their email addresses.
Okay.
So then, I'm gonna refresh the page.
Get a new one.
Let's sign up again.
This time we'll be test three.
God, I don't know why I can't remember
to not type an email
into that first field.
- I mean, that's good user feedback.
Like, I should probably pop
up something that says, yeah.
- So now, I have this.
And I'm just gonna navigate
here and then back.
It shows that I'm still not logged in.
- Uh-oh.
- And it's dumping that log in.
So, will it let me?
- So I wonder if this is
because of the Gatsby SSR thing?
Like, where's layout coming in?
- It's being wrapped around each page.
- Hmm.
Okay.
- Okay so, oh, oh, oh!
No, it worked this time,
it stuck this time.
So now we've got user object.
- Maybe it just took a
while to update the page.
I've never had this delay before.
But yeah, you have a user object.
It's got all the metadata that you need,
including whether it's confirmed or not.
Yeah, so we autoconfirmed you.
So that's what happened, you
see all the way down there?
- Confirmed_at, yeah.
isConfirmed true.
- You can use
the user metadata, like the full name,
and then you can add extra
metadata when you sign up.
So if you have a bigger forum,
if you want like, you
know, where they're from,
some other details about them,
you can add more metadata onto there.
But yeah, that's your
basic Identity setup,
and you can--
- Yeah, and so if I wanted to, in here,
like instead of this, we could,
well actually, let's in addition to this.
- Like, Hello first name.
- Yeah.
We can do,
identity.user.user_metadata.
- .user.user_metadata.name.
- Is it full_name?
- Just name.
Is it full_name?
I think it's just, oh it's full_name.
Huh.
- Full_name.
And then, save that.
And now we should see, there's me.
Alright.
So, that's super cool.
Um, and let's see how we're doing on time.
We have about 40-ish minutes
to do a
really whatever we want.
- Functions?
- Yeah, let's do some Functions.
- I'm gonna ask you to do one more thing,
because I'm pretty proud of this.
Before we get to that.
So head over to Identity, the
top right, on the app page.
- Okay.
- So now we're gonna add extra providers.
Right now we only have email.
- Okay.
- So if you scroll up, I think.
All the way up, all the
way, External providers.
Um, so we have some default providers
and you can configure your
own with service functions.
But let's just do like GitHub or Google,
or, yeah, whatever you want to have.
- GitHub's any easy one.
We'll use default for now.
- Right, but you can setup your own app.
And you can add Google
if you want to as well.
Or whatever, it doesn't matter.
- Yeah, let's roll here.
And log in.
- Alright, so you can log out.
- Then I'm gonna log out.
- Uh.
- Oh yeah.
That's, that's--
- This is a check
that you have to run on your code,
which is identity.user,
if you're logged out, don't display it.
(laughs)
Uh, you probably want to
put it at the P level.
- Hmm?
Oh, I was just gonna leave it.
I was just gonna bail entirely.
- Alright.
- So that way it should
just come back empty.
Nothing was returned?
Oh.
- You gotta give it a null.
- Oh, boo.
Yeah.
Alright.
(chuckles)
- React is too strict sometimes.
Like, why not do undefined, right?
If you're gonna do the null.
- Actually, I thought that one was,
I thought that one did work,
but that, okay that makes sense.
So we're returning null now,
because we're not logged in.
So if I go to log in.
Um, testing providers on localhost,
because it redirects your production site.
- Oh, you have to deploy this.
Okay, so you have to deploy,
but you see that continue
with GitHub section?
- Yeah.
- Oh, you wanna deploy it?
- Well, yeah let's, why not?
- Just push, yeah git push.
- Let's git command -am,
or, where am I at?
I think there's stuff I need to add.
git add, do I need ignore this .netlify/?
- You don't have to ignore it.
But I do, but you don't have to ignore it,
it doesn't matter.
People who don't have access,
- What don't I, actually,
this is a good question,
- it basically contains a link
- what's in this?
- So it tells Netlify CLI what
site is linked to this repo.
It's just one siteID.
- Okay.
- So if people don't have
access to your site anyway,
they can't access it.
So if you push it, it
doesn't really matter.
- Okay, and then is this like
hooked up in the toml, or?
- Um, no, the CLI reads it.
- Oh, oh, I understand!
Okay, cool.
I'm just, in the interest in
of getting this done quickly,
I'm just going to add everything,
and then we will commit and
say add identity support.
And then we'll push.
And now, if we go back
to the Netlify dashboard,
I can go look at the deploys,
and it should be rebuilding already.
Which is awesome.
And then, once this is done,
we should be able to go play with this a,
we should be able to play with this.
And it looks like we've got
a couple questions coming in
in the chat.
That first question was
about doing something similar
for stuff other than the user.
Uh, Faraz, if you can
rephrase that question,
I'm not quite sure I understand.
The follow-up question was about
the React fragment
shortcut, which is here.
This is, yeah this is just
shorthand for React.Fragment.
And so, it just makes
life a little bit easier.
But this is a way to kind
of wrap things in an element
that doesn't render in the dom.
So if avoids the div soup.
Another question was...
Let's see.
Oh, so this is a question for you, Shawn,
is there a data store
we can use with Netlify?
- Um, so straight answer is no.
The longer answer is,
there is an add-ons marketplace
that we're launching,
and the add-ons will enable you to add on
basically any database that you want.
Right now we are, our
first partner is FaunaDB.
And they've been really good,
especially on the GraphQL side.
In terms of spinning up a database,
so we can definitely try
that in this livestream,
if we want to.
- Uh-oh.
- Oo, you, it looks like you've
been logging out something.
Oh, something happened with
the server side rendering.
- Building failed.
- Uh-oh.
Uh, this is one of those HTML
snafus.
- What?
Import.
- So does it need to be transpiled?
Is that what's going on?
- Feels like it shouldn't,
but I guess we can.
- It looks like it is transpiled.
Cause it's not using JSX,
it's using the createElement.
- Hmm, okay.
So what actually went wrong here?
Is there an error message?
- Um, no, it's trying to parse.
- Testing providers won't work.
(tongue clicking)
Hmm.
- Scroll up, scroll up,
scroll up, scroll up.
It's trying to parse something.
Um, let's do a, yeah
let's see our docs page.
So what is this docs page, for Gatsby?
- Um, well that one is
about, like making sure
that you're not trying
to access the window.
Um, let's run a build locally
and see if we get the same error.
- We should get the exact same error.
If we don't, that's a problem.
(laughing)
Um, for what it's worth, I
never tested this on Gatsby,
I just did it Create React App.
So this is probably something
I should've looked at
before this livestream.
(chuckles)
- Well that's okay.
Do you know, does anything look at the,
does anything try to look at the window?
- Um.
- Oh, oh, oh, okay.
I know what's happening.
So let's run the transpilers.
We're gonna do gatsby compile es6, yeah.
So this is a plugin that'll just
run everything through Babbel.
I'm wondering if it's
because of the Babbel version
or the node version.
- Yeah.
- Um, I will just,
I don't think this is
a long term solution,
but this will hopefully
solve our problem for now.
So let me add that.
- I'm also gonna volunteer that, yeah,
I do have one thing that
looks at the window,
I should probably take that out.
It's the provider's code.
- The provider code looks at the window?
- Yeah, ironically, to check
if it's local host or not.
- Okay, um, is it guarded?
Do you know?
- No, no, no, but I should guard it.
- Okay, um.
- If you wanna give me a sec,
I'll just update the code and fix it.
(laughs)
- Hot patches on the livestream.
- Yeah, why not?
This is all happening live.
Like yeah, okay so.
I mean this makes sense,
it's just that I didn't
really test it on Gatsby,
I should have.
So do I check window === undefined?
Something like that?
- Ah-ha, yeah.
So this would just need to check,
like basically if window exists,
and if not, just automatically
return false or true,
or whatever you want it
to be as the default.
- Okay.
So window
=== undefined.
That's awesome.
- And while you're doing
that I'm gonna set up--
- So I'm typing JS and the VS code is
helping me with the thing.
So I can refer to window,
but I just can't refer any
properties of window, right?
- Yeah, so basically what you're doing,
is during the build, window doesn't exist,
so if you try to access
any properties on it,
during a server-side rendering phase,
it will just fail with an undefined error.
So, in your code, if
you just guard and say,
for server-side rendering,
this thing that relies
window will always be false,
then you just short-circuit that check
and it never tries.
That means, then.
- So I've made the code change
and I'm about to publish it.
- Okay great.
And this was,
react-netlify--
- But I mean, hopefully the
compilation isn't needed,
because that would be
surprising if it does;
and if it does, then I
can make more changes.
But I shouldn't have to, right?
I'm basically just, like all I see
is like ES modals code
is knocking file down.
- Yeah.
- So that's been published.
So it's version 0.27.
- Let's do yarn add
react-netlify-identity-widget@latest.
And so right now, we are at,
what's our version right now?
We are currently looking at 0.26.
So this should pull in 27.
27.
- It's the little things.
Yay!
Alright, let's yarn build
and see what happens.
- Alright, let's build it again.
I have now, this code is not running,
so let's just try it without.
- But your hypothesis was,
what was your hypothesis?
Or were you just like double checking a--
- So my worry is that it's
trying to import modules
and it's like expecting CJS.
But I'm not 100% sure.
So this looks like the same problem,
so let's turn this on.
And let's see what
happens if I run a build.
- Oh, so you need CJS build.
I think I have that.
- Well, I don't feel
like we should need it,
but I also, I feel like this is a problem
that we've hit a couple
times and it's one that's
kinda hitting the whole
landscape right now,
because everybody is, that was it.
Oh no, okay, so we're getting closer.
Window is not defined.
- I thought I, see I checked against that.
Is this not the check?
- Eh that looks.
Hmm.
Let's um.
I thought that was the check.
- How should I?
Yeah so?
- Gatsby html build.
(laughs)
- You have to get your own,
you have to check your own.
- Oh, typeof.
- Oh typeof!
Oh God.
Why is it?
Uh, okay, I know why it's typeof,
but it's annoying that
I have to remember it.
(laughing)
It's so annoying!
- And I feel like it's one of those things
that's like, you would have to look up
if we had a utility.
So writing a utility is not any easier
than just like having to look this up.
- And just to double check,
if I use the short circuit and,
I'm not sure if that,
to me that makes sense
that that's good enough,
but usually you have an
if statement around it,
I just use the short circuit and.
What do you think?
- Yeah, that, so I like that.
That seems like something
that would be good.
It is certainly not, apparently not doing
what we need it to do.
So um.
- So you know what, I'm gonna
do it the long way around.
Net is local host,
equals false, and then...
Sorry, I'm doing all of this off screen,
which is fantastic live streaming.
I'm basically taking out
the short circuit and,
and making sure that I put anything
that references the window
inside of the guard.
Which makes sense, right?
Alright, so git@git-admit-fix-window
(typing drowns out Shawn).
And I'm publishing again.
(laughs)
- And so we're gonna get the 0.28.
Let me know when that's ready.
- I feel like the error messages
in Gatsby should be better.
Like, that was a very opaque--
- It's high on our list.
Like, we know.
We just published an update to the CLI
to use Ink.
Which Ink is a React
library for writing CLIs,
and kind of controlling CLI output.
And it unlocks a bunch of work
that we've done research for.
- Yep, it's published.
- Okay, so that's published,
so let me install.
And Shannon Soper, has done
a bunch of research on this.
She worked together with Kyle,
and they just kind of reviewed
all of the CLI experiences out there
to figure out what are
the really good ones
and like how can we borrow to make sure.
Uh, let's see, I'm still getting 27.
Um.
Wait, did you just go mute?
- Just refresh I guess.
I mean, retry again, cause
it's definitely published.
It says 28.
- Okay.
Um, yeah, somebody just
asked about my terminal.
This is iTerm, or iTerm2 I
guess is the official one.
And I customized it using an article
that I definitely don't
have a link to anymore.
(laughs)
Okay, so I'm still getting 27.
- Why?
- I don't know.
- npm.im/react-netlify.
(typing)
Oh, npm/react-netlify.
- Netlify.
- Like I got the confirmation
email and everything.
It's 28 on the npm site.
- Yeah, what's going on?
- Maybe it's not @latest?
Yeah, cause I typically
never, yeah okay sure.
I typically never do the @latest,
I just put the name of it
and it knows what to do.
- Yeah, I well--
- As far as I know, it's not @latest.
- Okay, so now we've got 28,
maybe the latest tag was
just a little slow for us.
So now we can build again
and hopefully everything
that we get works for us.
So, we're gonna get
through that html build.
Come on.
(chuckles)
- Okay, well that was a
little bit of a detour.
We don't have to--
- It's alright.
- Yeah, yeah it's awesome.
Alright, so let's push.
- Okay, we did it!
- Yay!
- Hey we did it!
Uh, git push, or wait, we
need to commit everything.
So what're we at?
Did that, so we're going to git commit,
upgrade dependencies.
Alright, so we are pushing,
and we can go back to our deploys.
We've got our new deploy and this one--
- It's gonna deploy that.
- This one's totally gonna work.
- So while we're waiting, we
can start on the Functions.
- Yeah, let's do it!
What do you need me to do to start?
Do I need to go to Functions?
Or do it just start?
- Nothing.
Nothing.
- Nothing?
- Head to your terminal.
- Okay.
- Okay, oh sorry, well okay.
I have my, I use my
terminal inside of VS Code,
so but whatever.
- Yeah I mean, let's do it.
Terminal.
- Yeah, isn't that much better?
That's so much better.
(laughs)
So right now, you have a
secret functions folder
and we define that for
you in netlify.toml.
So if you head over to netlify.toml,
you can see that, over there,
we call function sequels functions.
It's stupid, but it's
in the docs, whatever.
But basically, it says,
your function's stored
inside a folder called functions.
You don't have that right now,
but we'll create that for
you when we get there.
- You'll create it for me?
- Yeah, yeah.
So Netlify Functions create.
The command to run,
netlify functions:create.
- Create.
- Mm hmm, and just hit enter.
And this gives you a
whole bunch of scaffolds,
you may need to have a smaller font size
to do...
Yeah well okay,
- Okay, so I have.
- you're suppose to be able to type
for somethings.
So just do like a hello-world.
Um, it's not working.
- Okay, so I think this is,
I'm gonna say this is probably not
the Netlify CLI, it's the fact that I'm on
a tiny window with my font blown way up
for the livestream.
So, yeah.
- So you can do hello-world,
and then we'll step
through the other stuff.
- Okay.
I'll just name it hello-world.
- You can name it whatever
you want, we give you a default name.
Yep, so it's created a functions folder,
if you look on the left.
And it just has your
default standard syntax
for a serverless function.
For people who are new to this,
basically it fits a certain signature,
you have to export a
function called handler,
so it exports to handler.
We're doing node style,
cause we're not transpiled.
We try to use it as much as a node here.
And then it's async, event,
context, and callback.
But then we don't use callback,
because we're returning a promise.
Um, so there's a callback signature,
and then there's a promise signature,
so we're using the promise signature,
so we don't need the callback.
And so events has the--
- So there's something
important to call out there,
because you just said
we're returning a promise,
but there's no promise here.
So the way that we're making
this return a promise,
is by using this async keyword.
And so that was a really
big tripping point for me,
when I was first starting
with async await:
was understanding what
happens under the hood,
when you use async await.
And understanding that
any function marked async
is going to return a promise.
Learning that was one of of
those things that I was like,
"Oh, that's why nothing works anymore."
(laughs)
So, okay.
We have,
an async event,
and that event is just gonna get,
like where does this come from?
Is this, just what comes in off of a--
- So that's uh, yeah, that
just gets attached to you
by the serverless backend.
And it's got a whole bunch
of other stuff as well,
if you wanna look at the full list.
Basically, it's the same thing as AWS,
the AWS callback syntax,
with some extra fields
for Identity, that we'll
talk about in the future.
So if you run this, with Netlify Dev.
If you just run, okay okay.
So if you pull up your,
do you still have the
Gatsby server running?
- Let's see, no.
- Okay, cool.
Do I wanna talk about Netlify Dev?
Sure.
So if you go to the, let me
paste this in the channel
and then we can talk about it.
- Okay.
- So, where's the channel?
So I put that in the channel
as well as my recent blog post.
Yeah, just click the most recent one.
- Here.
- Yeah.
Just the most recent one is fine.
Okay, so if you scroll down,
(laughs) yeah sure, so if you scroll down,
so Netlify Dev is for local dev emulation
of everything that you can do in Netlify.
This is a beta, so we're
not fully there yet,
but this is just a, yeah, this exact image
is what I want to show people.
And you can obviously see the demo
in the video up above.
But basically, so you have your projects,
so for us it's Gatsby,
Gatsby hosts on localhost:8000
by default, right?
So we need to tell Netlify Dev
to list it on localhost:8000
and then we add in a while
bunch of other functionality,
like add-ons, functions, and redirects,
to give you basically
what's the entire Netlify
production experience.
And then we'll give you a new port,
which is localhost, for example, :8888.
And then you can view
that port on the browser,
in your local laptop.
And that is suppose to represent
your entire production like
environment on your laptop.
- So like this is our Gatsby site.
And then that function
that we just wrote is here.
And then Netlify Dev is taking all of that
and turning it into the
full Netlify experience,
which is then available
to us at localhost:8888.
- Yup, that's it.
- That's cool.
That's very cool
- Pretty simple, right?
- Yeah, so how do I do it?
Like do I need to do anything?
- So no, because for Gatsby,
obviously one of our hugest partners,
we have detectors.
So usually there's some
configuration to do,
for Gatsby, we've already done that.
So all you do is run Netlify
Dev in your terminal.
- For real?
- Yeah, that's it.
So it's listing to :8000.
- Okay, so what happened here?
- But it's redirecting
on the Lambda server.
Right?
With port 34567.
So we need to work on that output,
I don't think that looks very nice.
So now the final proxy
is on localhost:8888.
- Okay.
- So if you click on that.
It's the same exact thing.
But now you have extra
functions and stuff, right.
That's the whole idea.
So what we're gonna do,
is we're gonna go to
localhost:8888/.netlify/functions/hello-world.
And that's the endpoint
that we just set up.
- And is there a trailing
slash or anything?
- No.
No, no, no.
No.
- Okay.
- And then if you do the, yeah exactly,
you're way ahead of me.
- Awesome.
- Right, so that's the
serverless function running
along side of Gatsby in
your local dev environment,
you didn't have to deploy it.
So previously...
I mean honestly,
- That's so cool.
- as someone who works on it day-to-day,
it's actually boring.
So I would like to get some
thoughts on like anything.
- No, I mean, that's a good thing.
Like boring is probably
one of the best outcomes
for technology: if something is exciting,
that also probably means
that it's pretty unstable.
Right?
Like you should be aiming
for boring and I love that.
When it's just like, oh
it works exactly the way
that you would expect it to work.
(laughs)
So this is really powerful,
because like the debugging process,
I mean serverless is pretty good at this.
You can run your serverless site locally,
but there's a little more
setup to it than this.
So being able to just
run a couple CLI commands
and it knows that it's a Gatsby site
and it just kinda does
the stuff is really cool.
How much time do we have left?
We've got about 25 minutes,
so let's build, I would
love to get this function
to like do a thing.
Like could we use that FaunaDB
and maybe store something?
- Uh, sure.
Okay, so what we're gonna do with that,
is netlify functions:create again.
- Okay, netlify functions:create.
- By the way, I have this alias to NFC,
because it's a lot to type.
You can also type NTL, for the CLI,
but you know, just cause
there's a lot of typing, I know.
- Yeah, I'm gonna make this bigger,
so that we can actually
see the output this time.
Okay, so type to search.
- So if you wanna set up FaunaDB,
you can set up CRUD Backend
or you can set up a GraphQL Backend.
And I know which one you want.
- Yeah, let's do the GraphQL one.
(laughing)
Got it and we'll call
this one, I don't know,
let's call it high-fives.
We'll do a high fives tracker.
- Alright.
This is way more than I originally
thought we were gonna do.
(laughing)
So what you see here, is we're
not just templating the code,
we're also installing the add-on
and injecting environment variable
into your Netlify Dev environment.
And so I'm just gonna ask you
to go ahead and say yes to this one,
cause your a first time user;
but in the future, you may
want to modify the Schema
right before you push it up to life.
So I think this is it.
So now if you run Netlify Dev.
- Like do I need to do
something with this?
- Nope.
We should probably clarify that,
this is just for information.
So what happens with this,
let me just show you,
so under functions, if
you go to your VS Code.
So we now have a high-fives folder.
And we have a Schema: schema.graphql.
And this is Schema definition
language for GraphQL,
if anyone's watching
that's like not familiar
with GraphQL, this is gonna
sound super alien right now.
(laughs)
So pause me if I need to
go like explain stuff.
This is Schema definition language,
we push it and we use
the sync-schema script:
sync-schema.js.
We use the sync-schema script
to push it to Fauna GraphQL.
So that's essentially all it does.
And this is code that you own,
we scaffold this for you, but
you are absolutely encouraged
or welcome to modify
this to suit your needs.
We just wanna show you,
like I feel like this is better than Docs,
because it's code that is literally pasted
right into your thing
and then you go fix it
to whatever you need.
And so what we just logged
out, is the default response,
from that endpoint after
we post that Schema
to the endpoint.
- Okay.
- Make sense?
- Yes, I think.
And all of my, these are all already set?
I don't have to do anything?
- Yep.
- Where do those get set?
Do they get put into a, like
are they in my environment?
- No, so they're not in your,
you're not gonna see
any of it in your code,
but when you run Netlify Dev,
we go up to your Netlify
instance that's linked,
and we pull it down and we insert it
in your process.env.
- I understand.
- So that you can just run with it.
- Okay, cool.
So if we want to
to track a high five,
what we're gonna do, is I'm
just gonna start by saying,
type HighFive and we can say
that it's going to have...
Well really we just need
like a count, right?
So we can just do a count,
and that'll be an integer,
and that's required,
and then I, well, let's
just leave it at that.
We're gonna do the minimum here.
And then we'll need a query.
And so we'll say allHighFives,
and that's going to return an integer.
And then we need a mutation,
and that's going to be--
- Uh, the mutation's generated for you.
- Oh is it?
Sick!
- Yeah.
- That's even better.
Okay, so let's do that.
- So let's just...
Is that?
Okay, so I'm not actually
sure if that will work,
but we'll figure this one out.
So this is something that
I should've implemented,
but basically you need to blow,
so right now you have an
existing Schema, right?
And you need to blow
away the existing Schema
to replace this, to add
this new Schema, right?
- And I just do that
through sync-schema, right?
- Um, you would, you would think that,
but I (laughs) I haven't done that.
(laughing)
So I need you to modify
the code a little bit.
Uh import.
God damn it.
Oh, mode override.
Okay, so inside of sync-schema,
I need to give a query variable
for mode=override.
- On?
- Yeah, /import.
Yeah, graphql.fauna.com/import,
and then question mark.
Yup, question mark.
- Wait, is it here though?
The dataString?
- No, no, no, no.
No, just put it in the /import.
- Okay.
Override.
- mode=override.
- mode=override.
- Yeah, I should have this in by default
and I was thinking about doing it,
but I just hadn't done it yet.
(chuckles)
- Okay, so now we've got an override mode,
and so now if I, do I assume I run a,
I run a--
- Yeah, you run a command.
So now you need to execute this script,
inside of the Netlify Dev environment.
So what we have it netlify dev:exec.
E-X-E-C.
And then the path to your, oh, no, no,
that just executes.
- Oh sorry.
(laughs)
- You need to give it
something to execute.
So it's: function/high-fives/sync-schema.
Mm-hmm, that's it.
So one concern I have is,
I'm not sure you're Schema is valid,
so it's gonna check whether
your Schema is valid or not,
based on their interpretation
of the Schema definition language.
Do you think it is?
- Um, I think so.
I guess this would need to come back.
I guess we'll find out.
- Why's it so slow?
- I don't know.
- Hmm.
Um, maybe it just doesn't execute.
- Did I break it?
- Mm, maybe it just hasn't responded.
You know what, I think you may be right.
Do you think I should've injected it
inside of the uh.
You see the problem is
I haven't tested this,
like this is a new thing.
Okay, so let's kill this.
- Okay.
- Let's kill this.
Okay, so I think your instinct
about the endpoint was correct.
So let's go back to the sync-schema.
- Okay.
- Instead of mode=override,
we should probably stick
this into the headers?
What do you think?
Is that a header or is it body?
I think it's header, right?
- Yeah, I mean my
assumption here is that...
dataString.
So it's just sending in
like the bodies straight up.
Um.
(door creaking)
Let's,
let's dive into
the Docs, maybe?
- For what?
- Wait, what is this?
- Oh, so this is the blog post
that explains a little
bit more than the Docs
about anything that people
want to know about detectors.
- Okay, so.
We want to manage functions?
- No, hang on, what're you trying to get?
- Well I'm trying to look for information
about this particular endpoint.
- Right, well that's
maintained by the Fauna folk,
not by Netlify.
You know, so I think it's
gonna take us too long
to figure this one out.
I think we should just execute
it without the import mode,
well yeah, without the import mode.
So just like, just what
you have right now.
Let's just save that, let's execute,
this command.
- Save it, executing.
- Yep, yep.
- So just again?
- Mm hmm.
Um, and we should've.
Ah, okay.
- Success!
Oh, internal server error.
- Yeah, because we uploaded
an incompatible Schema.
I think that's what it is.
So if you give it a HighFives array.
Like, instead of, right.
Yeah, let me just, um.
Yeah, I think if you do
like HighFive, exactly.
HighFives array.
Yeah, exactly.
And I'm not sure that you are
allowed to have two queries,
like you would wanna combine them.
- Right, lemme just do this.
I'm just gonna keep the original Schema,
so that we don't lose.
- Cause I know this one works.
(laughs)
- Alright, cool.
So we'll just do that.
- Unfortunately we were testing
very beta things right now.
Yep, okay.
- That's alright.
Okay.
Maybe?
- Awesome.
- Hey, it worked!
- So run Netlify Dev.
- Netlify Dev.
- Sorry, I'm muting myself
whenever I cough or sneeze,
cause I'm really sick right now.
- Yeah, you're a trooper
for getting on this,
despite being sick.
I really appreciate that.
- I've been looking forward
to this for like two weeks,
I'm not gonna reschedule.
- Okay, so which, we're not
looking at than one anymore.
- So you wanna be on :8000.
I think you have it, maybe
you closed it somewhere?
- Here we go.
- Right, so instead of
functions/hello-world,
we have what is it?
High-five.
- High-fives.
- Mm hmm.
So you should get a full playground.
And then you can look at the Schema.
You have a whole bunch of stuff.
And as well as the
mutations created for you,
so go ahead and do your
thing with your mutation.
- Alright, so here's what I'm gonna do,
I'm gonna create a mutation.
And we're going to create a HighFive.
And the data, oh my God,
I love this so much.
(laughs)
Like GraphQL makes me so happy,
because I don't even need to know
what the generated Schema is,
I just like let it auto-complete.
And for that we are going
to give 500 high fives.
And what should come back is what?
A count?
- Sure.
- Oh it is just excellent!
Alright, so let's get a high five.
We're going to do a query
and we'll call this one get all,
no, we'll get allHighFives.
And then I want the count
and that should give us back an array.
- There's gonna be an array of high fives.
So we were kind of like
setting up the Schema wrong,
we just need instances of high fives,
or whatever, or like an eight high five.
- In like a full-fledged app,
what we would probably be doing here,
is we would be connecting these
to like post IDs or users
or something like that.
So I think this Schema is correct,
for what it would ultimately be,
it's just silly when
we're doing it right now,
where there's like one
global count of high fives.
- Yeah.
- But that's okay.
I mean, this is, like
it's cool that this works,
so now what I wanna do, is I want to
like I wanna send a
mutation from this function.
And we've got 11 minutes to do that,
so let's tuck in.
So I've got this thing here.
We've got out handler.
- Yeah.
And this is all standard
Apollo server code.
- Okay.
And we're just missing
our query, is that right?
- Oh, what do you want?
- GraphQL, fetch, and headers.
- No, you're sending it
from the front end, right?
From the Gatsby app?
- And it's just picking up
the query from somewhere else?
Like am I just passing in the query?
- Yeah, exactly.
So what this is, right,
it's basically a serverless function proxy
between you and the
ultimate GraphQL backend.
- Okay.
- Where you can do off
checks and stuff like that.
Do you know what I mean?
- Yeah.
- So from your Gatsby app,
you were doing, you made need Apollo,
or you just wanna use a fetch?
- Let's just use a fetch for now.
- Nice, that's the way of GraphQL.
- Yeah, we'll see how well this goes.
I'm gonna create a new component,
because otherwise I'm going
to definitely get myself
tied in a knot here.
And we'll call this high-fives.
And in it, we're gonna
import React from 'react'
and then we're gonna create
a component called HighFives.
And that is going to be,
exported.
Okay.
And then, in our index file,
I'm going to import HighFives
from '..components/high-fives'
and we will just drop this
here.
Okay, so, in doing that,
what should've happened, is in our app,
that is still running at :8888,
we've got out high-fives TODO.
So now, we need to actually
make it do a thing.
And the thing that we want it to do,
is send a mutation.
- Fetch data or send mutation.
- Well we actually we wanna do two things.
- Let's do the send mutation first.
- One, is read all the high fives.
And two, add new high fives.
This would probably be two components,
in the real world, but we're
gonna cram it all in here.
So should we start
with a read or a write?
- would it help
if I jumped in with a Live Share?
With the VS Code live thing?
And then I can help you
out with one of these.
- Yeah, let's see if I can turn it on.
Maybe.
No?
Do I have Live Share on this browser?
Let's see.
- Oh no.
- I may have, so I'm using,
I use a different thing for.
- Forget it, it's probably too much.
Yeah, for us, let's just
do the count and a button.
So yeah, it'll probably take more time if,
you can just do it.
- Okay.
And so the query that we want,
is the query that we wrote,
which is out here.
To get allHighFives.
So I know that I want this query.
And...
Alright, Shawn just went AWOL,
so we're just gonna (laughs),
we're gonna just keep
coding from the hip here.
Alright, oh he's back.
Okay, alright.
(laughing)
- I just went to get
some water, I'm sorry.
- No, no worries at all.
- I was hoping no one would notice.
- Okay, so I've got my query,
and then I have a mutation,
and the mutation is gonna
be a little different,
because we're gonna want variables.
So I'm just, and like I'm
purposefully leaving out
template tags and all that stuff.
So here, I'm gonna want a count,
and that's gonna be an integer.
And we're gonna use that count here.
So, here's what I've got right now.
I've got a query and a mutation.
How should I send these in?
- What do you mean?
With the fetch?
- So you're just doing
like a straight-up fetch
to the function?
- Yeah, so on load.
Yeah, exactly, straight-up
fetch to the function.
So on load, we use a React effect to...
Actually, we can have to buttons, right?
Let's just have two
buttons, we don't need--
- Yeah, let's have two buttons.
We're not doing useEffect,
we're just gonna do it.
- useState.
- So we've got,
it's gonna be count and setCount,
is--
- And default that to like
a null string or something.
- We'll set it to zero, right?
Cause that's gonna be
our high five counts.
That way it defaults to zero.
And then we want to,
getHighFives.
And that's gonna be a function,
that's going to send a query.
And then it will setCount to newCount.
So we're gonna use fetch.
And now I gotta look at the docs,
because I don't remember how fetch works.
- Oh um, just I can walk you through it.
- Yeah, perfect.
Good.
Am I just typing in--
- So open codes, ./netlify.
Yeah, /.netlify/functions/high-fives.
And then .then.
You may want to make this
async await, or something.
- Yeah, you're definitely right there.
So we're gonna go async,
await.
- And don't forget to JSON it.
- Like so?
- Yep.
- Okay, so that should give us back
our.
- Uh, newCount.
- Let's see, newCount.
So this is gonna be the result.
And that'll be what we await.
- Oh, you typoed async.
- Did I?
Uh.
- Yeah.
- That woulda been, that
woulda been fun to debug.
Alright, and so newCount
is going to be, what?
Result.data.
allHighFives
and then we'll just do like find whatever.
And then we'll get the count.
So we're basically diving into the result,
getting the first thing, and
then returning the count.
And so that should work.
And then, down here, we're going to say.
The count.
- Oh you love those fragments.
- I do love fragments.
I'm actually not gonna
use is this time though.
Let's go with the UL, and we're going to
set the Count is count.
And then we want
a button, well,
we'll just set it in here.
The button onClick, we want to
getHighFives.
And that button is going to Update Count.
- Yeah, I really like the user experience.
- Eh, it's gonna be great.
So, did I break it?
Okay, so that's okay.
Something didn't work
though, cause it's not--
- Why's it not showing?
- I did something wrong.
- useState is not defined.
- Ah, okay.
(laughs)
Okay.
- I'm telling you man,
always React.useState.
- Okay, so, this is sort of working,
but we're not actually sending...
Unexpected G in token, eh?
- Oh, is it not giving a JSON?
- Well we're also not sending it anything.
- Huh?
- We're also still not sending anything.
(laughing)
So we've basically set up a fetch,
but we're sending it empty.
(laughing)
So I think we need to
add some options, right?
- Yeah.
This is, okay so.
This is where I also
don't know how to use it,
because I use Apollo too much.
- Yeah, so I've done this before.
- Is it just a body?
- It's the body and I think
it needs to be called query.
So body is query.
And we'll use HIGH_FIVES_QUERY.
And then,
let's,
console.log that.
And then we'll return this.
Cause I think that's right, but--
- See, I always use the network tab,
in case JSONing isn't going right.
Uh you don't need it now,
cause you already console logged it.
- Yeah, we'll still need that console.
So let's jump in here,
hit that update count.
Something exploded.
Failed to execute, request
with GET/HEAD cannot have body.
- Is it, it's a post.
It's a post.
- Oh yeah.
Right.
Okay so, is it method?
- Method, method: 'post'.
Yep.
- Okay.
So let's run that again.
Update.
Okay, we got closer.
- Come on!
- But, it didn't like something,
because we also weren't...
It comes back as a ReadableStream.
- I think it's res.body.ReadableStream.
Sorry, res.body.json.
- Well it just gave us a string of 500.
We're doing something wrong.
- Oh, let's look your
console, your terminal.
Where were you hiding your Netlify Dev?
Huh?
- We also don't have our...
Unexpected token O at position one.
Oh, let's see, where is
this actually happening?
High-fives 43.
- Inside of the serverless.
- High-five 43.
Something, something's going wrong.
- No, it's inside of
the serverless function.
- Right.
Oh, inside of the serverless function.
- Mm hmm.
- Which is,
over here.
- It's in the functions.
Oh, yep, and then there's
a file called high-fives.
So we've named it the same thing.
So this must be expecting
some other response,
like the Apollo server response.
- Did you do this?
- Yes.
(laughing)
It's a promisify.
Because that's what I always do,
but I should probably use util.promisify,
but I like yay and nay.
But do you know what I mean?
Apollo server expects a certain format.
- Right, and so we are
sending it the wrong thing.
And that means that the
thing it's expecting...
Well we're missing headers,
I know that for sure.
Or is it suppose to add these for us?
- Yeah, that's the secret
that's for the key,
so it's not exposed to the outside world.
- Okay.
- I'm also Googling.
(chuckles)
- Okay, so do we have
just like a plain fetch,
or do I need to install a bunch of stuff?
- I mean, it's Apollo, like
they're gonna want you to...
I don't know, there's an
old blog post from /go.
- Yeah, so I did this on another repo,
and I'm trying to
remember which one it is.
I guess I'll just poke at 'em for a second
and see if...
Uh, repositories.
And I get this.
- So it looks like...
No, I don't see any...
You know what we could do?
We could monitor the,
you know the playground?
If you look at the network
tab on the playground,
and then you send the query,
it should give you the structural defects.
- So I actually, I just remembered,
that I 100% did this.
And we can uh.
- To an Apollo backend?
- Yeah, to an Apollo backend.
Well actually to a serverless function.
If I can find handleSubmit,
which gets handed in,
from feedback-widget,
which uses, now this uses Axios,
but we can still look at how it works.
So it is the payload, which
the payload looks like this.
Contains a query and then variables.
And so if we pass it that,
if that's right, that's
what we did anyways.
Cause we did,
a query.
Hmm.
Okay, I'm doing something wrong.
So let's take a look at the playground.
- Yeah, look at the network tab.
And then send a query.
- Yeah, I don't know why I refreshed.
(laughs)
- And then click the last one.
So that should give you a good sense
of what they have.
- That's the request headers.
And here's the--
- operationName,
what is this?
null, "variables", oh maybe we need
to just supply all these fields.
Cause you supplied, yeah okay.
Huh.
You can just stick that in there.
- So I'm gonna take that straight up.
And then we're gonna run that.
- Tell me that works.
- Let's see.
- Tell me that works.
- Okay, so it still doesn't like that.
- Yeah, we don't need res.,
oh, it's still 500 Error,
what's the error code?
So res.body.json.
- So what we're sending, oh wait,
but it's taking in object.object.
- Why is it an object.object?
- No idea.
- Ah!
- Which, that seems silly,
that that wouldn't just work;
but let's try it again.
- I don't think you,
are you suppose to stringify it like that?
- I don't know, but,
it took it.
Oh my God, it totally works.
- So it worked?
- That worked.
- Okay.
- That's, really?
- So then we just need
to remove res.body.json
- You just gotta stringify?
- I don't know.
- That doesn't make any sense.
- Dude, I always use Apollo client,
you know, it's done for you,
I don't have to think about it.
- Alright, I'm getting rid of that.
- Remove the .body I think.
- Yeah, let's just do that.
And then
I'm gonna run this again.
- We still have the JSON,
right?
- I don't know actually,
- I think we still have the JSON.
- cause the world doesn't
make sense anymore.
Cannot read property
allHighFives of undefined.
I mean, it doesn't seem like
I should have to stringify,
but it 100% just passed
in like object.object,
when I didn't stringify.
So I--
- No, to JSON on it,
you have to JSON on it.
- You have to do to JSON it?
- No, the result of the fetch, to JSON.
.then.
No, no, no, no, no, no, hold on.
No, no, no, you're one level lower,
cause you're still inside the--
- Aha, yep, good catch.
- .then and then res.json.
Yeah, people are telling us,
that we don't know how to send JS objects.
(laughing)
- Probably, probably fair.
Okay, so I'm gonna send that.
- I mean, I just use Apollo client,
it's so much better.
Ay!
- Oh snap!
Okay, it only takes,
how many DevRels does it
take to build a button?
Okay so, this is, clearly
this is a little bit janky,
but we are also now six minutes overtime,
so I think um.
But what this shows, and what
I think is cool about this,
is that what we were able to do here,
is say what we needed, and I think,
I'm gonna test, one
more test before we go.
Cause I wanna see how all this works.
I'm gonna refresh,
update, and I get it back.
So we don't actually need this stuff,
we just need to send in the query.
And so effectively what we're doing here,
is we're sending like this fetch,
off to our serverless function
that's managed by Netlify.
And then, in Netlify, we are
able to execute that query,
which is already scaffolded out for us.
You know we didn't make
any changes whatsoever,
into this high-fives
function that was created:
it just runs.
And so by writing out
the Schema that we wanted
and then writing out the
queries that we wanted,
we can send off like the mutations
and all the things that we need,
to change these value.
So if I actually,
actually, what I can do, is
I am going to keep these,
and I'm gonna set the count to 999.
And then I'm gonna pass
in the mutation instead.
- Damn.
- And we're gonna see if this works.
- But you need to fetch it again.
Yeah, because it's expecting a read.
Cause you no longer have an allHighFives.
Cause you--
- Well it's gonna return this,
which comes back with a count,
which means that I actually
just need the count.
Yes?
- I think you just.
- See?
Okay.
Let's try it.
Ah.
Damn it.
Okay, so (laughs) I thought
I was getting clever,
but no, you're absolutely right.
What we would need to do here is,
let's console.log the result
and see what came out of it.
And,
go to the console,
update, it's gonna crash,
but it gives us back an error,
because the variable count is used,
what does that mean?
- Oh, it's Int!.
- Oh!
I didn't, so I wrote the wrong thing.
So we go up here.
- GraphQL!
- And we say that it's like this.
- Oh GraphQL, come on.
Come on, that's so stupid, right?
- Cut me some slack,
cut me some slack, bro.
Okay, so then we get back some data,
we get createHighFive and we get a count.
So I just need to update this
to be data.createHighFive.count.
And now, if I go in here.
Damn!
999 high fives!
So that is, I'm feeling
pretty good about that.
How do you feel about that?
- Uh it took us way too long to get there,
but yeah, I'm feeling pretty good.
(laughing)
Because the whole point is
you can define your Schema,
upload it, and then start working with it.
You know, it's really the dream.
And, you know, Netlify
takes no credit for this,
this is all Fauna's work.
And I think AppSync does the same thing.
- Yeah, I played with AppSync
in a livestream a week or
two ago, with Nader Dabit,
and we did something
really similar to this,
which was, I mean it's great.
And I love that tooling
is starting to move in this direction,
where the really kind of
finicky configuration stuff,
just gets abstracted because
it's a solved problem, right?
And so we just let the people,
who have solved those
problems, solve them for us.
And I'm really excited about this.
I think this is gonna be
a fun thing to play with.
Shawn, I think that's all
the time we got today.
Where should people find you?
I mean I know for sure,
we want them looking at you on Twitter:
like Shawn is very active on Twitter.
So that's--
- The four letter handle, always works.
- Yeah the (laughs).
But yeah, so go follow him there for sure.
Where else?
- That's about it, I'm in New York,
if people wanna hang out,
always just give me a shout.
I am active on the React
Subreddit: r/reactjs.
And yeah, check out our
blog posts at Netlify Dev.
I'm sort of the lead maintainer for now,
so if anyone has any
issues using Netlify Dev,
let me know and I'll fix it.
- Awesome.
And Netlify dev is, let's see,
we had it in here somewhere.
Netlify Dev.
Here's a direct link to Netlify Dev,
if you wanna learn more about it.
- Yep.
- Well, Shawn, thank you
so much for coming on,
this was a lot of fun.
- Yeah, thanks for having
me, that was a ride.
(laughing)
- No, it's good, we get
to learn in public, right?
And I feel like we did
a lot of that today.
(laughing)
- Yes, learn in public,
that's another thing that I really like.
Alright cool, well thanks
for taking all your time,
and thanks for everyone on the livestream:
sorry for all the
frustrations that we had.
This is the raw, unfiltered,
coding series, right?
(laughing)
- It's uh, it's always great, you know?
You just blunder your way through
and eventually you get
something that works;
and I feel that's exactly
what we did today.
So thanks, everybody.
Make sure you check out
on the Twitch stream,
there are a whole list
of events coming up.
We've got, next week,
I think I haven't even
written this down yet.
I haven't even written this,
no wait, yeah, no, no.
So next week we're gonna look at Airtable,
using it as a CMS.
The week after that, I'm
gonna be on with Andre,
and I can't remember
what we're talking about.
Then Henry Zhu and I, from Babbel,
are gonna be working on
a Gatsby podcast theme.
We've got all sorts of
exciting stuff coming up,
so make sure you head over
to twitch.tv/jlengstorf,
hit the follow button,
and let's definitely be
best friends on Twitch.
Thanks, everyone, and we
will see you next week.
- Bye.
