Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Add docs for How to Add Custom Middleware #6

Merged
merged 9 commits into from
Jan 29, 2025

Conversation

Pathan-Amaankhan
Copy link
Member

@Pathan-Amaankhan Pathan-Amaankhan commented Jan 28, 2025

What

  • This PR adds a doc for how to add custom middlewares in our next application.

Related Issue(s):

Screenshots

image

Additional Info

Checklist

  • I have read the Contribution Guidelines.
  • My code is tested to the best of my abilities.
  • My code passes all lints (ESLint, tsc, prettier etc.).
  • My code has detailed inline documentation.
  • I have added unit tests to verify the code works as intended.
  • I have updated the project documentation accordingly.

@Pathan-Amaankhan Pathan-Amaankhan marked this pull request as ready for review January 28, 2025 11:30
@justlevine justlevine changed the title Docs: Adds How to Add a Custom Middleware documentation docs: Add How to Add Custom Middleware Jan 28, 2025
docs/middlewares.md Outdated Show resolved Hide resolved
@justlevine justlevine changed the title docs: Add How to Add Custom Middleware docs: Add docs for How to Add Custom Middleware Jan 28, 2025
Comment on lines 13 to 34
```typescript
/**
* Middleware function for Next.js
*
* This middleware adds a custom header 'x-current-path' to the response,
* which contains the current pathname of the request.
*
* @param next - Next middleware
* @return The response object with modified headers
*/
export const currentPath: MiddlewareFactory = ( next: NextMiddleware ) => {
return async ( request: NextRequest, _next: NextFetchEvent ) => {
const response = await next( request, _next );

if ( response ) {
response.headers.set( 'x-current-path', request.nextUrl.pathname );
}

return response;
};
};
```
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a src directory for keeping the code. The description is good enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 6325e84

Comment on lines 40 to 88
```typescript
/**
* Middleware function for Next.js
*
* This middleware adds custom proxies.
*
* @param next - Next middleware
* @return Custom redirection or NextMiddleware.
*/
export const proxies: MiddlewareFactory = ( next: NextMiddleware ) => {
return async ( request: NextRequest, _next: NextFetchEvent ) => {
const nextPath = request.nextUrl.pathname;

const { homeUrl, uploadsDirectory, restUrlPrefix } = getConfig();

// Proxy for WordPress uploads.
const uploadsRegex = new RegExp(
// Adding trailing slash to uploadsDirectory path if not already present before searching.
`${ addTrailingSlash( uploadsDirectory ) }.*`
);
if ( uploadsRegex.test( nextPath ) ) {
const match = uploadsRegex.exec( nextPath );

if ( match && match[ 0 ] ) {
return NextResponse.redirect( new URL( match[ 0 ], homeUrl ) );
}
}

// Proxy for WordPress APIs.
// If nextPath starts with restUrlPrefix, redirect to homeUrl/pathName.
if ( nextPath.startsWith( restUrlPrefix ) ) {
const APIRegex = new RegExp( `${ restUrlPrefix }.*` );
const match = APIRegex.exec( request.nextUrl.toString() );
if ( match && match[ 0 ] ) {
return NextResponse.redirect( new URL( match[ 0 ], homeUrl ) );
}
}

// Proxy for Admin AJAX.
if ( '/wp-admin/admin-ajax.php' === nextPath ) {
return NextResponse.redirect(
new URL( '/wp-admin/admin-ajax.php', homeUrl )
);
}

return next( request, _next );
};
};
```
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 6325e84

Comment on lines 90 to 96
## How to add custom middleware

To add custom middleware, please follow the instructions provided below:

1. Create middleware of type `MiddlewareFactory`.
2. Import middleware to `src/middleware.ts` file.
3. In `src/middleware.ts` file, add imported middleware to `middleware` array.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO in any tutorial/how-to, you should never provide any information for the next step until the previous one is done. The steps in the section "## Sample Implementation of Middleware" are more suited to be here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 579f857

Comment on lines 123 to 169
## Sample Implementation of Middleware

In this example we will be creating a homepage redirect whenever `/about` page is visited.

### Step 1

- Create a `src/redirectToHome.ts` middleware file containing the following middleware code:

```typescript
import { MiddlewareFactory } from '@snapwp/next';
import { type NextRequest, NextFetchEvent, NextMiddleware } from 'next/server';

export const redirectToHome: MiddlewareFactory = (
next: NextMiddleware
): NextMiddleware => {
// Return NextMiddleware.
return ( request: NextRequest, _next: NextFetchEvent ) => {
// Redirect to home page whenever user visits about page.
if ( '/about' === request.nextUrl.pathname ) {
return NextResponse.redirect( new URL( '/', request.url ) );
}

return next( request, _next ); // Call next middleware to conitnue execution.
};
};
```

### Step 2

- Import middleware created in `Step 1` file to `src/middleware.ts`.

```typescript
import { redirectToHome } from './redirectToHome';
```

### Step 3

- In `src/middleware.ts`, add the imported `redirectToHome` middleware in `middlewares` array.

```typescript
const middlewares: MiddlewareFactory[] = [ redirectToHome ];
```

## Notes

- Multiple middleware can be loaded by adding them to `middleware` array in `src/middleware.ts` file.
- The execution priority of middleware will depend on the index they are added in `middleware` array.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This highlighted section is enough for "how to add a custom middleware"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 579f857

@Pathan-Amaankhan
Copy link
Member Author

Hi @ayushnirwal @justlevine,
One thing I would like to ask from my end i.e. the file paths that we have added like src/middleware.ts, can we convert them to a working link in future once we have a working master branch...? or should we skip this...?

cc: @joelabreo227

@justlevine
Copy link
Collaborator

justlevine commented Jan 29, 2025

One thing I would like to ask from my end i.e. the file paths that we have added like src/middleware.ts, can we convert them to a working link in future once we have a working master branch...? or should we skip this...?

@Pathan-Amaankhan

For /docs we can use repository-relative paths. README.md files (since they're used in NPM) should use absolute links pointing to tree/develop.

Copy link
Collaborator

@justlevine justlevine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refocused on our audience and then deduped.

If something I removed you feel is important to be restored, we discuss and add it back in v0.0.1

@justlevine justlevine merged commit 7540302 into develop Jan 29, 2025
16 checks passed
@justlevine justlevine deleted the docs/middleware branch January 29, 2025 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants