Skip to content

Commit

Permalink
docs: adding rehydration doc and updates to building apps over… (#19214)
Browse files Browse the repository at this point in the history
  • Loading branch information
gillkyle authored and sidharthachatterjee committed Nov 10, 2019
1 parent 1acac83 commit ac5af97
Show file tree
Hide file tree
Showing 16 changed files with 136 additions and 42 deletions.
2 changes: 2 additions & 0 deletions docs/blog/2018-10-15-beyond-static-intro/index.md
Expand Up @@ -43,6 +43,8 @@ One of the central ideas of Gatsby is that we statically generate our HTML conte
1. Invoke [ReactDOM.hydrate method][hydrate] to pick up just where we left our static HTML
1. Transfer rendering to the [React reconciler][reconciler]

_This process is spelled out in more detail in the ["Understanding React Rehydration" guide](/docs/react-rehydration)_

It's this last phase that bridges the gap between static sites and full-fledged applications. In this phase you can make data calls, authenticate users, and perform all the app-like functionality you desire.

It's really that easy.
Expand Down
4 changes: 2 additions & 2 deletions docs/blog/2019-02-14-behind-the-scenes-q-and-a/index.md
Expand Up @@ -60,7 +60,7 @@ To watch the full recorded webinar, [register here](https://www.gatsbyjs.com/beh
**Answer:** Yes, build-times do go up with image processing as it's very CPU intensive.

**Question:** I have an app which has Frontend and Admin Panel so how do I do code splitting based on Module so the admin javascript should not include in Frontend and vice versa?
**Answer:** Gatsby splits code automatically by route so code only used on the admin panel will only be loaded there. Check out [Building Apps with Gatsby](/docs/building-apps-with-gatsby/) for details about how to build the admin section.
**Answer:** Gatsby splits code automatically by route so code only used on the admin panel will only be loaded there. Check out [Building Apps with Gatsby](/docs/adding-app-and-website-functionality/) for details about how to build the admin section.

### GraphQL / Data Layer

Expand Down Expand Up @@ -145,7 +145,7 @@ To watch the full recorded webinar, [register here](https://www.gatsbyjs.com/beh

**Question:** Are there data fetching hooks that we can use for client-side loading of authenticated content that isn't serialized at build-time?
**Answer:** Check out [Building a site with authentication](/docs/building-a-site-with-authentication/) and [Building Apps with Gatsby
](/docs/building-apps-with-gatsby/)
](/docs/adding-app-and-website-functionality/)

**Question:** How to do SSR loading for Dynamic content- for example, a blog, as it uses build time SSR technique?
**Answer:** Gatsby's data layer and source plugins can fetch data dynamically at build time to grab your data. Then whenever your data changes, you rebuild your site with the updated content. Builds are fast so you can update the site every few minutes if necessary.
Expand Down
Expand Up @@ -43,7 +43,7 @@ The code we built is [available on GitHub](https://github.com/jlengstorf/gatsby-

## Additional links and resources

- [Building Apps With Gatsby](/docs/building-apps-with-gatsby/)
- [Adding App Functionality with Gatsby](/docs/adding-app-and-website-functionality/)
- [Auth0](https://auth0.com/)
- [Simple auth example in Gatsby](https://github.com/gatsbyjs/gatsby/blob/master/examples/simple-auth/)
- [Source code for the Gatsby store](https://github.com/gatsbyjs/store.gatsbyjs.org), which uses Auth0 to authenticate users
Expand Down
78 changes: 78 additions & 0 deletions docs/docs/adding-app-and-website-functionality.md
@@ -0,0 +1,78 @@
---
title: Adding App and Website Functionality
overview: true
---

Gatsby empowers developers and creators to make many different types of websites. One may wish to add additional functionality to their site such as search, authentication, forms, comments, and plenty of others.

The distinction between apps and websites is blurry, the way Dustin Schau puts it in a [blog post](/blog/2018-10-15-beyond-static-intro/):

<Pullquote citation="Dustin Schau" narrow={true}>
I contend that the line between these two concepts is extremely blurry. There
isn’t some magic percentage threshold that, when crossed, indicates that a
static site is now an application. Nor is the inverse true, that an “app” is
somehow static because some percentage of its content never or rarely changes.
</Pullquote>

Gatsby allows you to orchestrate data fetching, transforming, and usage in pages, but it also allows you to make the call about how, when, and where, that happens. It allows you to make a site as feature-less or feature-rich as you want, you aren't restricted to just static sites.

## How hydration makes apps possible

Even though Gatsby generates static files, Gatsby apps [rehydrate](/docs/glossary#hydration) from static HTML rendered by ReactDOM APIs into an app running client-side JavaScript. The general approach as outlined in the [React Hydration guide](/docs/react-hydration) is as follows:

1. Build and render static HTML, creating content and pages with data injected at build time
2. Invoke `ReactDOM.hydrate()` method to pick up where the static HTML was left
3. Transfer rendering to the React reconciler

It's this last phase that bridges the gap between static sites and full-fledged applications. In this phase you can make calls for [dynamic data](/docs/client-data-fetching/), [authenticate users](/docs/building-a-site-with-authentication/), and perform all the app-like functionality you desire because the page is running a React application.

## Common patterns for Gatsby apps

There are different options for organizing how your pages are created and what they will be responsible for. These patterns can be combined and tweaked for specific use cases such as pulling in data at [build time](/docs/glossary#build) for great performance, or calling for data at [runtime](/docs/glossary#runtime) for a more dynamic experience.

Because all Gatsby pages are hydrated into React, **any of the following patterns are capable of app-like behavior**. This section is to help explain some higher level patterns for thinking about Gatsby.

### Static pages

Static files are output by running `gatsby build` from exported components in your `src/pages` folder or from pages created using the [`createPage` API](/docs/node-apis/#createPages), as shown in this diagram:

![Static Site diagram with pages created from Gatsby automatically and programmatically](./images/simple-static-site.png)

The diagram illustrates the 2 main methods for creating pages in your site:

1. Automatically through `src/pages`
2. Programmatically with the `createPage` API

_**Note**: plugins and themes can also implement the `createPage` API and create pages on your behalf_

When you export a React component from a file in the `src/pages` directory (in this case `src/pages/home.js` for `/home`) Gatsby will automatically create a static page. By looping through Markdown files in your filesystem you can create pages for all blog posts programmatically. The docs have more information about [creating and modifying pages](/docs/creating-and-modifying-pages/).

These created pages _could_ run JavaScript once React hydrates them, but they don't need to.

### Hybrid app pages

Your created pages can make calls to external services and APIs in order to allow more interactive and dynamic behavior. These are sometimes referred to as hybrid app pages because they share a combination of static features that Gatsby creates to help load your site quickly and performantly as well as traditional web app features.

The following diagram shows a similar site to the one in the previous example, but with a subscription form added to the home page that makes client-side `POST`'s to a database somewhere, as well as blog posts that `GET` recommendations from a database or other API endpoint.

![Hybrid Site diagram with pages hitting other services with JavaScript](./images/simple-hybrid-site.png)

Following a pattern like this means you are relying on a [backend](/docs/glossary#backend) to remain operational for features like email signups and blog recommendations, but because the static assets created aren't generated by the server on demand, the content on your site (like your blog posts or home page) will never go down or become unavailable.

### Client only routes

Using a React-based client-side router is also supported by Gatsby. This pattern is often referred to as client only routes, which are routes not reflected in your statically rendered files. Gatsby ships with `@reach/router`, so it is a great option to keep your site from having to ship additional JavaScript with another routing library.

With Gatsby, you can import a router and set up routes for navigation the same way you would in traditional React apps. The only difference is Gatsby doesn't build those routes into individual pages in the `/public` folder. As a result, in order to allow users to access that URL directly, you can use a plugin to create those pages. This is covered in the [Client Only Routes](/docs/client-only-routes-and-user-authentication/) guide.

The following diagram shows how a `<Router />` component can be mounted on a page. In this example, `src/pages/app` references `<Route />`s.

![Client Only Routes Site diagram with pages setup using a router](./images/simple-client-only-routes.png)

In this illustration, a client-rendered user page could display specific information about the logged-in user, and dynamic client-side routes at `/app/tasks/:id` could display specific information for a task of a given ID.

---

Generating performant sites with statically rendered assets is a core focus of Gatsby, but it's only one side of the coin. In this section of the docs, you will find a showcase of guides and concepts on how to level up your site to include all the app-like features on top of the static base.

<GuideList slug={props.slug} />
8 changes: 0 additions & 8 deletions docs/docs/adding-website-functionality.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/docs/building-a-site-with-authentication.md
Expand Up @@ -3,7 +3,7 @@ title: Building a Site with Authentication
---

With Gatsby, you are able to create restricted areas in your app. For that, you
must use the concept of [client-only routes](/docs/building-apps-with-gatsby/#client-only-routes).
must use the concept of [client-only routes](/docs/client-only-routes-and-user-authentication/).

Using the [@reach/router](https://reach.tech/router/) library, which comes
installed with Gatsby, you can control which component will be loaded when a
Expand Down
25 changes: 0 additions & 25 deletions docs/docs/building-apps-with-gatsby.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/docs/creating-and-modifying-pages.md
Expand Up @@ -12,7 +12,7 @@ Pages can be created in three ways:
- Plugins can also implement `createPages` and create pages for you

You can also implement the API [`onCreatePage`](/docs/node-apis/#onCreatePage)
to modify pages created in core or plugins or to create [client-only routes](/docs/building-apps-with-gatsby/).
to modify pages created in core or plugins or to create [client-only routes](/docs/client-only-routes-and-user-authentication/).

## Debugging help

Expand Down
Binary file added docs/docs/images/simple-client-only-routes.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docs/images/simple-hybrid-site.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docs/images/simple-static-site.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/docs/porting-from-create-react-app-to-gatsby.md
Expand Up @@ -220,7 +220,7 @@ There are two possibilities of routes that you can set up: static and client-onl

> **Note**: An advantage to having pages in separate files like this is a defined way of [automatically code splitting](/docs/how-code-splitting-works/), whereas Create React App requires you to use the `import()` syntax to assign what elements should be loaded dynamically.
For dynamic routes, you should implement routing with [@reach/router](https://reach.tech/router), which is already included with Gatsby. Dynamic routes can be implemented the same way you would implement a router in Create React App (or any other React application). However, because these routes won't be represented as HTML files in the final build, if you want users to be able to visit the routes directly (like entering the URL in the search bar), you'll need to generate pages in the `gatsby-node.js` file which is demonstrated in the [Building Apps with Gatsby](/docs/building-apps-with-gatsby/) guide.
For dynamic routes, you should implement routing with [@reach/router](https://reach.tech/router), which is already included with Gatsby. Dynamic routes can be implemented the same way you would implement a router in Create React App (or any other React application). However, because these routes won't be represented as HTML files in the final build, if you want users to be able to visit the routes directly (like entering the URL in the search bar), you'll need to generate pages in the `gatsby-node.js` file which is demonstrated in the [Building Apps with Gatsby](/docs/adding-app-and-website-functionality/) guide.

```jsx
import React from "react"
Expand Down
33 changes: 33 additions & 0 deletions docs/docs/react-rehydration.md
@@ -0,0 +1,33 @@
---
title: Understanding React Rehydration
---

One of the central ideas of Gatsby is that HTML content is statically generated using React DOM server-side APIs. Another key feature is that this static HTML content can then be _enhanced_ with client-side JavaScript via React hydration, which allows for [app-like features](/docs/adding-app-and-website-functionality/) in Gatsby sites.

The steps taken to deliver a built site to the browser are discussed below:

## Build and render static assets

Running `gatsby build` starts up a Node.js server that processes your site: it creates a GraphQL schema, fetches data that your pages will pull in by [extracting queries](/docs/query-extraction/) from your code and [executing them](/docs/query-execution/), and it then [renders each page's HTML](/docs/html-generation/).

_The ["Overview of the Gatsby Build Process" conceptual guide](/docs/overview-of-the-gatsby-build-process/) helps explain what's happening at each step in the build process._

All of this data is gathered during the build and written into the `/public` folder. You can [customize Gatsby's configurations](/docs/customization/) for Babel and webpack, as well as the HTML generated by your build, in order to tweak how your site gets built.

## The `ReactDOM.hydrate` method

The `hydrate()` method is called internally by Gatsby from `ReactDOM`, which according to the [React docs](https://reactjs.org/docs/react-dom.html#hydrate) is:

> Same as [render()](https://reactjs.org/docs/react-dom.html#render), but is used to hydrate a container whose HTML contents were rendered by [ReactDOMServer](https://reactjs.org/docs/react-dom-server.html).
_**Note**: if you need to, the hydrate method can be replaced with a custom function by using the [`replaceHydrationFunction` Browser API](/docs/browser-apis/#replaceHydrateFunction)._

This means that the browser can "pick up" where the server left off with the contents created by Gatsby in the `/public` folder and render the site in the browser just like any other React app would. Since the data and structure of the pages is already written out, it's not necessary for Gatsby to go to another server asking for HTML or other data.

## Transfer rendering to the React reconciler

After ReactDOM hydrates the content, the [React reconciler](https://reactjs.org/docs/reconciliation.html) can take over and [diff](https://en.m.wikipedia.org/wiki/Diff) the tree of elements. It then becomes responsible for making updates in the UI based on changing state or props.

## Additional resources

- [Rendering on the Web](https://developers.google.com/web/updates/2019/02/rendering-on-the-web) from Google
2 changes: 1 addition & 1 deletion docs/tutorial/authentication-tutorial.md
Expand Up @@ -2,7 +2,7 @@
title: Making a Site with User Authentication
---

Sometimes, you need to create a site with gated content, available only to authenticated users. Using Gatsby, you may achieve this using the concept of [client-only routes](/docs/building-apps-with-gatsby/#client-only-routes), to define which pages a user can view only after logging in.
Sometimes, you need to create a site with gated content, restricted to only authenticated users. Using Gatsby, you may achieve this using the concept of [client-only routes](/docs/client-only-routes-and-user-authentication/), to define which pages a user can view only after logging in.

## Prerequisites

Expand Down
12 changes: 12 additions & 0 deletions www/gatsby-node.js
Expand Up @@ -384,6 +384,18 @@ exports.createPages = ({ graphql, actions, reporter }) => {
isPermanent: true,
})

createRedirect({
fromPath: `/docs/building-apps-with-gatsby/`,
toPath: `/docs/adding-app-and-website-functionality/`,
isPermanent: true,
})

createRedirect({
fromPath: `/docs/adding-website-functionality/`,
toPath: `/docs/adding-app-and-website-functionality/`,
isPermanent: true,
})

createRedirect({
fromPath: `/docs/using-fragments/`,
toPath: `/docs/using-graphql-fragments/`,
Expand Down
6 changes: 4 additions & 2 deletions www/src/data/sidebars/doc-links.yaml
Expand Up @@ -348,8 +348,8 @@
- title: Debugging Async Lifecycles
link: /docs/debugging-async-lifecycles/
breadcrumbTitle: Async Lifecycles
- title: Adding Website Functionality
link: /docs/adding-website-functionality/
- title: Adding App and Website Functionality
link: /docs/adding-app-and-website-functionality/
items:
- title: Linking Between Pages
link: /docs/linking-between-pages/
Expand Down Expand Up @@ -540,6 +540,8 @@
link: /docs/building-with-components/
- title: Lifecycle APIs
link: /docs/gatsby-lifecycle-apis/
- title: React Rehydration
link: /docs/react-rehydration
- title: PRPL Pattern
link: /docs/prpl-pattern/
- title: GraphQL Concepts
Expand Down

0 comments on commit ac5af97

Please sign in to comment.