|
| 1 | +# Getting Started with the Experimental App Router |
| 2 | + |
| 3 | +This tutorial will introduce you to Faust’s experimental app router example project. It contains a site demonstrating the use of utilities like [getClient](./getclient.md), [getAuthClient](./getauthclient.md), [faustRouteHandler](./faustroutehandler.md), [loginAction](./onlogin-server-action.md), and [logoutAction](./onlogout-server-action.md). You can use this project as a base for future projects and as a good reference site for app routing. It assumes you are comfortable with the command line, have a foundational knowledge of Faust and Next.js routing, and understand the basics of JavaScript, WordPress and Bash. |
| 4 | + |
| 5 | +- [Experimental App Router example project](https://github.com/wpengine/faustjs/tree/canary/examples/next/app-router) |
| 6 | + |
| 7 | +- [NPM package](https://www.npmjs.com/package/@faustwp/experimental-app-router) |
| 8 | + |
| 9 | +## How to Get the Example Working Locally |
| 10 | + |
| 11 | +### Install and Build |
| 12 | + |
| 13 | +Get started by downloading the example project by running: |
| 14 | + |
| 15 | +```shell |
| 16 | +npx create-next-app \ |
| 17 | + -e https://github.com/wpengine/faustjs/tree/main \ |
| 18 | + --example-path examples/next/app-router \ |
| 19 | + --use-npm |
| 20 | +``` |
| 21 | + |
| 22 | +### .env.local File Set Up |
| 23 | + |
| 24 | +Copy the example’s `.env.local.sample` file, ensuring you rename the file `.env.local`. |
| 25 | + |
| 26 | +You’ll see an example `NEXT_PUBLIC_WORDPRESS_URL` in this file. Set this to your WordPress site’s URL. |
| 27 | + |
| 28 | +You’ll also see a NEXT\_PUBLIC\_URL set to http://localhost:3000. You can keep that as is for now. |
| 29 | + |
| 30 | +Set your FAUST\_SECRET\_KEY. For more information on where to find this secret key, refer back to this example. |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | +### Run the Project |
| 35 | + |
| 36 | +Run the example project by entering `npm run dev` |
| 37 | +Navigate to `http://localhost:3000/.` |
| 38 | + |
| 39 | +You should now see a simple site page using your site’s name and a few published posts: |
| 40 | + |
| 41 | + |
| 42 | + |
| 43 | +## The Example Project File Structure |
| 44 | + |
| 45 | +This is the new standard file structure for App Router Next.js apps. For more information, check out the [App Router](https://nextjs.org/docs/app) docs from Next.js. |
| 46 | + |
| 47 | +```shell |
| 48 | +❯ tree -L 2 |
| 49 | +. |
| 50 | +│ν app |
| 51 | +│ └── [postSlug] |
| 52 | +│ └── page.tsx |
| 53 | +│ └── api/faust/[route] |
| 54 | +│ └── route.ts |
| 55 | +│ └── my-account |
| 56 | +│ └── page.tsx |
| 57 | +│ └── making-client-queries |
| 58 | +│ └── page.tsx |
| 59 | +│ └── login |
| 60 | +│ └── page.tsx |
| 61 | +│ ├── layout.tsx |
| 62 | +│ └── page.tsx |
| 63 | +│❯ node_modules |
| 64 | +│.env.local.sample |
| 65 | +│faust.config.js |
| 66 | +│next-end.d.ts |
| 67 | +│next.config.ts |
| 68 | +│package.json |
| 69 | +│possibleTypes.json |
| 70 | +│tsconfig.json |
| 71 | +``` |
| 72 | + |
| 73 | +## Fetching Data |
| 74 | + |
| 75 | +[getClient](./getclient.md) is a function that returns an ApolloClient, specifically for use in React Server Components (RSC). When making authenticated requests in the Next.js App Router from an RSC, the [getAuthClient](./getauthclient.md) is used instead. Both are part of the `@faustwp/experimental-app-router` package. |
| 76 | + |
| 77 | +In the example project under the folder `my-account`, you’ll find an example of getAuthClient in action: |
| 78 | + |
| 79 | +```js |
| 80 | +// in examples/next/app-router/app/my-account/page.tsx |
| 81 | +import { gql } from '@apollo/client'; |
| 82 | +import { getAuthClient } from '@faustwp/experimental-app-router'; |
| 83 | + |
| 84 | +export default async function Page() { |
| 85 | + const client = await getAuthClient(); |
| 86 | + |
| 87 | + if (!client) { |
| 88 | + return <>You must be authenticated</>; |
| 89 | + } |
| 90 | + |
| 91 | + const { data } = await client.query({ |
| 92 | + query: gql` |
| 93 | + query GetViewer { |
| 94 | + viewer { |
| 95 | + name |
| 96 | + posts { |
| 97 | + nodes { |
| 98 | + id |
| 99 | + title |
| 100 | + } |
| 101 | + } |
| 102 | + } |
| 103 | + } |
| 104 | + `, |
| 105 | + }); |
| 106 | + |
| 107 | + return ( |
| 108 | + <> |
| 109 | + <h2>Welcome {data.viewer.name}</h2> |
| 110 | + |
| 111 | + <ul> |
| 112 | + {data.viewer.posts.nodes.map((post) => ( |
| 113 | + <li key={post.id}>{post.title}</li> |
| 114 | + ))} |
| 115 | + </ul> |
| 116 | + </> |
| 117 | + ); |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +### Fetching Data on the Client |
| 122 | + |
| 123 | +Additionally, you can make client side requests using Apollo's `useQuery` hook like usual (You will need to do this in a client component using the `use client` directive): |
| 124 | + |
| 125 | +```js |
| 126 | +'use client'; |
| 127 | + |
| 128 | +import { gql, useQuery } from '@apollo/client'; |
| 129 | + |
| 130 | +export default function Page() { |
| 131 | + const { data } = useQuery(gql` |
| 132 | + query MyQuery { |
| 133 | + generalSettings { |
| 134 | + title |
| 135 | + } |
| 136 | + } |
| 137 | + `); |
| 138 | + |
| 139 | + return <>{data?.generalSettings?.title}</>; |
| 140 | +} |
| 141 | +``` |
| 142 | +
|
| 143 | +For client side queries to work, make sure you are wrapping your root `layout` with the `<FaustProvider>` component imported via: |
| 144 | +
|
| 145 | +```js |
| 146 | +import { FaustProvider } from '@faustwp/experimental-app-router/ssr'; |
| 147 | +``` |
| 148 | +
|
| 149 | +## Authentication |
| 150 | +
|
| 151 | +Authentication in the experimental-app-router is powered by two utilities, [onLogin](./onlogin-server-action.md) and [onLogout](./onlogout-server-action.md). These are built on [Next.js server actions](http://nextjs.org/docs/app/api-reference/functions/server-actions\) and perform an action to log a user in and out using cookie caching and cookie removal, respectively. |
| 152 | +
|
| 153 | +In the example project, navigate to `http://localhost:3000/login` and log into your app using your `wp-admin` credentials from the `NEXT_PUBLIC_WORDPRESS_URL` you set in your .env.local file. |
| 154 | + |
| 155 | + |
| 156 | + |
| 157 | +Upon successfully logging in, you’ll be directed to `http://localhost:3000/my-account`. This functionality comes from the helper function, [onLogin](./onlogin-server-action.md). |
| 158 | + |
| 159 | + |
| 160 | + |
| 161 | +The `/my-account` page grabs the authenticated user's name and posts and displays them. |
| 162 | + |
| 163 | +This page also has a "Logout" button, clicking it calls the [onLogout](./onlogout-server-action.md) server action, the user is logged out, and the page is refreshed with no authenticated user. |
| 164 | + |
| 165 | +Note that when viewing the `/my-account` without an authenticated user, the first conditional statement in the associated `my-account/page.tsx` will be triggered, and the message, `You must be authenticated` will show on the screen. |
| 166 | + |
| 167 | + |
0 commit comments