Skip to content

Commit cb8d997

Browse files
committed
📝 :constructor: ssr and ssg documentation
1 parent 61ee0fc commit cb8d997

File tree

25 files changed

+470
-150
lines changed

25 files changed

+470
-150
lines changed

articles/njs-file-extension.md

Lines changed: 106 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,106 @@
1-
TODO:
2-
- must import nullstack
3-
- must have one component class
4-
- must extend nullstack
5-
- must export the class
6-
- components doesent need any method to be valid
7-
- will change your code with optimizations
8-
- will remove server functions from client
9-
- will create a registry of whitelisted function calls
1+
---
2+
title: NJS File Extension
3+
description: Nullstack Javascript files let Webpack know which loaders to use at transpile time
4+
---
5+
6+
Nullstack Javascript files let Webpack know which loaders to use at transpile time.
7+
8+
NJS files must import Nullstack because at transpile time JSX tags will be replaced with *Nullstack.element*
9+
10+
This extension also allows Nullstack to make free transpile time optimizations like source injection and others mentioned in the documentation.
11+
12+
On the *server* bundle static async functions are mapped into a registry for security.
13+
14+
On the *client* bundle static async functions are removed and replaced with a flag.
15+
16+
On both *server* and *client* bundles, a hash with the md5 of the original source code is added to the class.
17+
18+
> 🐱‍💻 Bellow an example of a original .njs file.
19+
20+
```jsx
21+
import Nullstack from 'nullstack';
22+
23+
class Tasks extends Nullstack {
24+
25+
static async getTasks({limit}) {
26+
const {readFileSync} = await import('fs');
27+
const json = readFileSync('tasks.json', 'utf-8');
28+
return JSON.parse(json).tasks.slice(0, limit);
29+
}
30+
31+
prepare(context) {
32+
context.tasks = [];
33+
}
34+
35+
async initiate(context) {
36+
context.tasks = await this.getTasks({limit: 10});
37+
}
38+
39+
renderTask({task}) {
40+
return (
41+
<li>
42+
<input bind={task.description} />
43+
</li>
44+
)
45+
}
46+
47+
render() {
48+
return (
49+
<main>
50+
<ul>
51+
{tasks.map((task) => <Task task={task} />)}
52+
</ul>
53+
</main>
54+
)
55+
}
56+
57+
}
58+
59+
export default Tasks;
60+
```
61+
62+
> 🐱‍💻 Bellow an example of the same transpiled .njs file.
63+
64+
```jsx
65+
import Nullstack from 'nullstack';
66+
67+
class Tasks extends Nullstack {
68+
69+
static getTasks = true;
70+
71+
prepare(context) {
72+
context.tasks = [];
73+
}
74+
75+
async initiate(context) {
76+
context.tasks = await this.getTasks({limit: 10});
77+
}
78+
79+
renderTask({task}) {
80+
return (
81+
<li>
82+
<input source={task} bind="description" />
83+
</li>
84+
)
85+
}
86+
87+
render() {
88+
const Task = this.renderTask;
89+
return (
90+
<main>
91+
<ul>
92+
{tasks.map((task) => <Task task={task} />)}
93+
</ul>
94+
</main>
95+
)
96+
}
97+
98+
}
99+
100+
export default Tasks;
101+
Tasks.hash = 'd493ac09d0d57574a30f136d31da455f';
102+
```
103+
104+
## Next step
105+
106+
⚔ Learn about [server-side rendering](/server-side-rendering).

articles/server-functions.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,27 @@ class Component extends Nullstack {
117117
export default Component;
118118
```
119119

120+
## Server only imports
121+
122+
You can use the async version of import inside a server function to import a dependency only on the server bundle.
123+
124+
```jsx
125+
import Nullstack from 'nullstack';
126+
127+
class Application extends Nullstack {
128+
129+
static async getTasks() {
130+
const {readFileSync} = await import('fs');
131+
// ...
132+
}
133+
134+
// ...
135+
136+
}
137+
138+
export default Application;
139+
```
140+
120141
## Security
121142

122143
Keep in mind that every server function is similar to an express route in API and must be coded without depending on view logic for security.

articles/server-side-rendering.md

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
1-
TODO:
2-
- renders html from the server for seo purposes
3-
- only loads nullstack after the html is responsive
4-
- becomes a single page application when nullstack is loaded
5-
- rehydrates the state without needing to remake api calls
6-
- groups all api calls into one local function call in the first request for performance
7-
- runs prepare and awaits all initiates before rendering
8-
- uses the project and page to generate the header
1+
---
2+
title: Server-Side Rendering
3+
description: Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from
4+
---
5+
6+
Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from.
7+
8+
Server-side rendering is good for SEO since it gives as fast as possible crawlable markup for search engines.
9+
10+
Nullstack starts the application for the user by first serving HTML of only the requested page with no overhead.
11+
12+
Before serving the HTML, Nullstack will wait for *prepare* and *initiate* of all components of that route to be resolved.
13+
14+
While server-side rendering all server functions run locally without the need to fetch an API, making the process even faster.
15+
16+
After the document is already painted in the browser, Nullstack loads the javascript client bundle and starts the hydration process.
17+
18+
No further requests to the server are made to recover the application state during hydration.
19+
20+
The page head will generate the necessary meta tags for SEO based on the contents of the [project](/context-project) and [page](/context-page) context keys.
21+
22+
## Next step
23+
24+
⚔ Learn about [static site generation](/static-site-generation).

articles/static-site-generation.md

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,51 @@
1-
TODO:
2-
- what it is
3-
- is always production mode
4-
- run comand from folder
5-
- doesent have access to server after initiates
6-
- can be served
7-
- real links
8-
- state lasts for one page
9-
- server side rendering is an alternative
1+
---
2+
title: Static Site Generation
3+
description: Use Nullstack to generate static websites for lightning-fast static applications using the full power of Nullstack without the need for a node.js back-end
4+
---
5+
6+
Use Nullstack to generate static websites for lightning-fast static applications using the full power of the Nullstack client without the need for a node.js back-end.
7+
8+
Static sites are useful for read-only applications like blogs and documentation.
9+
10+
> 💡 This documentation is actually a static site generated with Nullstack.
11+
12+
All the benefits of [server-side rendering](/server-side-rendering) apply to static generated sites.
13+
14+
You can generate a static website with the following NPX command:
15+
16+
```sh
17+
npx create-nullstatic-app
18+
```
19+
20+
By default, it will create your Nullstatic application in the *static* folder.
21+
22+
You can change the folder by passing it as an argument to the command:
23+
24+
```sh
25+
npx create-nullstatic-app docs
26+
```
27+
28+
The Nullstatic generator will run your application in production mode and crawl every link to an internal route it finds in your DOM.
29+
30+
> 💡 Make sure to have the server production port free when you run this command.
31+
32+
The [manifest.json](/context-project) and the contents of the public folder will be copied into the target folder.
33+
34+
Besides generating raw HTML it will also generate a JSON file for each route with a copy of the state.
35+
36+
On the first visit to your static application, HTML will be served and hydrated.
37+
38+
On the subsequent requests, Nullstack will fetch the generated JSON and update the application state without ever reloading the page.
39+
40+
This, in fact, gives you not only a static generated site, but a static generated API that feeds a Single Page Application with zero costs.
41+
42+
## Caveats
43+
44+
Nullstatic only crawls your application up to the initiate resolution, further API requests triggered by events will be ignored.
45+
46+
47+
## Next step
48+
49+
> 🎉 *Congratulations*. You are done with the advanced concepts!
50+
51+
⚔ Learn [how to deploy a nullstack application](/how-to-deploy-a-nullstack-application).

articles/styles.md

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
1-
TODO:
2-
- recommended pattern of component import
3-
- scss
4-
- purgecss
5-
- explain caveats of purge
6-
- explain work around with purge (prism example)
1+
---
2+
title: Styles
3+
description: Using styles with Nullstack is as simple as importing a style file
4+
---
5+
6+
Using styles with Nullstack is as simple as importing a style file.
7+
8+
Nullstack comes with a [SASS](https://sass-lang.com) loader by default, but you can still use vanilla CSS.
9+
10+
> ✨ It's a good practice to import a file with the same name as the component.
11+
12+
```jsx
13+
import Nullstack from 'nullstack';
14+
import './Header.scss';
15+
16+
class Header extends Nullstack {
17+
// ...
18+
}
19+
20+
export default Header;
21+
```
22+
23+
In production mode Nullstack uses [PurceCSS](https://purgecss.com), which cleans your client.css file, but has some gotchas.
24+
25+
> ✨ Learn more about [safelisting your css](https://purgecss.com/safelisting.html)
26+
27+
## Next step
28+
29+
⚔ Learn about the [NJS file extension](/njs-file-extension).

0 commit comments

Comments
 (0)