Now let's start with the starting page.
Here on this starting page,
we want the featured events.
So we need to load those featured events
onto this index.js page.
So into this index.js component here,
this homepage component.
The question now is how do we wanna load the data?
Now we could do it with client site data fetching.
We could use useEffect with the fetch API
or install and use the useSWR hook here
which we learned about.
We could do that, but does this make sense?
Is this the best solution here?
I would argue that here we actually wanna use,
one of the two forms of pre-rendering instead.
So static generation or server-side rendering.
Because the starting page, which we're looking at here,
this is a page which should be understood
by search engine crawlers.
It's important that they are able to understand our site
and well, direct traffic to our site.
And as a visitor on this page, it would also be nice
if we see something instantly.
It's also not likely
that this data changes multiple times per second
or minute even.
So there isn't really a reason for loading this
on the client side.
It's also not some user specific data
and it's also not data behind a login screen
or anything like that.
So here I would argue, it makes a lot of sense
to pre-render this page with some data.
That then just leaves one question,
should we use getServersideProps
for real server-side pre-rendering where the page
is pre-rendered on the server on the fly for every request
or do we want getStaticProps to pre-render the page,
during the build process and potentially also on the server
if we set revalidate to a certain value
so that we have a mostly updated page.
I would argue for this kind of page,
we don't need server-side rendering.
We don't need to pre-render it for every request,
instead using getStaticProps makes most sense here,
I would say.
So we can export this async function,
getStaticProps here in this index.js file.
Get our context, though here, we won't need it.
So we can also omit it.
And then in here,
return an object with the props for this homepage component.
Now the props should be an object
and in there I want to have my featured events
which now should be fetched from Firebase,
not from the dummy-data.js file anymore.
We're past this world.
Now we have the Firebase backend
and we wanna fetch that data from there.
Now, how do we fetch the featuredEvents from Firebase?
Actually, when it comes to querying Firebase,
you can adjust the HTTP request
which is being sent with some query parameters
to filter the data you are retrieving.
If you search for Firebase realtime database filter,
you'll find this retrieving data article,
and there you'll learn how you can adjust
to the URL to which you send the request,
with query parameters QL,
filter the data which you are retrieving.
And you can filter by a specific child keys,
look for a certain values and so on.
Now you can do that and feel free to dive into the docs
to implement it such that you do filter on Firebase side
for retrieving only selected data.
I will not do that here,
because this is not a Firebase course.
And it's really just a dummy backend.
Instead, I will add a new file here.
Let's say in a helpers folder,
a file which I'll name api-util.js.
So which has utility functions
for working with an API and in there,
I will now add a function
which gives me the featured events,
but I will actually always fetch all events first
and then filter them just here in JavaScript
which is of course not ideal because it means
that we always fetch all the data, even if we don't need it.
But as I just said, that's just not the focus here,
it would be very Firebase specific
if we write the Firebase query logic here
and that, well, basically leads nowhere.
So therefore I'll go to dummy-data.js
and copy the getFeaturedEvents function from there
and add it here in the api-util.js file.
But I'll also add a number of functions here, getAllEvents.
And in there, I will write the logic
for fetching all events data from Firebase.
So I'll turn this into an async function
so that I can use async await here.
I'll also convert getFeaturedEvents
into an async function.
And then here in getAllEvents, I will call fetch.
So the built-in fetch API,
which is available in the browser
and thanks to next JS also can be used inside
of getStaticProps and getServersideProps.
And here, we'll then send a request to this Firebase URL.
So to this rest API URL, which then triggers Firebase
to talk to our database here.
There we wanna reach out into the events node.
So this node, which I added here
and then because it's Firebase,
we need to add .json at the end here.
That's Firebase specific.
Now, since we use async here,
we can also await this
to get our response like this without then.
Under the hood, async awaits still uses then,
but we can write it
in this more convenient way here.
And we can get our data by awaiting response.json.
We also might want to implement error handling here,
but for the moment, I'll skip it.
Instead here, we then have the data.
And as you learned in the last section,
Firebase returns your data as an object.
So I'll transform my events here.
I'll add them as an empty array
and then loop through my data.
So through all the keys and data,
so through all the entries and events.
So these are my keys, e1, e2 and e3.
And I'll loop through them.
And for every key, I'll push a new event
into this events array, where the id is equal to key
and where I then wanna distribute all of the nested data
which is stored under that key into that events object.
And to not manually write all these key value pairs,
I'll use the spread operator
and just copy everything from data
for the given key.
So from this nested object here
into this object, which we push onto events.
That should ensure that events is an array full of objects,
with all these fields here and with an id field,
which is e1, e2 or e3.
And then I will return events here.
Now, overall, we still return a promise here,
because of async,
but that promise will then resolve to this events array.
And in getFeaturedEvents,
we can now get all events
by awaiting the result of calling, getAllEvents.
So this function I just worked on, I call it here,
since it returns a promise,
I await that promise
which I can because I added async here.
Then I have all events and I return all events,
filtering for the events that are featured.
Again, that means that we always load all events first,
but here for this demo, that is okay.
Now it's getFeaturedEvents,
this getFeaturedEvents, not the one from dummy-data
which I wanna use in index.js.
So here we wanna import getFeaturedEvents from,
and then I'll dive into the helpers folder into api-util.
And now here in getStaticProps,
we can get the featured events
by awaiting the result of getFeaturedEvents.
So of calling this function, which we just worked on
which I now imported.
We can use await because that is an async function.
And then it's these featuredEvents
which I'll set as a value for the featuredEvents prop.
Now we can also name this prop just events.
It doesn't have to be named featuredEvents.
And with that in getStaticProps,
we return an object with our featuredEvents
in props and the featuredEvents ultimately,
are fetched from Firebase.
So now in the component function here, which is executed
after getStaticProps, we now should accept props.
So the props which are set
by getStaticProps, and then here we no longer need
to call getFeaturedEvents.
And we don't wanna call it here,
because we don't wanna fetch them on the client,
instead, I just forward prop.events.
So my events here to EventList.
And now let's see if that works.
If we save that.
If we go back to the starting page and reload,
that's looking good.
I see my events and I can still click on them.
And if I reload and view the page source here,
we see that the event data is actually part
of that HTML file
which was sent back by the server.
So pre-rendering this page with the event data worked.
And here we are using static generation,
because we're using getStaticProps.
So this applies what we learned with Firebase
and with getStaticProps to this homepage.