Skip to content
This repository was archived by the owner on Oct 13, 2022. It is now read-only.

Commit b5c63a7

Browse files
authored
Merge pull request #15 from sveltejs/layout
docs for sveltejs/sapper#157
2 parents 0952b40 + cfd4149 commit b5c63a7

File tree

12 files changed

+149
-132
lines changed

12 files changed

+149
-132
lines changed

routes/_components/Layout.html renamed to app/App.html

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
<Nav {page}/>
1+
<Nav page={
2+
props.path === '/' ? 'home' :
3+
props.path === '/guide' ? 'guide' :
4+
null
5+
}/>
26

37
<div>
4-
<slot></slot>
8+
<svelte:component this={Page} {...props}/>
59
</div>
610

711
<style>
@@ -19,11 +23,9 @@
1923
</style>
2024

2125
<script>
22-
import Nav from './Nav.html';
23-
2426
export default {
2527
components: {
26-
Nav
28+
Nav: '../components/Nav.html'
2729
}
2830
};
2931
</script>

app/client.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
import { init } from 'sapper/runtime.js';
22
import { routes } from './manifest/client.js';
3+
import { Store } from 'svelte/store.js';
4+
import App from './App.html';
35

46
// `routes` is an array of route objects injected by Sapper
5-
init(document.querySelector('#sapper'), routes);
7+
init({
8+
target: document.querySelector('#sapper'),
9+
App,
10+
routes,
11+
store: state => {
12+
const store = new Store(state);
13+
14+
fetch(`guide-contents.json`).then(r => r.json()).then(guide_contents => {
15+
store.set({ guide_contents });
16+
});
17+
18+
return store;
19+
}
20+
});
621

722
if (navigator.serviceWorker && navigator.serviceWorker.controller) {
823
navigator.serviceWorker.controller.onstatechange = function(e) {

app/server.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@ import express from 'express';
22
import compression from 'compression';
33
import sapper from 'sapper';
44
import serve from 'serve-static';
5+
import { Store } from 'svelte/store.js';
56
import { routes } from './manifest/server.js';
7+
import App from './App.html';
68

79
express()
810
.use(
911
compression({ threshold: 0 }),
1012
serve('assets'),
11-
sapper({ routes })
13+
sapper({
14+
App,
15+
routes,
16+
store: () => new Store({
17+
guide_contents: []
18+
})
19+
})
1220
)
1321
.listen(process.env.PORT);
File renamed without changes.

routes/_components/Nav.html renamed to components/Nav.html

+4-6
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,11 @@
202202
</style>
203203

204204
<script>
205-
import GuideContents from './GuideContents.html';
206-
207205
export default {
206+
components: {
207+
GuideContents: './GuideContents.html'
208+
},
209+
208210
data () {
209211
return {
210212
open: false,
@@ -234,10 +236,6 @@
234236

235237
this.set({ open: !open });
236238
}
237-
},
238-
239-
components: {
240-
GuideContents
241239
}
242240
};
243241
</script>

content/guide/01-structure.md

+28-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ If you take a look inside the [sapper-template](https://github.com/sveltejs/sapp
1111
├ app
1212
│ ├ manifest
1313
│ │ ├ # files generated by Sapper
14+
│ ├ App.html
1415
│ ├ client.js
1516
│ ├ server.js
1617
│ ├ service-worker.js
@@ -45,17 +46,40 @@ Your package.json contains your app's dependencies, including `sapper`, and defi
4546

4647
### app
4748

48-
This contains the three *entry points* for your app — `app/client.js`, `app/server.js` and (optionally) `app/service-worker.js` — along with an `app/template.html` file.
49+
This contains the three *entry points* for your app — `app/client.js`, `app/server.js` and (optionally) `app/service-worker.js` — along with an `app/template.html` file and your main `app/App.html` component.
50+
51+
#### app/App.html
52+
53+
This is the root component of your entire app. It is responsible for overall layout and for rendering individual pages:
54+
55+
```html
56+
<!-- app/App.html -->
57+
<main>
58+
<svelte:component this={Page} {...props}>
59+
</main>
60+
61+
<style>
62+
main {
63+
max-width: 800px;
64+
margin: 0 auto;
65+
}
66+
</style>
67+
```
4968

5069
#### app/client.js
5170

52-
This *must* import, and call, the `init` function from `sapper/runtime.js`, using the `routes` object Sapper generates:
71+
This *must* import, and call, the `init` function from `sapper/runtime.js`, using your `App.html` and the `routes` object Sapper generates:
5372

5473
```js
5574
import { init } from 'sapper/runtime.js';
5675
import { routes } from './manifest/client.js';
76+
import App from './App.html';
5777

58-
init(document.querySelector('#sapper'), routes);
78+
init({
79+
target: document.querySelector('#sapper'),
80+
App,
81+
routes
82+
});
5983
```
6084

6185
In many cases, that's the entirety of your entry module, though you can do as much or as little here as you wish. See the [runtime API](guide#runtime-api) section for more information on functions you can import.
@@ -66,7 +90,7 @@ In many cases, that's the entirety of your entry module, though you can do as mu
6690
This is a normal Express (or [Polka](https://github.com/lukeed/polka), etc) app, with three requirements:
6791

6892
* it should serve the contents of the `assets` folder, using for example [serve-static](https://github.com/expressjs/serve-static)
69-
* it should call `app.use(sapper({ routes }))` at the end, where `routes` is imported from `app/manifest/server.js`
93+
* it should call `app.use(sapper({ App, routes }))` at the end, where `routes` is imported from `app/manifest/server.js` and `App` is your `App.html`
7094
* it must listen on `process.env.PORT`
7195

7296
Beyond that, you can write the server however you like.

content/guide/11-migrating.md

+46
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,49 @@ If you have a service worker, you should also have a `webpack/service-worker.con
8484
#### Pages
8585

8686
* Your `preload` functions should now use `this.fetch` instead of `fetch`. `this.fetch` allows you to make credentialled requests on the server, and means that you no longer need to create a `global.fetch` object in `app/server.js`.
87+
88+
89+
### 0.11 to 0.12
90+
91+
In earlier versions, each page was a completely standalone component. Upon navigation, the entire page would be torn down and a new one created. Typically, each page would import a shared `<Layout>` component to achieve visual consistency.
92+
93+
As of 0.12, this changes: we have a single `<App>` component, defined in `app/App.htnl`, which controls the rendering of the rest of the app. See [sapper-template](https://github.com/sveltejs/sapper-template/blob/master/app/App.html) for an example.
94+
95+
This component is rendered with the following values:
96+
97+
* `Page` — a component constructor for the current page
98+
* `props` — an object with `params`, `query`, and any data returned from the page's `preload` function, if any
99+
* `preloading``true` during preload, `false` otherwise. Useful for showing progress indicators
100+
101+
Sapper needs to know about your app component. To that end, you will need to modify your `app/server.js` and `app/client.js`:
102+
103+
```js
104+
// app/server.js
105+
import polka from 'polka';
106+
import sapper from 'sapper';
107+
import serve from 'serve-static';
108+
import { routes } from './manifest/server.js';
109+
import App from './App.html';
110+
111+
polka()
112+
.use(
113+
serve('assets'),
114+
sapper({ App, routes })
115+
)
116+
.listen(process.env.PORT);
117+
```
118+
119+
```js
120+
// app/client.js
121+
import { init } from 'sapper/runtime.js';
122+
import { routes } from './manifest/client.js';
123+
import App from './App.html';
124+
125+
init({
126+
target: document.querySelector('#sapper'),
127+
routes,
128+
App
129+
});
130+
```
131+
132+
Once your `App.htnl` has been created and your server and client apps updated, you can remove any `<Layout>` components from your individual pages.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"marked": "^0.3.7",
2525
"node-fetch": "^2.0.0",
2626
"npm-run-all": "^4.1.2",
27-
"sapper": "^0.11.1",
27+
"sapper": "^0.12.0",
2828
"serve": "^6.4.10",
2929
"serve-static": "^1.13.1",
3030
"svelte": "^2.4.4",

routes/4xx.html

+2-21
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,5 @@
22
<title>Sapper • Military-grade progressive web apps, powered by Svelte</title>
33
</svelte:head>
44

5-
<Layout>
6-
<h1>{error.message}</h1>
7-
<p>Error code {status}</p>
8-
</Layout>
9-
10-
<style>
11-
12-
</style>
13-
14-
<script>
15-
import Layout from './_components/Layout.html';
16-
import store from './_store.js';
17-
18-
export default {
19-
components: {
20-
Layout
21-
},
22-
23-
store: () => store
24-
};
25-
</script>
5+
<h1>{error.message}</h1>
6+
<p>Error code {status}</p>

routes/5xx.html

+2-21
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,5 @@
22
<title>Sapper • Military-grade progressive web apps, powered by Svelte</title>
33
</svelte:head>
44

5-
<Layout>
6-
<h1>Internal server error</h1>
7-
<p>{error.message}</p>
8-
</Layout>
9-
10-
<style>
11-
12-
</style>
13-
14-
<script>
15-
import Layout from './_components/Layout.html';
16-
import store from './_store.js';
17-
18-
export default {
19-
components: {
20-
Layout
21-
},
22-
23-
store: () => store
24-
};
25-
</script>
5+
<h1>Internal server error</h1>
6+
<p>{error.message}</p>

routes/guide.html

+18-45
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,22 @@
22
<title>Learn Sapper</title>
33
</svelte:head>
44

5-
<Layout page='guide'>
6-
<div ref:container class='content'>
7-
{#each sections as section}
8-
<section id='{section.slug}'>
9-
<h2>
10-
{section.metadata.title}
11-
<small><a href='https://github.com/sveltejs/sapper.svelte.technology/edit/master/content/guide/{section.file}'>edit this section</a></small>
12-
</h2>
13-
14-
{@html section.html}
15-
</section>
16-
{/each}
17-
</div>
18-
19-
<div class='sidebar'>
20-
<GuideContents ref:contents/>
21-
</div>
22-
</Layout>
5+
<div ref:container class='content'>
6+
{#each sections as section}
7+
<section id='{section.slug}'>
8+
<h2>
9+
{section.metadata.title}
10+
<small><a href='https://github.com/sveltejs/sapper.svelte.technology/edit/master/content/guide/{section.file}'>edit this section</a></small>
11+
</h2>
12+
13+
{@html section.html}
14+
</section>
15+
{/each}
16+
</div>
17+
18+
<div class='sidebar'>
19+
<GuideContents ref:contents/>
20+
</div>
2321

2422
<style>
2523
.sidebar {
@@ -223,29 +221,9 @@ <h2>
223221
</style>
224222

225223
<script>
226-
import store from './_store.js';
227-
import GuideContents from './_components/GuideContents.html';
228-
import Layout from './_components/Layout.html';
229-
230-
function throttle(fn, ms) {
231-
let blocked = false;
232-
233-
function unblock() {
234-
blocked = false;
235-
};
236-
237-
return function () {
238-
if (blocked) return;
239-
blocked = true;
240-
241-
fn();
242-
setTimeout(unblock, ms);
243-
};
244-
}
245-
246224
export default {
247-
store() {
248-
return store;
225+
components: {
226+
GuideContents: '../components/GuideContents.html'
249227
},
250228

251229
preload() {
@@ -306,11 +284,6 @@ <h2>
306284

307285
onresize();
308286
onscroll();
309-
},
310-
311-
components: {
312-
GuideContents,
313-
Layout
314287
}
315288
};
316289
</script>

0 commit comments

Comments
 (0)