diff --git a/docs/getting-started/installation.mdx b/docs/getting-started/installation.mdx
index 35b041b1..d3cf028e 100644
--- a/docs/getting-started/installation.mdx
+++ b/docs/getting-started/installation.mdx
@@ -133,6 +133,11 @@ using [Edge.js](https://edgejs.dev/docs/introduction) as template engine
to serve static HTML from the server.
- `WEB REACT` application is ideal for creating full-stack applications using
[React](https://react.dev/).
+- `WEB REACT SSR` application is ideal for creating full-stack applications using
+[React](https://react.dev/) applying [SSR (Server Side Rendering)](https://www.sanity.io/glossary/server-side-rendering)
+techniques for faster page loads and to allow search engines to crawl your
+pages for [SEO (Search Engine Optimization)(https://searchengineland.com/guide/what-is-seo)
+purposes.
## Running your application
diff --git a/docs/rest-api-application/web-application.mdx b/docs/rest-api-application/web-application.mdx
index 82b70e68..97250401 100644
--- a/docs/rest-api-application/web-application.mdx
+++ b/docs/rest-api-application/web-application.mdx
@@ -35,8 +35,8 @@ athenna new my-web-app
:::note
-Don't forget to select `WEB EDGE` or `WEB REACT` when prompted about the
-application type.
+Don't forget to select `WEB EDGE`, `WEB REACT` or `WEB REACT SSR` when
+prompted about the application type.
:::
@@ -63,6 +63,15 @@ imports. Each entry point will result in a separate output bundle.
Also, if needed, you can define multiple entrypoints. For example, an
entry point for your user-facing app and another for the admin panel.
+#### assetsUrl
+
+It contains the URL to prefix when generating links for assets in
+production. If you upload the Vite output to a CDN, then the value
+of this property should be the CDN server URL.
+
+Ensure you update the backend configuration to use the same `assetsUrl`
+value.
+
#### buildDirectory
The `buildDirectory` option defines a relative path to the output
@@ -72,7 +81,7 @@ If you decide to change the default value, make sure also to update the
`buildDirectory` path in the `vite` object inside
configuration file.
-Default: `public/assets`
+Default: `Path.public('assets')`
#### reload
@@ -81,15 +90,6 @@ on file change. By default, we watch for Edge templates in `WEB EDGE`
application and `.tsx` files on `WEB REACT`. However, you can
configure additional patterns as well.
-#### assetsUrl
-
-It contains the URL to prefix when generating links for assets in
-production. If you upload the Vite output to a CDN, then the value
-of this property should be the CDN server URL.
-
-Ensure you update the backend configuration to use the same `assetsUrl`
-value.
-
### Vite backend configuration
#### dev
@@ -99,17 +99,33 @@ By default, this is controlled by the `Config.get('app.environment')`
configuration which points to the `APP_ENV` environment variable
defined in your `.env` file.
+#### assetsUrl
+
+The URL to prefix when generating links for assets in production.
+If you upload the Vite output to a CDN, then the value of this
+property should be the CDN server URL.
+
#### buildDirectory
It contains the path to the Vite's build output directory.
You must also update this backend config if you change the
default value inside the `vite.config.ts` file.
-#### assetsUrl
+#### ssrEntrypoint
-The URL to prefix when generating links for assets in production.
-If you upload the Vite output to a CDN, then the value of this
-property should be the CDN server URL.
+With this option set, SSR will be turn on into your application.
+This defines where Vite needs to look when compiling your server
+entrypoint files and when searching for the default entrypoint to
+render when using `response.render()` method.
+
+Default: `src/resources/app/app.tsx`
+
+#### ssrBuildDirectory
+
+It contains the path to the Vite's SSR build output directory, which
+needs to export the components so the server could import and serve it.
+
+Default: `Path.public('assets/server')`
#### scriptAttributes
@@ -343,6 +359,120 @@ export default {
}
```
+## Server Side Rendering (SSR)
+
+SSR, short for Server-Side Rendering, is a technique in web development
+where the webpage's content is rendered on the server instead of the client's
+browser. The primary advantage of SSR lies in its ability to significantly
+enhance user experience by facilitating faster page transitions and quick
+loading times.
+
+If you use `WEB EDGE` application type you will be already using
+SSR by default, but you can't use nice frameworks like React without some heavy
+configuration.
+
+That's why Athenna exposes the `WEB REACT SSR` application type that will come
+with everything configured for you to start building your application. The key
+difference from `WEB REACT` and `WEB REACT SSR` is that instead of letting the
+client create and load React root, we do that on the server and just hydrate the
+root in the client, which is way less expensive for the client machine.
+
+### Configurations
+
+The configurations in your `vite` object of
+that make your application understand you want to use some framework
+with SSR are the following:
+
+```typescript
+export default {
+ vite: {
+ // ...
+
+ ssrEntrypoint: 'src/resources/app/app.tsx',
+ ssrBuildDirectory: Path.public('assets/server')
+ }
+}
+```
+
+- `ssrEntrypoint` will map your server entrypoint for serving your
+component.
+- `ssrBuildDirectory` will map where the server entrypoint compiled
+code should be stored. This property also defines where the manifest
+file of your server code will stored, in this case our manifest file
+would be stored inside .
+
+:::note
+
+Vite never will compile your backend code, this will still be done by
+`tsc`. The `ssrEntrypoint` file is the entrypoint of your backend
+code to the client code, Vite compiles your entrypoint in runtime
+(in development) so we avoid adding features to `tsc` to load files
+like CSS, JSX, SASS and etc.
+
+:::
+
+### Hydrate part
+
+In the we are
+hydrating the root element using React API:
+
+```typescript
+import { App } from '#app/app'
+import { hydrateRoot } from 'react-dom/client'
+
+hydrateRoot(document.getElementById('root'), )
+```
+
+:::note
+
+For now Athenna has integration only with React for SSR. If you want
+support for other frameworks, please [open a discussion](https://github.com/orgs/AthennaIO/discussions).
+
+:::
+
+### Rendering React components
+
+The `@athenna/vite` package exposes the `React` helper which you
+can use to load and render components inside your backend routes.
+The following example is the default example that comes with the
+`WEB REACT SSR` application type:
+
+```typescript
+import { React } from '@athenna/vite'
+import { Controller, type Context } from '@athenna/http'
+
+@Controller()
+export class AppController {
+ public async index({ request, response }: Context) {
+ const { createApp } = await React.loadEntrypoint()
+
+ const element = await React.renderComponent(createApp(request.baseUrl))
+
+ return response.view('index', { element })
+ }
+}
+```
+
+1. First we use the `loadEntrypoint()` method that internally will
+use Vite to compile (or search in manifest file) the content of your
+`ssrEntrypoint` file. After that the module is imported and you can
+use all the resources from the file.
+2. After importing the `createApp()` function from our entrypoint,
+we call the function to create our `` component and send as
+parameter to the `renderComponent()` method which will use `react-dom/server`
+to transform the component to an HTML string.
+3. Now is simple, we just need to send our element to `index.edge`
+view which will render all the elements.
+
+#### Importing other components
+
+In case you want to import other components beside the entrypoint
+you can use the `loadComponent()` method:
+
+```typescript
+const { createApp } = await React.loadComponent('src/resources/app/app.tsx')
+```
+
## Manifest file
Vite generates the manifest file alongside the production build