diff --git a/docs/markdown/07-middleware/00-title.md b/docs/markdown/07-middleware/00-title.md
new file mode 100644
index 0000000..7520035
--- /dev/null
+++ b/docs/markdown/07-middleware/00-title.md
@@ -0,0 +1,3 @@
+
+
+# Lifecycles & Middleware
diff --git a/docs/markdown/07-middleware/01-intro.md b/docs/markdown/07-middleware/01-intro.md
new file mode 100644
index 0000000..29930c5
--- /dev/null
+++ b/docs/markdown/07-middleware/01-intro.md
@@ -0,0 +1,12 @@
+
+
+# http request lifecycle on Next.js
+
+1. headers - next.config.js
+2. redirects - next.config.js
+3. middleware
+4. rewrites | beforeFiles - next.config.js
+5. routes (/public, /\_next/..., /app...)
+6. rewrites | afterFiles - next.config.js
+7. dynamic routes (/[slug]/page.tsx ...)
+8. rewrites | fallback - next.config.js
diff --git a/docs/markdown/07-middleware/10-next-config.md b/docs/markdown/07-middleware/10-next-config.md
new file mode 100644
index 0000000..69e232e
--- /dev/null
+++ b/docs/markdown/07-middleware/10-next-config.md
@@ -0,0 +1,9 @@
+
+
+# next.config.js
+
+**next.config.js** can be used to affect the request on various things :
+
+- headers
+- rewrites
+- redirects
diff --git a/docs/markdown/07-middleware/11-headers.md b/docs/markdown/07-middleware/11-headers.md
new file mode 100644
index 0000000..8b37b5a
--- /dev/null
+++ b/docs/markdown/07-middleware/11-headers.md
@@ -0,0 +1,81 @@
+
+
+# next.config.js
+
+## headers
+
+```js
+module.exports = {
+ async headers() {
+ return [
+ {
+ source: '/employees',
+ headers: [
+ {
+ key: 'x-some-custom-header',
+ value: 'hello im a custom header value',
+ },
+ ],
+ },
+ {
+ source: '/employees/:id(\\d{1,})', // will match /employees/123 (not /employees/abc)
+ headers: [
+ {
+ key: 'x-custom-regex-header',
+ value: 'header value based on regex',
+ },
+ ],
+ },
+ ];
+ },
+};
+```
+
+##--##
+
+Advanced matching :
+
+```js
+module.exports = {
+ async headers() {
+ return [
+ {
+ source: '/:path*', // match everything except home
+ has: [
+ {
+ type: 'header',
+ key: 'x-existing-header', // match based on existing header
+ },
+ ],
+ headers: [
+ {
+ key: 'x-another-header',
+ value: 'hello',
+ },
+ ],
+ },
+ {
+ source: '/employees',
+ has: [
+ {
+ type: 'query',
+ key: 'search',
+ value: 'some-value',
+ },
+ {
+ type: 'cookie',
+ key: 'authorized',
+ value: 'true',
+ },
+ ],
+ headers: [
+ {
+ key: 'x-authorized',
+ value: ':authorized', // reference value of cookie
+ },
+ ],
+ },
+ ];
+ },
+};
+```
diff --git a/docs/markdown/07-middleware/12-matching.md b/docs/markdown/07-middleware/12-matching.md
new file mode 100644
index 0000000..1959a51
--- /dev/null
+++ b/docs/markdown/07-middleware/12-matching.md
@@ -0,0 +1,26 @@
+
+
+# next.config.js
+
+## matching request
+
+Regex based matching :
+
+```js
+module.exports = {
+ async headers() {
+ return [
+ // Regex based matching :
+ {
+ source: '/employees/:id(\\d{1,})', // will match /employees/123 (not /employees/abc)
+ headers: [
+ {
+ key: 'x-custom-regex-header',
+ value: 'header value based on regex',
+ },
+ ],
+ },
+ ];
+ },
+};
+```
diff --git a/docs/markdown/07-middleware/13-matching-attribute.md b/docs/markdown/07-middleware/13-matching-attribute.md
new file mode 100644
index 0000000..e8c332e
--- /dev/null
+++ b/docs/markdown/07-middleware/13-matching-attribute.md
@@ -0,0 +1,63 @@
+
+
+# next.config.js
+
+## matching request
+
+Request attribute matching :
+
+- **has** : check if request has a specified attribute / value
+- **missing** : check if request is missing attribute / value
+
+Has and missing objects can have the following fields :
+
+- type : header |cookie | host | query
+- key
+- value
+
+##--##
+
+```js
+module.exports = {
+ async headers() {
+ return [
+ {
+ source: '/:path*', // match everything except home
+ has: [
+ {
+ type: 'header',
+ key: 'x-existing-header', // match based on existing header
+ },
+ ],
+ headers: [
+ {
+ key: 'x-another-header',
+ value: 'hello',
+ },
+ ],
+ },
+ {
+ source: '/employees',
+ has: [
+ {
+ type: 'query',
+ key: 'search',
+ value: 'some-value',
+ },
+ {
+ type: 'cookie',
+ key: 'authorized',
+ value: 'true',
+ },
+ ],
+ headers: [
+ {
+ key: 'x-authorized',
+ value: ':authorized', // reference value of cookie
+ },
+ ],
+ },
+ ];
+ },
+};
+```
diff --git a/docs/markdown/07-middleware/14-redirects.md b/docs/markdown/07-middleware/14-redirects.md
new file mode 100644
index 0000000..754eea7
--- /dev/null
+++ b/docs/markdown/07-middleware/14-redirects.md
@@ -0,0 +1,22 @@
+
+
+# next.config.js
+
+## redirects
+
+```js
+module.exports = {
+ async redirects() {
+ return [
+ {
+ source: '/about',
+ destination: '/',
+ permanent: true,
+ },
+ ];
+ },
+};
+```
+
+- permanent **true** : redirects with 308 status code indicating caches to store the redirect permenatly
+- permanent **false** : redirects with 307 status code (temporary, not cached)
diff --git a/docs/markdown/07-middleware/15-rewrite.md b/docs/markdown/07-middleware/15-rewrite.md
new file mode 100644
index 0000000..f6a18e0
--- /dev/null
+++ b/docs/markdown/07-middleware/15-rewrite.md
@@ -0,0 +1,18 @@
+
+
+# next.config.js
+
+## rewrites
+
+```js
+module.exports = {
+ async rewrites() {
+ return [
+ {
+ source: '/about',
+ destination: '/',
+ },
+ ];
+ },
+};
+```
diff --git a/docs/markdown/07-middleware/16-rewrite-advanced.md b/docs/markdown/07-middleware/16-rewrite-advanced.md
new file mode 100644
index 0000000..b46da18
--- /dev/null
+++ b/docs/markdown/07-middleware/16-rewrite-advanced.md
@@ -0,0 +1,45 @@
+
+
+# next.config.js
+
+## rewrites
+
+Detailed configuration :
+
+1. headers - next.config.js
+2. redirects - next.config.js
+3. middleware
+4. rewrites | beforeFiles - next.config.js
+5. routes (/public, /\_next/..., /app...)
+6. rewrites | afterFiles - next.config.js
+7. dynamic routes (/[slug]/page.tsx ...)
+8. rewrites | fallback - next.config.js
+
+##--##
+
+```js
+module.exports = {
+ async rewrites() {
+ return {
+ beforeFiles: [
+ {
+ source: '/some-page',
+ destination: '/somewhere-else',
+ },
+ ],
+ afterFiles: [
+ {
+ source: '/non-existent',
+ destination: '/somewhere-else',
+ },
+ ],
+ fallback: [
+ {
+ source: '/:path*',
+ destination: `https://my-old-site.com/:path*`,
+ },
+ ],
+ };
+ },
+};
+```
diff --git a/docs/markdown/07-middleware/20-lab.md b/docs/markdown/07-middleware/20-lab.md
new file mode 100644
index 0000000..b80d945
--- /dev/null
+++ b/docs/markdown/07-middleware/20-lab.md
@@ -0,0 +1,11 @@
+
+
+# next.config.js lifecycles
+
+## Lab
+
+
+
+TODO
+
+
diff --git a/docs/markdown/07-middleware/30-middleware.md b/docs/markdown/07-middleware/30-middleware.md
new file mode 100644
index 0000000..d91bd05
--- /dev/null
+++ b/docs/markdown/07-middleware/30-middleware.md
@@ -0,0 +1,9 @@
+
+
+# middleware
+
+Limits of next.config.js :
+
+- build time
+- limited conditional rules
+- not possible to return early
diff --git a/docs/markdown/07-middleware/31-definition.md b/docs/markdown/07-middleware/31-definition.md
new file mode 100644
index 0000000..7b38a51
--- /dev/null
+++ b/docs/markdown/07-middleware/31-definition.md
@@ -0,0 +1,28 @@
+
+
+# middleware
+
+What is next.js middleware ?
+
+allows to catch the incoming request and :
+
+- modify the request / response :
+ - rewrite
+ - redirect
+ - modify request headers
+ - modify response headers
+ - return early
+- produce and return an early response
+
+##--##
+
+Runs before caching content / route matching :
+
+1. headers - next.config.js
+2. redirects - next.config.js
+3. **middleware**
+4. rewrites | beforeFiles - next.config.js
+5. routes (/public, /\_next/..., /app...)
+6. rewrites | afterFiles - next.config.js
+7. dynamic routes (/[slug]/page.tsx ...)
+8. rewrites | fallback - next.config.js
diff --git a/docs/markdown/07-middleware/32-use-cases.md b/docs/markdown/07-middleware/32-use-cases.md
new file mode 100644
index 0000000..1f04fdd
--- /dev/null
+++ b/docs/markdown/07-middleware/32-use-cases.md
@@ -0,0 +1,9 @@
+
+
+# middleware
+
+- Authentication
+- Localization (ex : redirect user to the right locale)
+- Bot detection
+- Complex URL rewriting
+- Logging / Analytics
diff --git a/docs/markdown/07-middleware/33-convention.md b/docs/markdown/07-middleware/33-convention.md
new file mode 100644
index 0000000..392ded1
--- /dev/null
+++ b/docs/markdown/07-middleware/33-convention.md
@@ -0,0 +1,14 @@
+
+
+# middleware
+
+## conventions
+
+Create a **/middleware.ts|js** file in the root directory
+export a **middleware** function :
+
+```js
+export const middleware = (request) => {
+ // Some server operations on the request
+};
+```
diff --git a/docs/markdown/07-middleware/34-url-matching.md b/docs/markdown/07-middleware/34-url-matching.md
new file mode 100644
index 0000000..57208cb
--- /dev/null
+++ b/docs/markdown/07-middleware/34-url-matching.md
@@ -0,0 +1,28 @@
+
+
+# request matching
+
+There are two ways to filter the requests :
+Exporting the **matcher** configuration :
+
+```js
+export const config = {
+ matcher: ['/employee/:path*', '/expenses/:path*'],
+};
+```
+
+##--##
+
+Conditional statements :
+
+```js
+export function middleware(request) {
+ if (request.nextUrl.pathname.startsWith('/employee')) {
+ // do something
+ }
+
+ if (request.nextUrl.pathname.startsWith('/expenses')) {
+ // do something
+ }
+}
+```
diff --git a/docs/markdown/07-middleware/35-api-modify.md b/docs/markdown/07-middleware/35-api-modify.md
new file mode 100644
index 0000000..23f0943
--- /dev/null
+++ b/docs/markdown/07-middleware/35-api-modify.md
@@ -0,0 +1,54 @@
+
+
+# API
+
+Modify response :
+
+```js
+import { NextResponse } from 'next/server';
+
+export function middleware(request) {
+ // Setting cookies on the response
+ const response = NextResponse.next();
+ response.cookies.set('sfeir', 'nextjs');
+ response.cookies.set({
+ name: 'test',
+ value: 'hello-world',
+ path: '/',
+ });
+
+ // Setting headers on the response
+ response.headers.set('sfeir', 'nextjs');
+
+ return response;
+}
+```
+
+##--##
+
+Modify request :
+
+```js
+import { NextResponse } from 'next/server';
+
+export function middleware(request) {
+ const cookie = request.cookies.get('nextjs');
+ console.log(cookie); // => { name: 'nextjs', value: 'fast', Path: '/' }
+
+ const allCookies = request.cookies.getAll();
+ console.log(allCookies); // => [{ name: 'nextjs', value: 'fast' }]
+
+ request.cookies.has('nextjs'); // => true
+ request.cookies.delete('nextjs');
+ request.cookies.has('nextjs'); // => false
+
+ // Setting headers
+ const requestHeaders = new Headers(request.headers);
+ requestHeaders.set('sfeir-request', 'nextjs');
+
+ // Setting cookies
+ request.cookies.set('sfeir-cookie', 'nextjs');
+
+ return response;
+}
+```
diff --git a/docs/markdown/07-middleware/36-api-rewrite-redirect.md b/docs/markdown/07-middleware/36-api-rewrite-redirect.md
new file mode 100644
index 0000000..ca08bdf
--- /dev/null
+++ b/docs/markdown/07-middleware/36-api-rewrite-redirect.md
@@ -0,0 +1,29 @@
+
+
+# API
+
+**Rewrite** response to display another URL :
+
+```js
+import { NextResponse } from 'next/server';
+
+export function middleware(request: NextRequest) {
+ if (request.nextUrl.pathname.startsWith('/employees')) {
+ return NextResponse.rewrite(new URL('/employees-internal', request.url));
+ }
+}
+```
+
+##--##
+
+**Redirect** the incoming request to a different URL :
+
+```js
+import { NextResponse } from 'next/server';
+
+export function middleware(request) {
+ if (request.nextUrl.pathname.startsWith('/employees')) {
+ return NextResponse.redirect(new URL('/', request.url));
+ }
+}
+```
diff --git a/docs/markdown/07-middleware/37-api-return.md b/docs/markdown/07-middleware/37-api-return.md
new file mode 100644
index 0000000..5d01cf2
--- /dev/null
+++ b/docs/markdown/07-middleware/37-api-return.md
@@ -0,0 +1,15 @@
+
+
+# API
+
+You can also produce a response early
+
+```js
+export function middleware(request) {
+ if (request.nextUrl.pathname.startsWith('/employee')) {
+ if (!checkRequest(request)) {
+ return Response.json({ success: false, message: 'bad request' }, { status: 400 });
+ }
+ }
+}
+```
diff --git a/docs/markdown/07-middleware/38-warning.md b/docs/markdown/07-middleware/38-warning.md
new file mode 100644
index 0000000..5f15598
--- /dev/null
+++ b/docs/markdown/07-middleware/38-warning.md
@@ -0,0 +1,11 @@
+
+
+# Warning
+
+- Middleware is on the critical path :
+
+ - avoid heavy operations & long tasks
+
+- Middleware does not run on a normal nodejs runtime :
+ - Native Node.js APIs are not supported (example : filesystem)
+ - only ES Modules node_modules are supported
diff --git a/docs/markdown/07-middleware/40-lab.md b/docs/markdown/07-middleware/40-lab.md
new file mode 100644
index 0000000..e233c22
--- /dev/null
+++ b/docs/markdown/07-middleware/40-lab.md
@@ -0,0 +1,11 @@
+
+
+# Middleware
+
+## Lab
+
+
+
+TODO
+
+