├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── pnpm-lock.yaml
├── public
└── index.html
├── rollup.config.js
├── server.js
└── src
├── App.svelte
├── main.js
└── url.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | public/build
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Bjorn Lu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Svelte URL
2 |
3 | Barebones routing with reactive URLs
4 |
5 | https://svelte.dev/repl/5abaac000b164aa1aacc6051d5c4f584?version=3
6 |
7 | ```svelte
8 | {#if $url.pathname === '/'}
9 |
Home Sweet Home
10 | {:else if $url.pathname === '/about'}
11 | About What?
12 | {:else}
13 | 404
14 | {/if}
15 | ```
16 |
17 | ## How to use
18 |
19 | This is not an NPM package. The heart of this repo is at [src/url.js](./src/url.js). It's only a single file so feel free to copy-paste it into your project.
20 |
21 | ## Try it out
22 |
23 | ```bash
24 | # Copy project with degit
25 | $ npx degit bluwy/svelte-url svelte-app
26 |
27 | # Change to project directory
28 | $ cd svelte-app
29 |
30 | # Install dependencies
31 | $ pnpm install
32 |
33 | # Build project
34 | $ pnpm build
35 |
36 | # Serve SPA at http://localhost:5001
37 | $ pnpm serve:spa
38 |
39 | # Or serve SSR at http://localhost:5002
40 | $ pnpm serve:ssr
41 | ```
42 |
43 | ## License
44 |
45 | MIT
46 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-url",
3 | "version": "1.0.0",
4 | "description": "Svelte reactive URL",
5 | "private": true,
6 | "author": "Bjorn Lu",
7 | "license": "MIT",
8 | "scripts": {
9 | "build": "rollup -c",
10 | "serve:spa": "sirv public -s --port 3000",
11 | "serve:ssr": "node server.js"
12 | },
13 | "devDependencies": {
14 | "@rollup/plugin-node-resolve": "^9.0.0",
15 | "@types/node": "^14.18.54",
16 | "polka": "^0.5.2",
17 | "rollup": "^2.79.1",
18 | "rollup-plugin-svelte": "^6.1.1",
19 | "sirv": "^1.0.19",
20 | "sirv-cli": "^1.0.14",
21 | "svelte": "^3.59.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | devDependencies:
8 | '@rollup/plugin-node-resolve':
9 | specifier: ^9.0.0
10 | version: 9.0.0(rollup@2.79.1)
11 | '@types/node':
12 | specifier: ^14.18.54
13 | version: 14.18.54
14 | polka:
15 | specifier: ^0.5.2
16 | version: 0.5.2
17 | rollup:
18 | specifier: ^2.79.1
19 | version: 2.79.1
20 | rollup-plugin-svelte:
21 | specifier: ^6.1.1
22 | version: 6.1.1(rollup@2.79.1)(svelte@3.59.2)
23 | sirv:
24 | specifier: ^1.0.19
25 | version: 1.0.19
26 | sirv-cli:
27 | specifier: ^1.0.14
28 | version: 1.0.14
29 | svelte:
30 | specifier: ^3.59.2
31 | version: 3.59.2
32 |
33 | packages:
34 |
35 | /@arr/every@1.0.1:
36 | resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==}
37 | engines: {node: '>=4'}
38 | dev: true
39 |
40 | /@polka/url@0.5.0:
41 | resolution: {integrity: sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==}
42 | dev: true
43 |
44 | /@polka/url@1.0.0-next.21:
45 | resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
46 | dev: true
47 |
48 | /@rollup/plugin-node-resolve@9.0.0(rollup@2.79.1):
49 | resolution: {integrity: sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg==}
50 | engines: {node: '>= 10.0.0'}
51 | peerDependencies:
52 | rollup: ^1.20.0||^2.0.0
53 | dependencies:
54 | '@rollup/pluginutils': 3.1.0(rollup@2.79.1)
55 | '@types/resolve': 1.17.1
56 | builtin-modules: 3.3.0
57 | deepmerge: 4.3.1
58 | is-module: 1.0.0
59 | resolve: 1.22.2
60 | rollup: 2.79.1
61 | dev: true
62 |
63 | /@rollup/pluginutils@3.1.0(rollup@2.79.1):
64 | resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
65 | engines: {node: '>= 8.0.0'}
66 | peerDependencies:
67 | rollup: ^1.20.0||^2.0.0
68 | dependencies:
69 | '@types/estree': 0.0.39
70 | estree-walker: 1.0.1
71 | picomatch: 2.3.1
72 | rollup: 2.79.1
73 | dev: true
74 |
75 | /@types/estree@0.0.39:
76 | resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
77 | dev: true
78 |
79 | /@types/node@14.18.54:
80 | resolution: {integrity: sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw==}
81 | dev: true
82 |
83 | /@types/resolve@1.17.1:
84 | resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
85 | dependencies:
86 | '@types/node': 14.18.54
87 | dev: true
88 |
89 | /builtin-modules@3.3.0:
90 | resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
91 | engines: {node: '>=6'}
92 | dev: true
93 |
94 | /console-clear@1.1.1:
95 | resolution: {integrity: sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==}
96 | engines: {node: '>=4'}
97 | dev: true
98 |
99 | /deepmerge@4.3.1:
100 | resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
101 | engines: {node: '>=0.10.0'}
102 | dev: true
103 |
104 | /estree-walker@0.6.1:
105 | resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
106 | dev: true
107 |
108 | /estree-walker@1.0.1:
109 | resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
110 | dev: true
111 |
112 | /fsevents@2.3.2:
113 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
114 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
115 | os: [darwin]
116 | requiresBuild: true
117 | dev: true
118 | optional: true
119 |
120 | /function-bind@1.1.1:
121 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
122 | dev: true
123 |
124 | /get-port@3.2.0:
125 | resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==}
126 | engines: {node: '>=4'}
127 | dev: true
128 |
129 | /has@1.0.3:
130 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
131 | engines: {node: '>= 0.4.0'}
132 | dependencies:
133 | function-bind: 1.1.1
134 | dev: true
135 |
136 | /is-core-module@2.12.1:
137 | resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==}
138 | dependencies:
139 | has: 1.0.3
140 | dev: true
141 |
142 | /is-module@1.0.0:
143 | resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
144 | dev: true
145 |
146 | /kleur@3.0.3:
147 | resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
148 | engines: {node: '>=6'}
149 | dev: true
150 |
151 | /local-access@1.1.0:
152 | resolution: {integrity: sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw==}
153 | engines: {node: '>=6'}
154 | dev: true
155 |
156 | /matchit@1.1.0:
157 | resolution: {integrity: sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==}
158 | engines: {node: '>=6'}
159 | dependencies:
160 | '@arr/every': 1.0.1
161 | dev: true
162 |
163 | /mri@1.2.0:
164 | resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
165 | engines: {node: '>=4'}
166 | dev: true
167 |
168 | /mrmime@1.0.1:
169 | resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==}
170 | engines: {node: '>=10'}
171 | dev: true
172 |
173 | /path-parse@1.0.7:
174 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
175 | dev: true
176 |
177 | /picomatch@2.3.1:
178 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
179 | engines: {node: '>=8.6'}
180 | dev: true
181 |
182 | /polka@0.5.2:
183 | resolution: {integrity: sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==}
184 | dependencies:
185 | '@polka/url': 0.5.0
186 | trouter: 2.0.1
187 | dev: true
188 |
189 | /require-relative@0.8.7:
190 | resolution: {integrity: sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==}
191 | dev: true
192 |
193 | /resolve@1.22.2:
194 | resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
195 | hasBin: true
196 | dependencies:
197 | is-core-module: 2.12.1
198 | path-parse: 1.0.7
199 | supports-preserve-symlinks-flag: 1.0.0
200 | dev: true
201 |
202 | /rollup-plugin-svelte@6.1.1(rollup@2.79.1)(svelte@3.59.2):
203 | resolution: {integrity: sha512-ijnm0pH1ScrY4uxwaNXBpNVejVzpL2769hIEbAlnqNUWZrffLspu5/k9/l/Wsj3NrEHLQ6wCKGagVJonyfN7ow==}
204 | peerDependencies:
205 | rollup: '>=1.19.2'
206 | svelte: '*'
207 | dependencies:
208 | require-relative: 0.8.7
209 | rollup: 2.79.1
210 | rollup-pluginutils: 2.8.2
211 | sourcemap-codec: 1.4.8
212 | svelte: 3.59.2
213 | dev: true
214 |
215 | /rollup-pluginutils@2.8.2:
216 | resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
217 | dependencies:
218 | estree-walker: 0.6.1
219 | dev: true
220 |
221 | /rollup@2.79.1:
222 | resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==}
223 | engines: {node: '>=10.0.0'}
224 | hasBin: true
225 | optionalDependencies:
226 | fsevents: 2.3.2
227 | dev: true
228 |
229 | /sade@1.8.1:
230 | resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
231 | engines: {node: '>=6'}
232 | dependencies:
233 | mri: 1.2.0
234 | dev: true
235 |
236 | /semiver@1.1.0:
237 | resolution: {integrity: sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==}
238 | engines: {node: '>=6'}
239 | dev: true
240 |
241 | /sirv-cli@1.0.14:
242 | resolution: {integrity: sha512-yyUTNr984ANKDloqepkYbBSqvx3buwYg2sQKPWjSU+IBia5loaoka2If8N9CMwt8AfP179cdEl7kYJ//iWJHjQ==}
243 | engines: {node: '>= 10'}
244 | hasBin: true
245 | dependencies:
246 | console-clear: 1.1.1
247 | get-port: 3.2.0
248 | kleur: 3.0.3
249 | local-access: 1.1.0
250 | sade: 1.8.1
251 | semiver: 1.1.0
252 | sirv: 1.0.19
253 | tinydate: 1.3.0
254 | dev: true
255 |
256 | /sirv@1.0.19:
257 | resolution: {integrity: sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==}
258 | engines: {node: '>= 10'}
259 | dependencies:
260 | '@polka/url': 1.0.0-next.21
261 | mrmime: 1.0.1
262 | totalist: 1.1.0
263 | dev: true
264 |
265 | /sourcemap-codec@1.4.8:
266 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
267 | deprecated: Please use @jridgewell/sourcemap-codec instead
268 | dev: true
269 |
270 | /supports-preserve-symlinks-flag@1.0.0:
271 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
272 | engines: {node: '>= 0.4'}
273 | dev: true
274 |
275 | /svelte@3.59.2:
276 | resolution: {integrity: sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==}
277 | engines: {node: '>= 8'}
278 | dev: true
279 |
280 | /tinydate@1.3.0:
281 | resolution: {integrity: sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==}
282 | engines: {node: '>=4'}
283 | dev: true
284 |
285 | /totalist@1.1.0:
286 | resolution: {integrity: sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==}
287 | engines: {node: '>=6'}
288 | dev: true
289 |
290 | /trouter@2.0.1:
291 | resolution: {integrity: sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==}
292 | engines: {node: '>=6'}
293 | dependencies:
294 | matchit: 1.1.0
295 | dev: true
296 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Svelte URL
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import resolve from '@rollup/plugin-node-resolve'
2 | import svelte from 'rollup-plugin-svelte'
3 |
4 | export default [
5 | // SPA
6 | {
7 | input: 'src/main.js',
8 | output: {
9 | format: 'iife',
10 | name: 'app',
11 | file: 'public/build/bundle.js',
12 | },
13 | plugins: [
14 | svelte({
15 | dev: true,
16 | hydratable: true,
17 | css: (css) => {
18 | css.write('bundle.css')
19 | },
20 | }),
21 | resolve({
22 | browser: true,
23 | dedupe: ['svelte'],
24 | }),
25 | ],
26 | },
27 | // SSR
28 | {
29 | input: 'src/App.svelte',
30 | output: {
31 | format: 'cjs',
32 | name: 'app',
33 | file: 'public/build/App.js',
34 | exports: 'named',
35 | },
36 | plugins: [
37 | svelte({
38 | dev: true,
39 | generate: 'ssr',
40 | css: (css) => {
41 | css.write('bundle.css')
42 | },
43 | }),
44 | resolve({
45 | browser: false,
46 | dedupe: ['svelte'],
47 | }),
48 | ],
49 | },
50 | ]
51 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const { URL } = require('url')
3 | const sirv = require('sirv')
4 | const polka = require('polka')
5 | const App = require('./public/build/App').default
6 |
7 | const baseHtml = fs.readFileSync('public/index.html', { encoding: 'utf-8' })
8 |
9 | polka()
10 | .use(sirv('public', { extensions: [] }))
11 | .use((req, res) => {
12 | const { html } = App.render({
13 | props: {
14 | ssrUrl: new URL(req.url, `http://${req.headers.host}`).href
15 | }
16 | })
17 |
18 | const result = baseHtml.replace(
19 | '
',
20 | `${html}
`
21 | )
22 |
23 | res.write(result)
24 | res.end()
25 | })
26 | .listen(3001, (err) => {
27 | if (err) throw err
28 | console.log('Ready at http://localhost:3001')
29 | })
30 |
--------------------------------------------------------------------------------
/src/App.svelte:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 | Home
21 | About
22 | 404
23 |
24 |
25 | {#if $url.pathname === '/'}
26 | Home Sweet Home
27 | {:else if $url.pathname === '/about'}
28 | About What?
29 | {:else}
30 | 404
31 | {/if}
32 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import App from './App.svelte'
2 |
3 | const app = new App({
4 | target: document.getElementById('app'),
5 | hydrate: true,
6 | })
7 |
8 | export default app
9 |
--------------------------------------------------------------------------------
/src/url.js:
--------------------------------------------------------------------------------
1 | import { derived, writable } from 'svelte/store'
2 |
3 | export function createUrlStore(ssrUrl) {
4 | // Ideally a bundler constant so that it's tree-shakable
5 | if (typeof window === 'undefined') {
6 | const { subscribe } = writable(ssrUrl)
7 | return { subscribe }
8 | }
9 |
10 | const href = writable(window.location.href)
11 |
12 | const originalPushState = history.pushState
13 | const originalReplaceState = history.replaceState
14 |
15 | const updateHref = () => href.set(window.location.href)
16 |
17 | history.pushState = function () {
18 | originalPushState.apply(this, arguments)
19 | updateHref()
20 | }
21 |
22 | history.replaceState = function () {
23 | originalReplaceState.apply(this, arguments)
24 | updateHref()
25 | }
26 |
27 | window.addEventListener('popstate', updateHref)
28 | window.addEventListener('hashchange', updateHref)
29 |
30 | return {
31 | subscribe: derived(href, ($href) => new URL($href)).subscribe
32 | }
33 | }
34 |
35 | // If you're using in a pure SPA, you can return a store directly and share it everywhere
36 | // export default createUrlStore()
37 |
--------------------------------------------------------------------------------