Skip to content

Commit

Permalink
fix: extend request context to fix bug with req.json()
Browse files Browse the repository at this point in the history
  • Loading branch information
aralroca committed Oct 4, 2023
1 parent 5e2445e commit 8d81192
Show file tree
Hide file tree
Showing 33 changed files with 436 additions and 330 deletions.
11 changes: 5 additions & 6 deletions docs/01-getting-started/01-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ related:

### System Requirements

- Bun [1.0.4]( https://bun.sh/) or later
- Bun [1.0.4](https://bun.sh/) or later
- macOS, Windows (including WSL), and Linux are supported.


### Automatic Installation

We recommend starting a new Brisa app using `create-brisa-app``, which sets up everything automatically for you.
We recommend starting a new Brisa app using `create-brisa-app``, which sets up everything automatically for you.

```sh
npx create-brisa-app
Expand Down Expand Up @@ -55,9 +54,9 @@ You need to add the jsx-runtime of Brisa in your `tsconfig.json` file:
```json
{
"compilerOptions": {
// ...rest
// ...rest
"jsx": "react-jsx",
"jsxImportSource": "brisa",
"jsxImportSource": "brisa"
}
}
```
Expand All @@ -70,7 +69,7 @@ Then, add an `index.tsx` file inside your `src/pages` folder. This will be your

```tsx
export default function Page() {
return <h1>Hello, Brisa!</h1>
return <h1>Hello, Brisa!</h1>;
}
```

Expand Down
40 changes: 18 additions & 22 deletions docs/01-getting-started/02-project-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,29 @@ This page provides an overview of the file and folder structure of a Brisa proje

## `src`-level folders

| | |
| ------------------------------------------------------------------------ | ---------------------------------- |
| [`pages`](/docs/building-your-application/routing#pages) | Pages Router |
| [`api`](/docs/building-your-application/routing#api) | Api Router |
| [`public`](/docs/building-your-application/optimizing/static-assets) | Static assets to be served |
| [`middleware`](/docs/building-your-application/configuring/middleware) | Middleware |
| [`layout`](/docs/building-your-application/configuring/layout) | Layout / Layouts |
| [`websocket`](/docs/building-your-application/configuring/websocket) | Websocket |
| [`i18n`](/docs/building-your-application/configuring/i18n) | Internationalization routing & translations |


| | |
| ---------------------------------------------------------------------- | ------------------------------------------- |
| [`pages`](/docs/building-your-application/routing#pages) | Pages Router |
| [`api`](/docs/building-your-application/routing#api) | Api Router |
| [`public`](/docs/building-your-application/optimizing/static-assets) | Static assets to be served |
| [`middleware`](/docs/building-your-application/configuring/middleware) | Middleware |
| [`layout`](/docs/building-your-application/configuring/layout) | Layout / Layouts |
| [`websocket`](/docs/building-your-application/configuring/websocket) | Websocket |
| [`i18n`](/docs/building-your-application/configuring/i18n) | Internationalization routing & translations |

## Top-level files

| | |
| ------------------------------------------------------------------------------------------- | --------------------------------------- |
| | |
| [`brisa.config.js`](/docs/app/api-reference/brisa-config-js) | Configuration file for Next.


| | |
| ------------------------------------------------------------ | ---------------------------- |
| | |
| [`brisa.config.js`](/docs/app/api-reference/brisa-config-js) | Configuration file for Next. |

### Special Files in `src/pages`

| | | |
| ----------------------------------------------------------------------------------------------------------- | ------------------- | ----------------- |
| [`_404`](/docs/pages/building-your-application/routing/custom-error#404-page) | `.js` `.jsx` `.tsx` | 404 Error Page |
| [`_500`](/docs/pages/building-your-application/routing/custom-error#500-page) | `.js` `.jsx` `.tsx` | 500 Error Page |
| | | |
| ----------------------------------------------------------------------------- | ------------------- | -------------- |
| [`_404`](/docs/pages/building-your-application/routing/custom-error#404-page) | `.js` `.jsx` `.tsx` | 404 Error Page |
| [`_500`](/docs/pages/building-your-application/routing/custom-error#500-page) | `.js` `.jsx` `.tsx` | 500 Error Page |

### Routes

Expand All @@ -58,4 +54,4 @@ This page provides an overview of the file and folder structure of a Brisa proje
| **File convention** | | |
| [`[file]`](/docs/pages/building-your-application/routing/dynamic-routes) | `.js` `.jsx` `.tsx` | Dynamic route segment |
| [`[...file]`](/docs/pages/building-your-application/routing/dynamic-routes#catch-all-segments) | `.js` `.jsx` `.tsx` | Catch-all route segment |
| [`[[...file]]`](/docs/pages/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | `.js` `.jsx` `.tsx` | Optional catch-all route segment |
| [`[[...file]]`](/docs/pages/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | `.js` `.jsx` `.tsx` | Optional catch-all route segment |
2 changes: 1 addition & 1 deletion docs/01-getting-started/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
---
title: Getting Started
description: Learn how to create full-stack web applications with Brisa.
---
---
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ In Brisa framework, a **page** is a [Brisa Component](/docs/components-details)

```jsx
export default function About() {
return <div>About</div>
return <div>About</div>;
}
```

Expand Down Expand Up @@ -43,7 +43,6 @@ Brisa supports pages with dynamic routes. For example, if you create a file call

The global layout is defined inside `/src/layout/index`. By default Brisa supports a default layout, but you can modify it here.


```jsx filename="src/layout/index.js"
import { RequestContext } from "brisa";

Expand Down Expand Up @@ -107,4 +106,4 @@ export default async function Layout({ children }: { children: JSX.Element }, {
}
```

The `fetch` is directly native and has no wrapper to control the cache. We recommend that you do not do the same `fetch` in several places, but use the [`context`](/docs/building-your-application/data-fetching/request-context) to store the data and consume it from any component.
The `fetch` is directly native and has no wrapper to control the cache. We recommend that you do not do the same `fetch` in several places, but use the [`context`](/docs/building-your-application/data-fetching/request-context) to store the data and consume it from any component.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ For example, a blog could include the following route `src/pages/blog/[slug].js`

```jsx
export default function Page(props, { route }) {
return <p>Post: {route.query.slug}</p>
return <p>Post: {route.query.slug}</p>;
}
```

Expand Down Expand Up @@ -54,4 +54,4 @@ The difference between **catch-all** and **optional catch-all** segments is that
| `pages/shop/[[...slug]].js` | `/shop` | `{}` |
| `pages/shop/[[...slug]].js` | `/shop/a` | `{ slug: ['a'] }` |
| `pages/shop/[[...slug]].js` | `/shop/a/b` | `{ slug: ['a', 'b'] }` |
| `pages/shop/[[...slug]].js` | `/shop/a/b/c` | `{ slug: ['a', 'b', 'c'] }` |
| `pages/shop/[[...slug]].js` | `/shop/a/b/c` | `{ slug: ['a', 'b', 'c'] }` |
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function Home() {
<a href="/blog/hello-world">Blog Post</a>
</li>
</ul>
)
);
}
```

Expand All @@ -29,7 +29,6 @@ The example above uses multiple `a` tags. Each one maps a path (`href`) to a kno
- `/about``src/pages/about.js`
- `/blog/hello-world``src/pages/blog/[slug].js`


## Navigation to dynamic paths

You can also use interpolation to create the path, which comes in handy for [dynamic route segments](/docs/building-your-application/routing/dynamic-routes). For example, to show a list of posts which have been passed to the component as a prop:
Expand All @@ -40,26 +39,23 @@ export default function Posts({ posts }) {
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${encodeURIComponent(post.slug)}`}>
{post.title}
</a>
<a href={`/blog/${encodeURIComponent(post.slug)}`}>{post.title}</a>
</li>
))}
</ul>
)
);
}
```

> [`encodeURIComponent`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) is used in the example to keep the path utf-8 compatible.

## I18n navigation

If you have [i18n routing](/docs/routing/internationalization) enabled, during navigation you always have to forget about route translations and during the render of the page will be translated to correct translated page.

```jsx
export default function Home() {
return <a href="/about">About Us</a>
return <a href="/about">About Us</a>;
}
```

Expand All @@ -77,7 +73,7 @@ It is always possible to force a specific route in case you want to change the l

```jsx
export default function Home() {
return <a href="/es/sobre-nosotros">About Us in Spanish</a>
return <a href="/es/sobre-nosotros">About Us in Spanish</a>;
}
```

Expand Down
14 changes: 6 additions & 8 deletions docs/02-building-your-application/01-routing/04-custom-error.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,38 @@ description: Override and extend the built-in Error page to handle custom errors

## 404 Page

To create a custom 404 page you can create a `src/pages/_404.js` file.
To create a custom 404 page you can create a `src/pages/_404.js` file.

```jsx filename="src/pages/_404.js"
export default function Custom404() {
return <h1>404 - Page Not Found</h1>
return <h1>404 - Page Not Found</h1>;
}
```

> **Good to know**: In this page you can access to the `request context`, `fetch` data, change the `head` content (meta tags, etc), and change the `response headers`, in the same way of the rest of pages.

## 500 Page

To customize the 500 page you can create a `src/pages/_500.js` file.

```jsx filename="src/pages/_500.js"
export default function Custom500({ error }, requestContext) {
return <h1>500 - {error.message}</h1>
return <h1>500 - {error.message}</h1>;
}
```

> **Good to know**: In this page you can access to the `request context`, `fetch` data, change the `head` content (meta tags, etc), and change the `response headers`, in the same way of the rest of pages.

### Errors in component-level

If you want to control errors at the component level instead of displaying a whole new page with the error, you can make the components have the error extension by adding the `ComponentName.error`:

```jsx
export default function SomeComponent() {
return /* some JSX */
return; /* some JSX */
}

SomeComponent.error = ({ error }, requestContext) => {
return <p>Oops! {error.message}</p>
}
return <p>Oops! {error.message}</p>;
};
```
49 changes: 23 additions & 26 deletions docs/02-building-your-application/01-routing/05-api-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ import { type RequestContext } from "brisa";

export function GET(request: RequestContext) {
const responseData = JSON.stringify({
message: "Hello world from Brisa!"
})
message: "Hello world from Brisa!",
});

const responseOptions = {
headers: { "content-type": "application/json" }
}
headers: { "content-type": "application/json" },
};

return new Response(responseData, responseOptions);
}
```


## Query and parameters

If we want for example to use a dynamic route for users and know which username it is:

- `/api/user/aralroca?id=3``src/api/user/[username].ts`

We have access to the route through the `RequestContext` and we can access both the parameters and the query.
Expand All @@ -39,7 +39,7 @@ We have access to the route through the `RequestContext` and we can access both
import { type RequestContext } from "brisa";

export function GET({ route: { query, params } }: RequestContext) {
const { id } = params
const { id } = params;
return new Response(`Hello world ${query.username} with id=${id}!`);
}
```
Expand All @@ -48,7 +48,6 @@ export function GET({ route: { query, params } }: RequestContext) {

The request that arrives is an extension of the native [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request), where apart from having everything that the request has, it has extra information of the request, such as the `i18n`, the `route` and more. If you want to know more take a look at [`request context`](/docs/building-your-application/data-fetching/request-context).


## Response

The [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) is the native one, so you can find out [here](https://developer.mozilla.org/en-US/docs/Web/API/Response) how it works.
Expand All @@ -65,27 +64,26 @@ Example:
import { type RequestContext } from "brisa";

export function GET({ i18n, route: { query, params } }: RequestContext) {
const { id } = params
return new Response(i18n.t('hello', { name: params.username, id }));
const { id } = params;
return new Response(i18n.t("hello", { name: params.username, id }));
}
```

And this inside `src/i18n/index.ts` or `src/i18n.ts` file:


```ts filename="src/i18n/index.ts" switcher
export default {
locales: ['en', 'es'],
defaultLocale: 'en',
locales: ["en", "es"],
defaultLocale: "en",
messages: {
en: {
hello: 'Hello {{name}} with id={{id}}!',
hello: "Hello {{name}} with id={{id}}!",
},
es: {
hello: '¡Hola {{name}} con id={{id}}!',
hello: "¡Hola {{name}} con id={{id}}!",
},
},
}
};
```

## Dynamic routes, catch all and optional catch all routes
Expand All @@ -97,15 +95,14 @@ API Routes support [dynamic routes](/docs/building-your-application/routing/dyna
It can be extended to catch all paths by adding three dots (`...`) inside the brackets. For example:

- `/api/post/a``pages/api/post/[...slug].js`
- `/api/post/a/b` `pages/api/post/[...slug].js`
`/api/post/a/b/c` and so on. `pages/api/post/[...slug].js`
- `/api/post/a/b``pages/api/post/[...slug].js`
`/api/post/a/b/c` and so on. → `pages/api/post/[...slug].js`

Catch all routes can be made optional by including the parameter in double brackets (`[[...slug]]`).

- `/api/post``pages/api/post/[[...slug]].js`
- `/api/post/a``pages/api/post/[[...slug]].js`
- `/api/post/a/b`, and so on. → `pages/api/post/[[...slug]].js`

- `/api/post``pages/api/post/[[...slug]].js`
- `/api/post/a``pages/api/post/[[...slug]].js`
- `/api/post/a/b`, and so on. → `pages/api/post/[[...slug]].js`

> **Good to know**: You can use names other than `slug`, such as: `[[...param]]`
Expand All @@ -115,14 +112,14 @@ You can set CORS headers on a `Response` using the standard Web API methods:

```ts
export async function GET(request: Request) {
return new Response('Hello, Brisa!', {
return new Response("Hello, Brisa!", {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
},
})
});
}
```

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@
"peerDependencies": {
"typescript": "5.2.2"
}
}
}
6 changes: 4 additions & 2 deletions src/__fixtures__/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export default async function middleware(request: Request) {
const url = new URL(request.url);
import { RequestContext } from "../types";

export default async function middleware(request: RequestContext) {
const url = new URL(request.finalURL);

if (url.pathname !== "/test") return;

Expand Down
Loading

0 comments on commit 8d81192

Please sign in to comment.