Skip to content

Commit 455ab79

Browse files
committed
docs: add docs from faust website for archiving
1 parent 7db45a1 commit 455ab79

File tree

14 files changed

+415
-1
lines changed

14 files changed

+415
-1
lines changed

packages/experimental-app-router/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@
1919
</a>
2020
</p>
2121

22+
> [!NOTICE] DEPRECATED
23+
> This package has been deprecated due to lack of Apollo support for React Server Components and Next's App Router. The Team is working on a [tooling to replace Faust](https://github.com/wpengine/hwptoolkit) and this will include App Router support. In the mean time, if you need bug fixes or security updates we'd recommend copying the source code of this package directly into your project for use.
24+
2225
This is an **experimental** collection of utilities to support Next.js' App Router feature in Faust. To get started, please visit the docs here:
2326

24-
https://faustjs.org/tutorial/getting-started-with-the-experimental-app-router
27+
## Documentation
28+
29+
- [Tutorial](./docs/getting-started.md)
30+
- Reference
31+
- [`faustRouteHandler`](./docs/faustroutehandler.md)
32+
- [`getAuthClient`](./docs/getauthclient.md)
33+
- [`getClient`](./docs/getclient.md)
34+
- [`onLogin` Server Action](./docs/onlogin-server-action.md)
35+
- [`onLogout` Server Action](./docs/onlogout-server-action.md)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# `faustRouteHandler`
2+
3+
`faustRouteHandler` is an API handler for App router projects. It's main purpose is to manage Faust.js API logic, such as authentication and internal route handling.
4+
5+
## Usage
6+
7+
Create a file `/app/api/faust/[route]/route.js` with the following contents:
8+
9+
```js
10+
import { faustRouteHandler } from '@faustwp/experimental-app-router';
11+
12+
const { GET, POST } = faustRouteHandler;
13+
14+
export { GET, POST };
15+
```
16+
17+
## Technical Reference
18+
19+
The `faustRouteHandler` is an object with the following properties:
20+
21+
`GET`
22+
23+
Handles GET requests over the `/app/api/faust/*` endpoint.
24+
25+
`POST`
26+
27+
Handle POST requests over the `/app/api/faust/*` endpoint.
28+
29+
## Additional Context
30+
31+
- [Next.js Route handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# `getAuthClient`
2+
3+
`getAuthClient` is a function that returns the `ApolloClient` making it available for use. It is used for making authenticated server side requests in the Next.js App Router to the WordPress backend and is part of the `@faustwp/experimental-app-router` package.
4+
5+
## Usage
6+
7+
Here is an example layout that imports `getAuthClient` and uses `query` to query WPGraphQL:
8+
9+
```js
10+
import { getAuthClient } from "@faustwp/experimental-app-router";
11+
12+
// app/my-account/posts/page.js
13+
export default async function Page() {
14+
const client = await getAuthClient();
15+
16+
if (!client) {
17+
return <>You must be authenticated to view this page!</>;
18+
}
19+
20+
const { data } = await client.query({
21+
query: gql`
22+
query GetMyPosts {
23+
viewer {
24+
posts {
25+
nodes {
26+
id
27+
title
28+
}
29+
}
30+
}
31+
}
32+
`,
33+
});
34+
35+
return (
36+
<>
37+
<h2>My posts</h2>
38+
<ul>
39+
{data.viewer.posts.nodes.map((post) => (
40+
<li key={post.id}>{post.title}</li>
41+
))}
42+
</ul>
43+
</>
44+
);
45+
}
46+
```
47+
48+
## Technical Reference
49+
50+
`getAuthClient(): ApolloClient | null`
51+
52+
The `getAuthClient` function returns the `ApolloClient`, making it available for use.
53+
54+
You can use the `ApolloClient` to perform authenticated queries for data using the `query` function.
55+
56+
The function will return `null` when it fails to retrieve the access token for making authenticated requests. If this happens, you want to check that your user becomes authenticated using the `onLogin` server action.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# `getClient`
2+
3+
`getClient` is a function that returns the `ApolloClient` making it available for use. It is part of the `@faustwp/experimental-app-router` package.
4+
5+
## Usage
6+
7+
Here is an example layout that imports `getClient` and uses `query` to query WPGraphQL:
8+
9+
```js
10+
import { gql } from '@apollo/client';
11+
import { getClient } from '@faustwp/experimental-app-router';
12+
import Link from 'next/link';
13+
import '../faust.config.js';
14+
15+
export const metadata = {
16+
title: 'Create Next App',
17+
description: 'Generated by create next app',
18+
};
19+
20+
export default async function RootLayout({ children }) {
21+
const client = await getClient();
22+
23+
const { data } = await client.query({
24+
query: gql`
25+
query GetLayout {
26+
generalSettings {
27+
title
28+
description
29+
}
30+
primaryMenuItems: menuItems(where: { location: PRIMARY }) {
31+
nodes {
32+
id
33+
label
34+
uri
35+
}
36+
}
37+
footerMenuItems: menuItems(where: { location: FOOTER }) {
38+
nodes {
39+
id
40+
label
41+
uri
42+
}
43+
}
44+
}
45+
`,
46+
});
47+
48+
return (
49+
<html lang="en">
50+
<body>
51+
<header>
52+
<div>
53+
<h1>
54+
<Link href="/">{data.generalSettings.title}</Link>
55+
</h1>
56+
57+
<h5>{data.generalSettings.description}</h5>
58+
</div>
59+
60+
<ul>
61+
{data.primaryMenuItems.nodes.map((node) => (
62+
<li>
63+
<Link href={node.uri}>{node.label}</Link>
64+
</li>
65+
))}
66+
</ul>
67+
</header>
68+
{children}
69+
</body>
70+
</html>
71+
);
72+
}
73+
```
74+
75+
## Technical Reference
76+
77+
`getClient(): ApolloClient | null`
78+
79+
The `getClient` function returns the `ApolloClient` making it available for use.
80+
81+
You can use the `ApolloClient` to perform queries for data using the `query` function.
82+
83+
## Additional Context
84+
85+
- [Next.js Server Actions](https://nextjs.org/docs/app/api-reference/functions/server-actions)
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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+
![](https://lh5.googleusercontent.com/WpRUpTGFotY68c0iyNKv6s41eaahfN8keoYXk_JlaHAUTzopbWhMDQAXiIEi0AjP1H0lXiIWV5AY0hgS8F8WlO3VknWWcD-Ii08OjJROe3LaPTtoYEyp0wzSCt_jnpACTPoSwtgH-PLhwtuF46OjREE)
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+
![The front page of the app displaying a list of published posts.](images/image-1024x771.png)
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+
![The login page displays a username field and a password field with a login button below them.](images/image-1-1024x771.png)
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+
![the endpoint my-account shows the posts available to the admin user upon login.](images/image-2-1024x810.png)
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+
![](images/image-3.png)
72.9 KB
Loading
80.2 KB
Loading
124 KB
Loading
129 KB
Loading
132 KB
Loading

0 commit comments

Comments
 (0)