mirror of https://github.com/sveltejs/svelte
[feat]: Move svelte.dev here (#8237)
* Push * Remove `rootDir` * Use tsconfig instead of jsconfig * Push recent changes * Better dark mode * empty commit to try and trigger a deploy * bump kit * Fix site-kit dep * Comment out blurb * Update site-kit to 3.2.1 * Externalise sourcemap-codec * Install sourcemap-codec as dep --------- Co-authored-by: Rich Harris <hello@rich-harris.dev>pull/8274/head
parent
952ca44fb1
commit
60806f74b9
@ -0,0 +1,19 @@
|
|||||||
|
# for local development, copy this file to .env.local file and
|
||||||
|
# fill in the blanks
|
||||||
|
|
||||||
|
# server-side
|
||||||
|
GITHUB_CLIENT_ID=
|
||||||
|
GITHUB_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Path to local copy of Svelte relative from sites/svelte.dev. Used by the REPL.
|
||||||
|
# Optional. The default value assumes the svelte repo and sites repo are in the same directory.
|
||||||
|
# LOCAL_SVELTE_PATH=../../../svelte
|
||||||
|
|
||||||
|
# staging database
|
||||||
|
SUPABASE_URL=https://kpaaohfbmxvespqoqdzp.supabase.co
|
||||||
|
SUPABASE_KEY=
|
||||||
|
|
||||||
|
PUBLIC_API_BASE="https://api.svelte.dev"
|
||||||
|
|
||||||
|
# client-side
|
||||||
|
VITE_MAPBOX_ACCESS_TOKEN=
|
@ -0,0 +1,54 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
rules: {
|
||||||
|
indent: [2, 'tab', { SwitchCase: 1 }],
|
||||||
|
semi: [2, 'always'],
|
||||||
|
'keyword-spacing': [2, { before: true, after: true }],
|
||||||
|
'space-before-blocks': [2, 'always'],
|
||||||
|
'no-mixed-spaces-and-tabs': [2, 'smart-tabs'],
|
||||||
|
'no-cond-assign': 0,
|
||||||
|
'no-unused-vars': 2,
|
||||||
|
'object-shorthand': [2, 'always'],
|
||||||
|
'no-const-assign': 2,
|
||||||
|
'no-class-assign': 2,
|
||||||
|
'no-this-before-super': 2,
|
||||||
|
'no-var': 2,
|
||||||
|
'no-unreachable': 2,
|
||||||
|
'valid-typeof': 2,
|
||||||
|
'quote-props': [2, 'as-needed'],
|
||||||
|
'one-var': [2, 'never'],
|
||||||
|
'prefer-arrow-callback': 2,
|
||||||
|
'prefer-const': [2, { destructuring: 'all' }],
|
||||||
|
'arrow-spacing': 2,
|
||||||
|
'no-inner-declarations': 0,
|
||||||
|
'require-atomic-updates': 0
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
es6: true,
|
||||||
|
browser: true,
|
||||||
|
node: true,
|
||||||
|
mocha: true
|
||||||
|
},
|
||||||
|
extends: ['eslint:recommended', 'plugin:import/errors', 'plugin:import/warnings'],
|
||||||
|
plugins: ['svelte3'],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['*.svelte'],
|
||||||
|
processor: 'svelte3/svelte3'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 9,
|
||||||
|
sourceType: 'module'
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
'import/core-modules': ['svelte'],
|
||||||
|
'svelte3/compiler': (() => {
|
||||||
|
try {
|
||||||
|
return require('svelte/compiler');
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
};
|
@ -1,10 +1,11 @@
|
|||||||
.DS_Store
|
/.env.local
|
||||||
node_modules
|
/.svelte-kit/
|
||||||
/build
|
/build/
|
||||||
/.svelte-kit
|
/functions/
|
||||||
/package
|
|
||||||
.env
|
/static/svelte-app.json
|
||||||
.env.*
|
/scripts/svelte-app/
|
||||||
!.env.example
|
/src/routes/_components/Supporters/contributors.jpg
|
||||||
vite.config.js.timestamp-*
|
/src/routes/_components/Supporters/contributors.js
|
||||||
vite.config.ts.timestamp-*
|
/src/routes/_components/Supporters/donors.jpg
|
||||||
|
/src/routes/_components/Supporters/donors.js
|
||||||
|
@ -1 +0,0 @@
|
|||||||
engine-strict=true
|
|
@ -1,13 +0,0 @@
|
|||||||
.DS_Store
|
|
||||||
node_modules
|
|
||||||
/build
|
|
||||||
/.svelte-kit
|
|
||||||
/package
|
|
||||||
.env
|
|
||||||
.env.*
|
|
||||||
!.env.example
|
|
||||||
|
|
||||||
# Ignore files for PNPM, NPM and YARN
|
|
||||||
pnpm-lock.yaml
|
|
||||||
package-lock.json
|
|
||||||
yarn.lock
|
|
@ -1,9 +1,5 @@
|
|||||||
{
|
{
|
||||||
"useTabs": true,
|
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "none",
|
|
||||||
"printWidth": 100,
|
"printWidth": 100,
|
||||||
"plugins": ["prettier-plugin-svelte"],
|
"useTabs": true
|
||||||
"pluginSearchDirs": ["."],
|
|
||||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
|
||||||
}
|
}
|
||||||
|
@ -1,38 +1,69 @@
|
|||||||
# create-svelte
|
## Running locally
|
||||||
|
|
||||||
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
|
A local database is only required in dev mode if you want to test reading and writing saved REPLs on it. Without a local database in dev mode, the REPL will be able to load saved REPLs from the production database, but not save them.
|
||||||
|
|
||||||
## Creating a project
|
Note also that in dev mode, the REPL will currently only work in Chrome, [as noted in the Vite documentation](https://vitejs.dev/guide/features.html#web-workers), pending support in Firefox for `import` statements in web workers.
|
||||||
|
|
||||||
If you're seeing this, you've probably already done this step. Congrats!
|
If you do want to use a database, set it up on [Supabase](https://supabase.com) with the instructions [here](../../db) and set the corresponding environment variables.
|
||||||
|
|
||||||
```bash
|
Run the site sub-project:
|
||||||
# create a new project in the current directory
|
|
||||||
npm create svelte@latest
|
|
||||||
|
|
||||||
# create a new project in my-app
|
```bash
|
||||||
npm create svelte@latest my-app
|
pnpm install
|
||||||
|
pnpm dev
|
||||||
```
|
```
|
||||||
|
|
||||||
## Developing
|
and navigate to [localhost:5173](http://localhost:5173).
|
||||||
|
|
||||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
The first time you run the site locally, it will update the list of Contributors and REPL dependencies. After this it won't run again unless you force it by running:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
pnpm update
|
||||||
|
|
||||||
# or start the server and open the app in a new browser tab
|
|
||||||
npm run dev -- --open
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building
|
## Running using the local copy of Svelte
|
||||||
|
|
||||||
|
By default, the REPL will fetch the most recent version of Svelte from https://unpkg.com/svelte. When running the site locally, you can also use your local copy of Svelte.
|
||||||
|
|
||||||
To create a production version of your app:
|
To produce the proper browser-compatible UMD build of the compiler, you will need to run `npm run build` (or `npm run dev`) in the `svelte` repository with the `PUBLISH` environment variable set to any non-empty string:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run build
|
git clone https://github.com/sveltejs/svelte.git
|
||||||
|
cd svelte
|
||||||
|
npm ci
|
||||||
|
PUBLISH=1 npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
You can preview the production build with `npm run preview`.
|
The default configuration assumes that the `sites` repository and the `svelte` repository are in the same directory. If not, you can set `LOCAL_SVELTE_PATH` in `sites/svelte.dev/.env` to a different path to the local copy of Svelte.
|
||||||
|
|
||||||
|
Then visit the REPL at [localhost:5173/repl?version=local](http://localhost:5173/repl?version=local). Please note that the local REPL only works with `pnpm dev` and not when building the site for production usage.
|
||||||
|
|
||||||
|
## REPL GitHub integration
|
||||||
|
|
||||||
|
In order for the REPL's GitHub integration to work properly when running locally, you will need to:
|
||||||
|
|
||||||
|
- [create a GitHub OAuth app](https://github.com/settings/developers):
|
||||||
|
- set `Authorization callback URL` to `http://localhost:5173/auth/callback`;
|
||||||
|
- set `Application name` as you like, and `Homepage URL` as `http://localhost:5173/`;
|
||||||
|
- create the app and take note of `Client ID` and `Client Secret`
|
||||||
|
- in this directory, create an `.env.local` file (see `.env.example`) containing:
|
||||||
|
```
|
||||||
|
GITHUB_CLIENT_ID=[your app's Client ID]
|
||||||
|
GITHUB_CLIENT_SECRET=[your app's Client Secret]
|
||||||
|
```
|
||||||
|
|
||||||
|
The GitHub app requires a specific callback URL, and so cannot be used with the preview deployment in the staging environment.
|
||||||
|
|
||||||
|
## Building the site
|
||||||
|
|
||||||
|
To build the website, run `pnpm build`. The output can be found in `build`.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Tests can be run using `pnpm test`.
|
||||||
|
|
||||||
|
## Translating the API docs
|
||||||
|
|
||||||
|
Anchors are automatically generated using headings in the documentation and by default (for the english language) they are latinised to make sure the URL is always conforming to RFC3986.
|
||||||
|
|
||||||
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
If we need to translate the API documentation to a language using unicode chars, we can setup this app to export the correct anchors by setting up `SLUG_PRESERVE_UNICODE` to `true` in `config.js`.
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
export const SLUG_PRESERVE_UNICODE = false;
|
||||||
|
export const SLUG_SEPARATOR = '_';
|
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
title: The easiest way to get started with Svelte
|
||||||
|
description: This'll only take a minute.
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/Rich_Harris
|
||||||
|
---
|
||||||
|
|
||||||
|
Svelte is a [new kind of framework](/blog/frameworks-without-the-framework). Rather than putting a `<script src='svelte.js'>` tag on the page, or bringing it into your app with `import` or `require`, Svelte is a compiler that works behind the scenes to turn your component files into beautifully optimised JavaScript.
|
||||||
|
|
||||||
|
Because of that, getting started with it can be a little bit confusing at first. How, you might reasonably ask, do you make a Svelte app?
|
||||||
|
|
||||||
|
|
||||||
|
## 1. Use the REPL
|
||||||
|
|
||||||
|
The [Svelte REPL](/repl) (Read-Eval-Print Loop) is the easiest way to begin. This is an interactive environment that allows you to modify code and instantly see the result.
|
||||||
|
|
||||||
|
You can choose from a list of [examples](/examples/), click the [REPL](/repl) link, and then tweak them until they do what you want.
|
||||||
|
|
||||||
|
<aside><p>You'll need to have <a href="https://nodejs.org/">Node.js</a> installed, and know how to use the terminal</p></aside>
|
||||||
|
|
||||||
|
At some point, your app will outgrow the REPL. Click the **download** button to save a `svelte-app.zip` file to your computer and uncompress it.
|
||||||
|
|
||||||
|
Open a terminal window and set the project up...
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/svelte-app
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
...then start up a development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
This will serve your app on [localhost:8080](http://localhost:8080) and rebuild it with [Rollup](https://rollupjs.org) every time you make a change to the files in `svelte-app/src`.
|
||||||
|
|
||||||
|
## 2. Use degit
|
||||||
|
|
||||||
|
When you download from the REPL, you're getting a customised version of the [sveltejs/template](https://github.com/sveltejs/template) repo. You can skip messing around with zip files by using [degit](https://github.com/Rich-Harris/degit), a project scaffolding tool.
|
||||||
|
|
||||||
|
In the terminal, you can instantly create a new project like so:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx degit sveltejs/template my-svelte-project
|
||||||
|
cd my-svelte-project
|
||||||
|
# to use TypeScript run:
|
||||||
|
# node scripts/setupTypeScript.js
|
||||||
|
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a new project in the `my-svelte-project` directory, install its dependencies, and start a server on http://localhost:8080.
|
||||||
|
|
||||||
|
You can find more information about using TypeScript [here](/blog/svelte-and-typescript).
|
||||||
|
|
||||||
|
Once you've tinkered a bit and understood how everything fits together, you can fork [sveltejs/template](https://github.com/sveltejs/template) and start doing this instead:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx degit your-name/template my-new-project
|
||||||
|
```
|
||||||
|
|
||||||
|
And that's it! Do `npm run build` to create a production-ready version of your app, and check the project template's [README](https://github.com/sveltejs/template/blob/master/README.md) for instructions on how to easily deploy your app to the web with [Vercel](https://vercel.com) or [Surge](http://surge.sh/).
|
||||||
|
|
||||||
|
You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) (Update from 2019: with Svelte 3 the CLI was deprecated and we now use [sirv-cli](https://www.npmjs.com/package/sirv-cli) in our template. Feel free to use whatever tool you like!) or the [API](https://github.com/sveltejs/svelte/tree/v2#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](https://svelte.dev/chat), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!
|
@ -0,0 +1,80 @@
|
|||||||
|
---
|
||||||
|
title: 'Sapper: Towards the ideal web app framework'
|
||||||
|
description: Taking the next-plus-one step
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/Rich_Harris
|
||||||
|
---
|
||||||
|
|
||||||
|
> Quickstart for the impatient: [the Sapper docs](https://sapper.svelte.dev), and the [starter template](https://github.com/sveltejs/sapper-template)
|
||||||
|
|
||||||
|
If you had to list the characteristics of the perfect Node.js web application framework, you'd probably come up with something like this:
|
||||||
|
|
||||||
|
1. It should do server-side rendering, for fast initial loads and no caveats around SEO
|
||||||
|
2. As a corollary, your app's codebase should be universal — write once for server _and_ client
|
||||||
|
3. The client-side app should _hydrate_ the server-rendered HTML, attaching event listeners (and so on) to existing elements rather than re-rendering them
|
||||||
|
4. Navigating to subsequent pages should be instantaneous
|
||||||
|
5. Offline, and other Progressive Web App characteristics, must be supported out of the box
|
||||||
|
6. Only the JavaScript and CSS required for the first page should load initially. That means the framework should do automatic code-splitting at the route level, and support dynamic `import(...)` for more granular manual control
|
||||||
|
7. No compromise on performance
|
||||||
|
8. First-rate developer experience, with hot module reloading and all the trimmings
|
||||||
|
9. The resulting codebase should be easy to grok and maintain
|
||||||
|
10. It should be possible to understand and customise every aspect of the system — no webpack configs locked up in the framework, and as little hidden 'plumbing' as possible
|
||||||
|
11. Learning the entire framework in under an hour should be easy, and not just for experienced developers
|
||||||
|
|
||||||
|
[Next.js](https://github.com/zeit/next.js) is close to this ideal. If you haven't encountered it yet, I strongly recommend going through the tutorials at [learnnextjs.com](https://learnnextjs.com). Next introduced a brilliant idea: all the pages of your app are files in a `your-project/pages` directory, and each of those files is just a React component.
|
||||||
|
|
||||||
|
Everything else flows from that breakthrough design decision. Finding the code responsible for a given page is easy, because you can just look at the filesystem rather than playing 'guess the component name'. Project structure bikeshedding is a thing of the past. And the combination of SSR (server-side rendering) and code-splitting — something the React Router team [gave up on](https://reacttraining.com/react-router/web/guides/code-splitting), declaring 'Godspeed those who attempt the server-rendered, code-split apps' — is trivial.
|
||||||
|
|
||||||
|
But it's not perfect. As churlish as it might be to list the flaws in something _so, so good_, there are some:
|
||||||
|
|
||||||
|
- Next uses something called 'route masking' to create nice URLs (e.g. `/blog/hello-world` instead of `/post?slug=hello-world`). This undermines the guarantee about directory structure corresponding to app structure, and forces you to maintain configuration that translates between the two forms
|
||||||
|
- All your routes are assumed to be universal 'pages'. But it's very common to need routes that only render on the server, such as a 301 redirect or an API endpoint that serves the data for your pages, and Next doesn't have a great solution for this. You can add logic to your `server.js` file to handle these cases, but it feels at odds with the declarative approach taken for pages
|
||||||
|
- To use the client-side router, links can't be standard `<a>` tags. Instead, you have to use framework-specific `<Link>` components, which is impossible in the markdown content for a blog post such as this one, for example
|
||||||
|
|
||||||
|
The real problem, though, is that all that goodness comes for a price. The simplest possible Next app — a single 'hello world' page that renders some static text — involves 66kb of gzipped JavaScript. Unzipped, it's 204kb, which is a non-trivial amount of code for a mobile device to parse at a time when performance is a critical factor determining whether or not your users will stick around. And that's the _baseline_.
|
||||||
|
|
||||||
|
We can do better!
|
||||||
|
|
||||||
|
## The compiler-as-framework paradigm shift
|
||||||
|
|
||||||
|
[Svelte introduced a radical idea](/blog/frameworks-without-the-framework): what if your UI framework wasn't a framework at all, but a compiler that turned your components into standalone JavaScript modules? Instead of using a library like React or Vue, which knows nothing about your app and must therefore be a one-size-fits-all solution, we can ship highly-optimised vanilla JavaScript. Just the code your app needs, and without the memory and performance overhead of solutions based on a virtual DOM.
|
||||||
|
|
||||||
|
The JavaScript world is [moving towards this model](https://tomdale.net/2017/09/compilers-are-the-new-frameworks/). [Stencil](https://stenciljs.com), a Svelte-inspired framework from the Ionic team, compiles to web components. [Glimmer](https://glimmerjs.com) _doesn't_ compile to standalone JavaScript (the pros and cons of which deserve a separate blog post), but the team is doing some fascinating research around compiling templates to bytecode. (React is [getting in on the action](https://twitter.com/trueadm/status/944908776896978946), though their current research focuses on optimising your JSX app code, which is arguably more similar to the ahead-of-time optimisations that Angular, Ractive and Vue have been doing for a few years.)
|
||||||
|
|
||||||
|
What happens if we use the new model as a starting point?
|
||||||
|
|
||||||
|
## Introducing Sapper
|
||||||
|
|
||||||
|
<aside><p>The <a href="https://sapper.svelte.dev/docs#Why_the_name">name comes from</a> the term for combat engineers, and is also short for Svelte app maker</p></aside>
|
||||||
|
|
||||||
|
[Sapper](https://sapper.svelte.dev) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise.
|
||||||
|
|
||||||
|
The same 'hello world' app that took 204kb with React and Next weighs just 7kb with Sapper. That number is likely to fall further in the future as we explore the space of optimisation possibilities, such as not shipping any JavaScript _at all_ for pages that aren't interactive, beyond the tiny Sapper runtime that handles client-side routing.
|
||||||
|
|
||||||
|
What about a more 'real world' example? Conveniently, the [RealWorld](https://github.com/gothinkster/realworld) project, which challenges frameworks to develop an implementation of a Medium clone, gives us a way to find out. The [Sapper implementation](https://github.com/sveltejs/realworld) takes 39.6kb (11.8kb zipped) to render an interactive homepage.
|
||||||
|
|
||||||
|
<aside><p>Code-splitting isn't free — if the reference implementation used code-splitting, it would be larger still</p></aside>
|
||||||
|
|
||||||
|
The entire app costs 132.7kb (39.9kb zipped), which is significantly smaller than the reference React/Redux implementation at 327kb (85.7kb), but even if it was as large it would _feel_ faster because of code-splitting. And that's a crucial point. We're told we need to code-split our apps, but if your app uses a traditional framework like React or Vue then there's a hard lower bound on the size of your initial code-split chunk — the framework itself, which is likely to be a significant portion of your total app size. With the Svelte approach, that's no longer the case.
|
||||||
|
|
||||||
|
But size is only part of the story. Svelte apps are also extremely performant and memory-efficient, and the framework includes powerful features that you would sacrifice if you chose a 'minimal' or 'simple' UI library.
|
||||||
|
|
||||||
|
## Trade-offs
|
||||||
|
|
||||||
|
The biggest drawback for many developers evaluating Sapper would be 'but I like React, and I already know how to use it', which is fair.
|
||||||
|
|
||||||
|
If you're in that camp, I'd invite you to at least try alternative frameworks. You might be pleasantly surprised! The [Sapper RealWorld](https://github.com/sveltejs/realworld) implementation totals 1,201 lines of source code, compared to 2,377 for the reference implementation, because you're able to express concepts very concisely using Svelte's template syntax (which [takes all of five minutes to master](https://v2.svelte.dev/guide#template-syntax)). You get [scoped CSS](/blog/the-zen-of-just-writing-css), with unused style removal and minification built-in, and you can use preprocessors like LESS if you want. You no longer need to use Babel. SSR is ridiculously fast, because it's just string concatenation. And we recently introduced [svelte/store](https://v2.svelte.dev/guide#state-management), a tiny global store that synchronises state across your component hierarchy with zero boilerplate. The worst that can happen is that you'll end up feeling vindicated!
|
||||||
|
|
||||||
|
But there are trade-offs nonetheless. Some people have a pathological aversion to any form of 'template language', and maybe that applies to you. JSX proponents will clobber you with the 'it's just JavaScript' mantra, and therein lies React's greatest strength, which is that it is infinitely flexible. That flexibility comes with its own set of trade-offs, but we're not here to discuss those.
|
||||||
|
|
||||||
|
And then there's _ecosystem_. The universe around React in particular — the devtools, editor integrations, ancillary libraries, tutorials, StackOverflow answers, hell, even job opportunities — is unrivalled. While it's true that citing 'ecosystem' as the main reason to choose a tool is a sign that you're stuck on a local maximum, apt to be marooned by the rising waters of progress, it's still a major point in favour of incumbents.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
We're not at version 1.0.0 yet, and a few things may change before we get there. Once we do (soon!), there are a lot of exciting possibilities.
|
||||||
|
|
||||||
|
I believe the next frontier of web performance is 'whole-app optimisation'. Currently, Svelte's compiler operates at the component level, but a compiler that understood the boundaries _between_ those components could generate even more efficient code. The React team's [Prepack research](https://twitter.com/trueadm/status/944908776896978946) is predicated on a similar idea, and the Glimmer team is doing some interesting work in this space. Svelte and Sapper are well positioned to take advantage of these ideas.
|
||||||
|
|
||||||
|
Speaking of Glimmer, the idea of compiling components to bytecode is one that we'll probably steal in 2018. A framework like Sapper could conceivably determine which compilation mode to use based on the characteristics of your app. It could even serve JavaScript for the initial route for the fastest possible startup time, then lazily serve a bytecode interpreter for subsequent routes, resulting in the optimal combination of startup size and total app size.
|
||||||
|
|
||||||
|
Mostly, though, we want the direction of Sapper to be determined by its users. If you're the kind of developer who enjoys life on the bleeding edge and would like to help shape the future of how we build web apps, please join us on [GitHub](https://github.com/sveltejs/svelte) and [Discord](https://svelte.dev/chat).
|
@ -0,0 +1,204 @@
|
|||||||
|
---
|
||||||
|
title: Svelte v2 is out!
|
||||||
|
description: Here's what you need to know
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/Rich_Harris
|
||||||
|
---
|
||||||
|
|
||||||
|
<aside>Our motto is 'move slowly and break things'. No, wait, that came out wrong...</aside>
|
||||||
|
|
||||||
|
Almost a year after we first started talking about version 2 on the Svelte issue tracker, it's finally time to make some breaking changes. This blog post will explain what changed, why it changed, and what you need to do to bring your apps up to date.
|
||||||
|
|
||||||
|
|
||||||
|
## tl;dr
|
||||||
|
|
||||||
|
Each of these items is described in more depth below. If you get stuck, ask for help in our friendly [Discord chatroom](https://svelte.dev/chat).
|
||||||
|
|
||||||
|
- Install Svelte v2 from npm
|
||||||
|
- Upgrade your templates with [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade)
|
||||||
|
- Remove calls to `component.observe`, or add the `observe` method from [svelte-extras](https://github.com/sveltejs/svelte-extras)
|
||||||
|
- Rewrite calls to `component.get('foo')` as `component.get().foo`
|
||||||
|
- Return `destroy` from your custom event handlers, rather than `teardown`
|
||||||
|
- Make sure you're not passing numeric string props to components
|
||||||
|
|
||||||
|
|
||||||
|
## New template syntax
|
||||||
|
|
||||||
|
The most visible change: we've made some improvements to the template syntax.
|
||||||
|
|
||||||
|
A common piece of feedback we heard was 'ewww, Mustache' or 'ewww, Handlebars'. A lot of people who used string-based templating systems in a previous era of web development *really* dislike them. Because Svelte adopted the `{{curlies}}` from those languages, a lot of people assumed that we somehow shared the limitations of those tools, such as weird scoping rules or an inability to use arbitrary JavaScript expressions.
|
||||||
|
|
||||||
|
<aside>If you need to show an actual `{` character, it's as easy as `&#123;`</aside>
|
||||||
|
|
||||||
|
Beyond that, JSX proved that double curlies are unnecessary. So we've made our templates more... svelte, by adopting single curlies. The result feels much lighter to look at and is more pleasant to type:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h1>Hello {name}!</h1>
|
||||||
|
```
|
||||||
|
|
||||||
|
There are a few other updates. But you don't need to make them manually — just run [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade) on your codebase:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx svelte-upgrade v2 src
|
||||||
|
```
|
||||||
|
|
||||||
|
This assumes any `.html` files in `src` are Svelte components. You can specify whichever directory you like, or target a different directory — for example, you'd do `npx svelte-upgrade v2 routes` to update a [Sapper](https://sapper.svelte.technology) app.
|
||||||
|
|
||||||
|
To see the full set of changes, consult the [svelte-upgrade README](https://github.com/sveltejs/svelte-upgrade#svelte-v2-syntax-changes).
|
||||||
|
|
||||||
|
|
||||||
|
## Computed properties
|
||||||
|
|
||||||
|
Another thing that people often found confusing about Svelte is the way computed properties work. To recap, if you had a component with this...
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
d: (a, b, c) => a = b + c
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
...then Svelte would first look at the function arguments to see which values `d` depended on, and then it would write code that updated `d` whenever those values changed, by injecting them into the function. That's cool, because it allows you to derive complex values from your component's inputs without worrying about when they need to recomputed, but it's also... *weird*. JavaScript doesn't work that way!
|
||||||
|
|
||||||
|
In v2, we use [destructuring](http://www.jstips.co/en/javascript/use-destructuring-in-function-parameters/) instead:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
d: ({ a, b, c }) => a = b + c
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
The Svelte compiler can still see which values `d` depends on, but it's no longer injecting values — it just passes the component state object into each computed property.
|
||||||
|
|
||||||
|
Again, you don't need to make this change manually — just run svelte-upgrade on your components, as shown above.
|
||||||
|
|
||||||
|
|
||||||
|
## Sorry, IE11. It's not you, it's... well actually, yeah. It's you
|
||||||
|
|
||||||
|
Svelte v1 was careful to only emit ES5 code, so that you wouldn't be forced to faff around with transpilers in order to use it. But it's 2018 now, and almost all browsers support modern JavaScript. By ditching the ES5 constraint, we can generate leaner code.
|
||||||
|
|
||||||
|
If you need to support IE11 and friends, you will need to use a transpiler like [Babel](https://babeljs.io/repl) or [Bublé](https://buble.surge.sh/).
|
||||||
|
|
||||||
|
|
||||||
|
## New lifecycle hooks
|
||||||
|
|
||||||
|
In addition to `oncreate` and `ondestroy`, Svelte v2 adds two more [lifecycle hooks](https://v2.svelte.dev/guide#lifecycle-hooks) for responding to state changes:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
onstate({ changed, current, previous }) {
|
||||||
|
// this fires before oncreate, and
|
||||||
|
// whenever state changes
|
||||||
|
},
|
||||||
|
|
||||||
|
onupdate({ changed, current, previous }) {
|
||||||
|
// this fires after oncreate, and
|
||||||
|
// whenever the DOM has been updated
|
||||||
|
// following a state change
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also listen to those events programmatically:
|
||||||
|
|
||||||
|
```js
|
||||||
|
component.on('state', ({ changed, current, previous }) => {
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## component.observe
|
||||||
|
|
||||||
|
With the new lifecycle hooks, we no longer need the `component.observe(...)` method:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// before
|
||||||
|
export default {
|
||||||
|
oncreate() {
|
||||||
|
this.observe('foo', foo => {
|
||||||
|
console.log(`foo is now ${foo}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// after
|
||||||
|
export default {
|
||||||
|
onstate({ changed, current }) {
|
||||||
|
if (changed.foo) {
|
||||||
|
console.log(`foo is now ${current.foo}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
This shrinks the amount of code Svelte needs to generate, and gives you more flexibility. For example, it's now very easy to take action when any one of *several* properties have changed, such as redrawing a canvas without debouncing several observers.
|
||||||
|
|
||||||
|
However, if you prefer to use `component.observe(...)`, then you can install it from [svelte-extras](https://github.com/sveltejs/svelte-extras):
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { observe } from 'svelte-extras';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
observe
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## component.get
|
||||||
|
|
||||||
|
This method no longer takes an optional `key` argument — instead, it always returns the entire state object:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// before
|
||||||
|
const foo = this.get('foo');
|
||||||
|
const bar = this.get('bar');
|
||||||
|
|
||||||
|
// after
|
||||||
|
const { foo, bar } = this.get();
|
||||||
|
```
|
||||||
|
|
||||||
|
This change might seem annoying initially, but it's the right move: among other things, it's likely to play better with type systems as we explore that space more fully in future.
|
||||||
|
|
||||||
|
|
||||||
|
## event_handler.destroy
|
||||||
|
|
||||||
|
If your app has [custom event handlers](https://v2.svelte.dev/guide#custom-event-handlers), they must return an object with a `destroy` method, *not* a `teardown` method (this aligns event handlers with the component API).
|
||||||
|
|
||||||
|
|
||||||
|
## No more type coercion
|
||||||
|
|
||||||
|
Previously, numeric values passed to components were treated as numbers:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<Counter start='1'/>
|
||||||
|
```
|
||||||
|
|
||||||
|
That causes unexpected behaviour, and has been changed: if you need to pass a literal number, do so as an expression:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<Counter start={1}/>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Compiler changes
|
||||||
|
|
||||||
|
In most cases you'll never need to deal with the compiler directly, so this shouldn't require any action on your part. It's worth noting anyway: the compiler API has changed. Instead of an object with a mish-mash of properties, the compiler now returns `js`, `css`, `ast` and `stats`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { js, css, ast, stats } = svelte.compile(source, options);
|
||||||
|
```
|
||||||
|
|
||||||
|
`js` and `css` are both `{ code, map }` objects, where `code` is a string and `map` is a sourcemap. The `ast` is an abstract syntax tree of your component, and the `stats` object contains metadata about the component, and information about the compilation.
|
||||||
|
|
||||||
|
Before, there was a `svelte.validate` method which checked your component was valid. That's been removed — if you want to check a component without actually compiling it, just pass the `generate: false` option.
|
||||||
|
|
||||||
|
|
||||||
|
## My app is broken! Help!
|
||||||
|
|
||||||
|
Hopefully this covers everything, and the update should be easier for you than it was for us. But if you find bugs, or discover things that aren't mentioned here, swing by [Discord chatroom](https://svelte.dev/chat) or raise an issue on the [tracker](https://github.com/sveltejs/svelte/issues).
|
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
title: Using CSS-in-JS with Svelte
|
||||||
|
description: You don't need to, but you can
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/Rich_Harris
|
||||||
|
---
|
||||||
|
|
||||||
|
CSS is a core part of any web app. By extension, a UI framework that doesn't have a built-in way to add styles to your components is unfinished.
|
||||||
|
|
||||||
|
That's why Svelte allows you to add CSS in a component's `<style>` tag. Co-locating your CSS with your markup means we can [solve the biggest problems developers face when writing CSS](/blog/the-zen-of-just-writing-css) without introducing new ones, all while providing a rather nice development experience.
|
||||||
|
|
||||||
|
But Svelte's style handling does have some limitations. It's too difficult to share styles between components, or apply app-level optimisations. These are areas we plan to address in future versions, but in the meantime if you need those things you can use any framework-agnostic CSS-in-JS library.
|
||||||
|
|
||||||
|
|
||||||
|
## For example
|
||||||
|
|
||||||
|
Here, we're using [Emotion](https://emotion.sh) to generate scoped class names that can be used across multiple components:
|
||||||
|
|
||||||
|
<div class="max">
|
||||||
|
<iframe
|
||||||
|
title="Aphrodite example"
|
||||||
|
src="/repl/embed?example=blog-svelte-css-in-js"
|
||||||
|
scrolling="no"
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
It's important to note that most CSS-in-JS libraries have a runtime library, and many don't support statically extracting styles out into a separate <code>.css</code> file at build time (which is essential for the best performance). You should therefore only use CSS-in-JS if it's necessary for your application!
|
||||||
|
|
||||||
|
Note that you can mix-and-match — you can still use Svelte's built-in CSS handling alongside a CSS-in-JS library.
|
@ -0,0 +1,149 @@
|
|||||||
|
---
|
||||||
|
title: Virtual DOM is pure overhead
|
||||||
|
description: Let's retire the 'virtual DOM is fast' myth once and for all
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/Rich_Harris
|
||||||
|
---
|
||||||
|
|
||||||
|
If you've used JavaScript frameworks in the last few years, you've probably heard the phrase 'the virtual DOM is fast', often said to mean that it's faster than the *real* DOM. It's a surprisingly resilient meme — for example people have asked how Svelte can be fast when it doesn't use a virtual DOM.
|
||||||
|
|
||||||
|
It's time to take a closer look.
|
||||||
|
|
||||||
|
|
||||||
|
## What is the virtual DOM?
|
||||||
|
|
||||||
|
In many frameworks, you build an app by creating `render()` functions, like this simple [React](https://reactjs.org/) component:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function HelloMessage(props) {
|
||||||
|
return (
|
||||||
|
<div className="greeting">
|
||||||
|
Hello {props.name}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can do the same thing without JSX...
|
||||||
|
|
||||||
|
```js
|
||||||
|
function HelloMessage(props) {
|
||||||
|
return React.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'greeting' },
|
||||||
|
'Hello ',
|
||||||
|
props.name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
...but the result is the same — an object representing how the page should now look. That object is the virtual DOM. Every time your app's state updates (for example when the `name` prop changes), you create a new one. The framework's job is to *reconcile* the new one against the old one, to figure out what changes are necessary and apply them to the real DOM.
|
||||||
|
|
||||||
|
|
||||||
|
## How did the meme start?
|
||||||
|
|
||||||
|
Misunderstood claims about virtual DOM performance date back to the launch of React. In [Rethinking Best Practices](https://www.youtube.com/watch?v=x7cQ3mrcKaY), a seminal 2013 talk by former React core team member Pete Hunt, we learned the following:
|
||||||
|
|
||||||
|
> This is actually extremely fast, primarily because most DOM operations tend to be slow. There's been a lot of performance work on the DOM, but most DOM operations tend to drop frames.
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
<img alt="Pete Hunt at JSConfEU 2013" src="/media/rethinking-best-practices.jpg">
|
||||||
|
<figcaption>Screenshot from <a href="https://www.youtube.com/watch?v=x7cQ3mrcKaY">Rethinking Best Practices</a> at JSConfEU 2013</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
But hang on a minute! The virtual DOM operations are *in addition to* the eventual operations on the real DOM. The only way it could be faster is if we were comparing it to a less efficient framework (there were plenty to go around back in 2013!), or arguing against a straw man — that the alternative is to do something no-one actually does:
|
||||||
|
|
||||||
|
```js
|
||||||
|
onEveryStateChange(() => {
|
||||||
|
document.body.innerHTML = renderMyApp();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Pete clarifies soon after...
|
||||||
|
|
||||||
|
> React is not magic. Just like you can drop into assembler with C and beat the C compiler, you can drop into raw DOM operations and DOM API calls and beat React if you wanted to. However, using C or Java or JavaScript is an order of magnitude performance improvement because you don't have to worry...about the specifics of the platform. With React you can build applications without even thinking about performance and the default state is fast.
|
||||||
|
|
||||||
|
...but that's not the part that stuck.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## So... is the virtual DOM *slow*?
|
||||||
|
|
||||||
|
Not exactly. It's more like 'the virtual DOM is usually fast enough', but with certain caveats.
|
||||||
|
|
||||||
|
The original promise of React was that you could re-render your entire app on every single state change without worrying about performance. In practice, I don't think that's turned out to be accurate. If it was, there'd be no need for optimisations like `shouldComponentUpdate` (which is a way of telling React when it can safely skip a component).
|
||||||
|
|
||||||
|
Even with `shouldComponentUpdate`, updating your entire app's virtual DOM in one go is a lot of work. A while back, the React team introduced something called React Fiber which allows the update to be broken into smaller chunks. This means (among other things) that updates don't block the main thread for long periods of time, though it doesn't reduce the total amount of work or the time an update takes.
|
||||||
|
|
||||||
|
|
||||||
|
## Where does the overhead come from?
|
||||||
|
|
||||||
|
Most obviously, [diffing isn't free](https://twitter.com/pcwalton/status/1015694528857047040). You can't apply changes to the real DOM without first comparing the new virtual DOM with the previous snapshot. To take the earlier `HelloMessage` example, suppose the `name` prop changed from 'world' to 'everybody'.
|
||||||
|
|
||||||
|
1. Both snapshots contain a single element. In both cases it's a `<div>`, which means we can keep the same DOM node
|
||||||
|
2. We enumerate all the attributes on the old `<div>` and the new one to see if any need to be changed, added or removed. In both cases we have a single attribute — a `className` with a value of `"greeting"`
|
||||||
|
3. Descending into the element, we see that the text has changed, so we'll need to update the real DOM
|
||||||
|
|
||||||
|
Of these three steps, only the third has value in this case, since — as is the case in the vast majority of updates — the basic structure of the app is unchanged. It would be much more efficient if we could skip straight to step 3:
|
||||||
|
|
||||||
|
```js
|
||||||
|
if (changed.name) {
|
||||||
|
text.data = name;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
(This is almost exactly the update code that Svelte generates. Unlike traditional UI frameworks, Svelte is a compiler that knows at *build time* how things could change in your app, rather than waiting to do the work at *run time*.)
|
||||||
|
|
||||||
|
|
||||||
|
## It's not just the diffing though
|
||||||
|
|
||||||
|
The diffing algorithms used by React and other virtual DOM frameworks are fast. Arguably, the greater overhead is in the components themselves. You wouldn't write code like this...
|
||||||
|
|
||||||
|
```js
|
||||||
|
function StrawManComponent(props) {
|
||||||
|
const value = expensivelyCalculateValue(props.foo);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p>the value is {value}</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
...because you'd be carelessly recalculating `value` on every update, regardless of whether `props.foo` had changed. But it's extremely common to do unnecessary computation and allocation in ways that seem much more benign:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function MoreRealisticComponent(props) {
|
||||||
|
const [selected, setSelected] = useState(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>Selected {selected ? selected.name : 'nothing'}</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{props.items.map(item =>
|
||||||
|
<li>
|
||||||
|
<button onClick={() => setSelected(item)}>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, we're generating a new array of virtual `<li>` elements — each with their own inline event handler — on every state change, regardless of whether `props.items` has changed. Unless you're unhealthily obsessed with performance, you're not going to optimise that. There's no point. It's plenty fast enough. But you know what would be even faster? *Not doing that.*
|
||||||
|
|
||||||
|
<aside><p><a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a> doubles down on defaulting to doing unnecessary work, with <a href="https://twitter.com/thekitze/status/1078582382201131008">predictable results</a>.</p></aside>
|
||||||
|
|
||||||
|
The danger of defaulting to doing unnecessary work, even if that work is trivial, is that your app will eventually succumb to 'death by a thousand cuts' with no clear bottleneck to aim at once it's time to optimise.
|
||||||
|
|
||||||
|
Svelte is explicitly designed to prevent you from ending up in that situation.
|
||||||
|
|
||||||
|
|
||||||
|
## Why do frameworks use the virtual DOM then?
|
||||||
|
|
||||||
|
It's important to understand that virtual DOM *isn't a feature*. It's a means to an end, the end being declarative, state-driven UI development. Virtual DOM is valuable because it allows you to build apps without thinking about state transitions, with performance that is *generally good enough*. That means less buggy code, and more time spent on creative tasks instead of tedious ones.
|
||||||
|
|
||||||
|
But it turns out that we can achieve a similar programming model without using virtual DOM — and that's where Svelte comes in.
|
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
title: Setting up your editor
|
||||||
|
description: Instructions for configuring linting and syntax highlighting
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/Rich_Harris
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
||||||
|
*__Coming soon__*
|
||||||
|
|
||||||
|
This post will walk you through setting up your editor so that it recognises Svelte files:
|
||||||
|
|
||||||
|
* eslint-plugin-svelte3
|
||||||
|
* svelte-vscode
|
||||||
|
* associating .svelte files with HTML in VSCode, Sublime, etc.
|
||||||
|
|
||||||
|
## Atom
|
||||||
|
|
||||||
|
To treat `*.svelte` files as HTML, open *__Edit → Config...__* and add the following lines to your `core` section:
|
||||||
|
|
||||||
|
```cson
|
||||||
|
"*":
|
||||||
|
core:
|
||||||
|
…
|
||||||
|
customFileTypes:
|
||||||
|
"text.html.basic": [
|
||||||
|
"svelte"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Vim/Neovim
|
||||||
|
|
||||||
|
You can use the [coc-svelte extension](https://github.com/coc-extensions/coc-svelte) which utilises the official language-server.
|
||||||
|
|
||||||
|
As an alternative you can treat all `*.svelte` files as HTML. Add the following line to your `init.vim`:
|
||||||
|
|
||||||
|
```
|
||||||
|
au! BufNewFile,BufRead *.svelte set ft=html
|
||||||
|
```
|
||||||
|
|
||||||
|
To temporarily turn on HTML syntax highlighting for the current buffer, use:
|
||||||
|
|
||||||
|
```
|
||||||
|
:set ft=html
|
||||||
|
```
|
||||||
|
|
||||||
|
To set the filetype for a single file, use a [modeline](https://vim.fandom.com/wiki/Modeline_magic):
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- vim: set ft=html :-->
|
||||||
|
```
|
||||||
|
|
||||||
|
## Visual Studio Code
|
||||||
|
|
||||||
|
We recommend using the official [Svelte for VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
|
||||||
|
|
||||||
|
## JetBrains WebStorm
|
||||||
|
|
||||||
|
The [Svelte Framework Integration](https://plugins.jetbrains.com/plugin/12375-svelte/) can be used to add support for Svelte to WebStorm, or other Jetbrains IDEs. Consult the [WebStorm plugin installation guide](https://www.jetbrains.com/help/webstorm/managing-plugins.html) on the JetBrains website for more details.
|
||||||
|
|
||||||
|
## Sublime Text 3
|
||||||
|
|
||||||
|
Open any `.svelte` file.
|
||||||
|
|
||||||
|
Go to *__View → Syntax → Open all with current extension as... → HTML__*.
|
@ -0,0 +1,100 @@
|
|||||||
|
---
|
||||||
|
title: Svelte for new developers
|
||||||
|
description: Never used Node.js or the command line? No problem
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/Rich_Harris
|
||||||
|
---
|
||||||
|
|
||||||
|
This short guide is designed to help you — someone who has looked at the [tutorial](/tutorial) and wants to start creating Svelte apps, but doesn't have a ton of experience using JavaScript build tooling — get up and running.
|
||||||
|
|
||||||
|
If there are things that don't make sense, or that we're glossing over, feel free to [raise an issue](https://github.com/sveltejs/svelte/issues) or [suggest edits to this page](https://github.com/sveltejs/svelte/blob/master/site/content/blog/2019-04-16-svelte-for-new-developers.md) that will help us help more people.
|
||||||
|
|
||||||
|
If you get stuck at any point following this guide, the best place to ask for help is in the [chatroom](https://svelte.dev/chat).
|
||||||
|
|
||||||
|
|
||||||
|
## First things first
|
||||||
|
|
||||||
|
You'll be using the *command line*, also known as the terminal. On Windows, you can access it by running **Command Prompt** from the Start menu; on a Mac, hit `Cmd` and `Space` together to bring up **Spotlight**, then start typing `Terminal.app`. On most Linux systems, `Ctrl-Alt-T` brings up the command line.
|
||||||
|
|
||||||
|
The command line is a way to interact with your computer (or another computer! but that's a topic for another time) with more power and control than the GUI (graphical user interface) that most people use day-to-day.
|
||||||
|
|
||||||
|
Once on the command line, you can navigate the filesystem using `ls` (`dir` on Windows) to list the contents of your current directory, and `cd` to change the current directory. For example, if you had a `Development` directory of your projects inside your home directory, you would type
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd Development
|
||||||
|
```
|
||||||
|
|
||||||
|
to go to it. From there, you could create a new project directory with the `mkdir` command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir svelte-projects
|
||||||
|
cd svelte-projects
|
||||||
|
```
|
||||||
|
|
||||||
|
A full introduction to the command line is out of the scope of this guide, but here are a few more useful commands:
|
||||||
|
|
||||||
|
* `cd ..` — navigates to the parent of the current directory
|
||||||
|
* `cat my-file.txt` — on Mac/Linux (`type my-file.txt` on Windows), lists the contents of `my-file.txt`
|
||||||
|
* `open .` (or `start .` on Windows) — opens the current directory in Finder or File Explorer
|
||||||
|
|
||||||
|
|
||||||
|
## Installing Node.js
|
||||||
|
|
||||||
|
[Node](https://nodejs.org/en/) is a way to run JavaScript on the command line. It's used by many tools, including Svelte. If you don't yet have it installed, the easiest way is to download the latest version straight from the [website](https://nodejs.org/en/).
|
||||||
|
|
||||||
|
Once installed, you'll have access to three new commands:
|
||||||
|
|
||||||
|
* `node my-file.js` — runs the JavaScript in `my-file.js`
|
||||||
|
* `npm [subcommand]` — [npm](https://www.npmjs.com/) is a way to install 'packages' that your application depends on, such as the [svelte](https://www.npmjs.com/package/svelte) package
|
||||||
|
* `npx [subcommand]` — a convenient way to run programs available on npm without permanently installing them
|
||||||
|
|
||||||
|
|
||||||
|
## Installing a text editor
|
||||||
|
|
||||||
|
To write code, you need a good editor. The most popular choice is [Visual Studio Code](https://code.visualstudio.com/) or VSCode, and justifiably so — it's well-designed and fully-featured, and has a wealth of extensions ([including one for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which provides syntax highlighting and diagnostic messages when you're writing components).
|
||||||
|
|
||||||
|
|
||||||
|
## Creating a project
|
||||||
|
|
||||||
|
We're going to use the [Svelte + Vite](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-svelte) template. You don't have to use a project template, but it means you have to do a lot less setup work.
|
||||||
|
|
||||||
|
On the command line, navigate to where you want to create a new project, then type the following lines (you can paste the whole lot, but you'll develop better muscle memory if you get into the habit of writing each line out one at a time then running it):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm create vite@latest my-svelte-project -- --template svelte
|
||||||
|
cd my-svelte-project
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
> You can replace `--template svelte` with `--template svelte-ts`, if you prefer TypeScript.
|
||||||
|
|
||||||
|
This creates a new directory, `my-svelte-project`, adds files from the [create-vite/template-svelte](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-svelte) template, and installs a number of packages from npm. Open the directory in your text editor and take a look around. The app's 'source code' lives in the `src` directory, while the files your app can load are in `public`.
|
||||||
|
|
||||||
|
In the `package.json` file, there is a section called `"scripts"`. These scripts define shortcuts for working with your application — `dev`, `build` and `preview`. To launch your app in development mode, type the following:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Running the `dev` script starts a program called [Vite](https://vitejs.dev/). Vite's job is to take your application's source files, pass them to other programs (including Svelte, in our case) and convert them into the code that will actually run when you open the application in a browser.
|
||||||
|
|
||||||
|
Speaking of which, open a browser and navigate to http://localhost:5173. This is your application running on a local *web server* (hence 'localhost') on port 5173.
|
||||||
|
|
||||||
|
Try changing `src/App.svelte` and saving it. The application will update with your changes.
|
||||||
|
|
||||||
|
|
||||||
|
## Building your app
|
||||||
|
|
||||||
|
In the last step, we were running the app in 'development mode'. In dev mode, Svelte adds extra code that helps with debugging, and Vite skips the final step where your app's JavaScript is compressed.
|
||||||
|
|
||||||
|
When you share your app with the world, you want to build it in 'production mode', so that it's as small and efficient as possible for end users. To do that, use the `build` command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Your `dist` directory now contains an optimised version of your app. You can run it like so:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run preview
|
||||||
|
```
|
@ -0,0 +1,85 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: October 2020"
|
||||||
|
description: New object methods, in-depth learning resources and tons of integration examples!
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Welcome to the first edition of our "What's new in Svelte" series! We'll try to make this a monthly blog post in which you'll find out about new features, bug fixes, and a showcase of Svelte projects from around the community.
|
||||||
|
|
||||||
|
## New features
|
||||||
|
1. `use:obj.method` allows functions defined within objects to be used within actions ([Example](https://svelte.dev/repl/c305722adb4a4545b27b198ea8ff9bde?version=3.27.0), **3.26.0**, warning removed in **3.27.0**)
|
||||||
|
2. `_` is now supported as a "numerical separator", similar to a `.` or `,` ([Example](https://svelte.dev/repl/844c39e91d1248649fe54af839fab570?version=3.26.0), **3.26.0**)
|
||||||
|
3. `import.meta` now works in template expressions ([Example](https://svelte.dev/repl/9630de41957a4c80a4fce264360a6bc7?version=3.26.0), **3.26.0**)
|
||||||
|
4. CSS Selectors with `~` and `+` combinators are now supported ([Example](https://svelte.dev/repl/91ad9257d2d1430185a504a18cc60172?version=3.29.0), **3.27.0**, with a compiler fix in **3.29.0**)
|
||||||
|
5. The `{#key}` block is now available to key arbitrary content on an expression. Whenever the expression changes, the contents inside the `{#key}` block will be destroyed and recreated. For an in-depth explanation and to find out how it's implemented, check out the [new blog post](https://lihautan.com/contributing-to-svelte-implement-key-block/) of Svelte Team member Tan Li Hau. ([More info](https://github.com/sveltejs/svelte/issues/1469), **3.29.0**)
|
||||||
|
6. Slots can now be forwarded through child components! This used to only be possible by adding extra wrapper `<div>`s ([More info](https://github.com/sveltejs/svelte/issues/2079), **3.29.0**)
|
||||||
|
7. When using TypeScript, you can now type the `createEventDispatcher` method:
|
||||||
|
```html
|
||||||
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher<{
|
||||||
|
/**
|
||||||
|
* you can also add docs
|
||||||
|
*/
|
||||||
|
checked: boolean; // Will translate to `CustomEvent<boolean>`
|
||||||
|
hello: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// ...
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
This will make sure that you can invoke dispatch only with the specified event names and its types. The Svelte for VS Code extension was also updated to deal with this new feature. It will provide strong typings for these events as well as autocompletion and hover information.
|
||||||
|
|
||||||
|
**New from Sapper!**
|
||||||
|
Sapper 0.28.9 just came out. The highlights from it include much better support for CSP nonces, asset preload support for exported pages, and error details are now available in the `$page` store on error pages.
|
||||||
|
|
||||||
|
In addition, Sapper's CSS handling has been rewritten over the course of recent releases in order to fix existing CSS handling bugs, refactor the CSS handling to occur entirely within a Rollup plugin, and remove the need internally to register CSS in the routing system. Congrats and thank you to the folks working on Sapper for all their solid work!
|
||||||
|
|
||||||
|
|
||||||
|
## Impactful bug fixes
|
||||||
|
- CSS compilation will no longer remove rules for the `open` attribute on `<details>` elements ([Example](https://svelte.dev/repl/ab4c0c177d1f4fab92f46eb8539cea9a?version=3.26.0), **3.26.0**)
|
||||||
|
- `prettier-plugin-svelte` will do a better job now at dealing with whitespaces, especially around inline elements. It will also preserve formatting inside `<pre>` tags and will no longer format languages which are not supported by Prettier, like SASS, Pug or Stylus.
|
||||||
|
|
||||||
|
|
||||||
|
## Coming up
|
||||||
|
- [Svelte Summit](https://sveltesummit.com/), Svelte's second global online conference, is taking place on October 18! Sign up for free to get reminders and talk updates!
|
||||||
|
|
||||||
|
For all the features and bugfixes see the CHANGELOG for [Svelte](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) and [Sapper](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Svelte Showcase
|
||||||
|
- [This CustomMenu example](https://svelte.dev/repl/3a33725c3adb4f57b46b597f9dade0c1?version=3.25.0) demos how to replace the OS right-click menu
|
||||||
|
- [GitHub Tetris](https://svelte.dev/repl/cc1eaa7c66964fedb5e70e3ecbbaa0e1?version=3.25.1) lets you play a Tetris-like game in a git commit history
|
||||||
|
- [Who are my representatives?](https://whoaremyrepresentatives.us/) is a website built with Svelte to help US residents get more info on their congressional representatives
|
||||||
|
- [Pick Palette](https://github.com/bluwy/pick-palette) is a color palette manager made with Svelte!
|
||||||
|
|
||||||
|
### In-depth learning:
|
||||||
|
- [Svelte 3 Up and Running](https://www.amazon.com/dp/B08D6T6BKS/ref=cm_sw_r_tw_dp_x_OQMtFb3GPQCB2) is a new book about building production-ready static web apps with Svelte 3
|
||||||
|
- [Sapper Tutorial (Crash Course)](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gdr4Qhx83gBBcID-KMe-PQ) walks through the ins-and-outs of Sapper, the Svelte-powered application framework
|
||||||
|
- [Svelte Society Day France](https://france.sveltesociety.dev/) happened September 27th featuring a wide variety of topics all in French! You can find the full recording [here](https://www.youtube.com/watch?v=aS1TQ155JK4).
|
||||||
|
|
||||||
|
### Plug-and-play components:
|
||||||
|
- [svelte-zoom](https://github.com/vaheqelyan/svelte-zoom) brings "nearly native" pan-and-zoom to images on desktop and mobile
|
||||||
|
- [svelte-materialify](https://github.com/TheComputerM/svelte-materialify) is a Material component library for Svelte with over 50 components
|
||||||
|
- [svelte-undoable](https://github.com/macfja/svelte-undoable) makes it easy to introduce undo and redo functionality using `bind:`
|
||||||
|
- [This Tilt component](https://svelte.dev/repl/7b23ad9d2693424482cd411b0378b55b?version=3.24.1) implements a common UX pattern where the hovered element tilts to follow the mouse
|
||||||
|
|
||||||
|
### Lots of examples of how use JS tech came out this month:
|
||||||
|
- [Sapper with PostCSS and Tailwind](https://codechips.me/sapper-with-postcss-and-tailwind/)
|
||||||
|
- [PrismJS (Code block syntax highlighting)](https://github.com/phptuts/Svelte-PrismJS)
|
||||||
|
- [Filepond (Drag-and-drop file upload)](https://github.com/pqina/svelte-filepond)
|
||||||
|
- [Ionic (UI Components)](https://github.com/Tommertom/svelte-ionic-app)
|
||||||
|
- [Pell (WYSIWYG Editor)](https://github.com/Demonicious/svelte-pell/)
|
||||||
|
- [Leaflet (Mapping)](https://github.com/anoram/leaflet-svelte)
|
||||||
|
|
||||||
|
**Reminder**: There's a [Svelte integrations repo](https://github.com/sveltejs/integrations) that demonstrates ways to incorporate Svelte into your stack (and vice versa). If you've got questions on how to use a particular piece of tech with Svelte, you may find your answer there... and if you've gotten something to work with Svelte, consider contributing!
|
||||||
|
|
||||||
|
For more amazing Svelte projects, check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)… and be sure to post your own!
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
By the way, Svelte now has an [OpenCollective](https://opencollective.com/svelte)! All contributions and all expenses are published in our transparent public ledger. Learn who is donating, how much, where that money is going, submit expenses, get reimbursed and more!
|
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: November 2020"
|
||||||
|
description: Slot forwarding fixes, SvelteKit for faster local development, and more from Svelte Summit
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Welcome back to the "What's new in Svelte" series! This month, we're covering new features & bug fixes, last month's Svelte Summit and some stand-out sites and libraries...
|
||||||
|
|
||||||
|
## New features & impactful bug fixes
|
||||||
|
|
||||||
|
1. Destructuring Promises now works as expected by using the `{#await}` syntax
|
||||||
|
(**3.29.3**, [Example](https://svelte.dev/repl/3fd4e2cecfa14d629961478f1dac2445?version=3.29.3))
|
||||||
|
2. Slot forwarding (released in 3.29.0) should no longer hang during compilation (**3.29.3**, [Example](https://svelte.dev/repl/29959e70103f4868a6525c0734934936?version=3.29.3))
|
||||||
|
3. Better typings for the `get` function in `svelte/store` and on lifecycle hooks (**3.29.1**)
|
||||||
|
|
||||||
|
**What's going on in Sapper?**
|
||||||
|
|
||||||
|
Sapper got some new types in its `preload` function, which will make typing easier if you are using TypeScript. See the [Sapper docs](https://sapper.svelte.dev/docs#Typing_the_function) on how to use them. There also were fixes to `preload` links in exported sites. Route layouts got a few fixes too - including ensuring CSS is applied to nested route layouts. You can also better organize your files now that extensions with multiple dots are supported. (**0.28.10**)
|
||||||
|
|
||||||
|
|
||||||
|
For all the features and bugfixes see the CHANGELOGs for [Svelte](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) and [Sapper](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
|
||||||
|
## [Svelte Summit](https://sveltesummit.com/) was Svelte-tacular!
|
||||||
|
- Rich Harris demoed the possible future of Svelte development in a talk titled "Futuristic Web Development". The not-yet-public project is called SvelteKit (name may change) and will bring a first-class developer experience and more flexibility for build outputs. If you want to get the full sneak-peek, [check out the video](https://www.youtube.com/watch?v=qSfdtmcZ4d0).
|
||||||
|
- 17 speakers made the best of the conference's virtual format... From floating heads to seamless demos, Svelte developers from every skill level will find something of interest in this year's [YouTube playlist](https://www.youtube.com/playlist?list=PL8bMgX1kyZThM1sbYCoWdTcpiYysJsSeu)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
- [Svelte Lab](https://sveltelab.app/) showcases a variety of components, visualizations and interactions that can be achieved in Svelte. You can click into any component to see its source or edit it, using the site's built-in REPL
|
||||||
|
- [svelte-electron-boilerplate](https://github.com/hjalmar/svelte-electron-boilerplate) is a fast way to get up and running with a Svelte app built in the desktop javascript framework, Electron
|
||||||
|
- [React Hooks in Svelte](https://github.com/joshnuss/react-hooks-in-svelte) showcases examples of common React Hooks ported to Svelte.
|
||||||
|
- [gurlic](https://gurlic.com/) is a social network and internet experiment that is super snappy thanks to Svelte
|
||||||
|
- [Interference 2020](https://interference2020.org/) visualizes reported foreign interference in the 2020 U.S. elections. You can learn more about how it was built in [YYY's talk at Svelte Summit]()
|
||||||
|
- [jitsi-svelte](https://github.com/relm-us/jitsi-svelte) lets you easily create your own custom Jitsi client by providing out-of-the-box components built with Svelte
|
||||||
|
- [Ellx](https://ellx.io/) is part spreadsheet, part notebook and part IDE. It's super smooth thanks to Svelte 😎
|
||||||
|
- [This New Zealand news site](https://www.nzherald.co.nz/nz/election-2020-latest-results-party-vote-electorate-vote-and-full-data/5CFVO4ENKNQDE3SICRRNPU5GZM/) breaks down the results of the 2020 Parliamentary elections using Svelte
|
||||||
|
- [Budibase](https://github.com/Budibase/budibase) is a no-code app builder, powered by Svelte
|
||||||
|
- [Svelt-yjs](https://github.com/relm-us/svelt-yjs) combines the collaborative, local-first technology of Yjs with the power of Svelte to enable multiple users across the internet to stay in sync.
|
||||||
|
- [tabler-icons-svelte](https://github.com/benflap/tabler-icons-svelte) is a Svelte wrapper for over 850 free MIT-licensed high-quality SVG icons for you to use in your web projects.
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Got an idea for something to add to the Showcase? Want to get involved more with Svelte? We're always looking for maintainers, contributors and fanatics... Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!
|
@ -0,0 +1,103 @@
|
|||||||
|
---
|
||||||
|
title: What's the deal with SvelteKit?
|
||||||
|
description: We're rethinking how to build Svelte apps. Here's what you need to know
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/rich_harris
|
||||||
|
---
|
||||||
|
|
||||||
|
<aside><p>If you <em>didn't</em> attend Svelte Summit, you can catch up on the <a href="https://www.youtube.com/c/SvelteSociety/videos">Svelte Society YouTube page</a></p></aside>
|
||||||
|
|
||||||
|
If you attended [Svelte Summit](https://sveltesummit.com/) last month you may have seen my talk, Futuristic Web Development, in which I finally tackled one of the most frequently asked questions about Svelte: when will Sapper reach version 1.0?
|
||||||
|
|
||||||
|
The answer: never.
|
||||||
|
|
||||||
|
This was slightly tongue-in-cheek — as the talk explains, it's really more of a rewrite of Sapper coupled with a rebrand — but it raised a lot of new questions from the community, and it's time we offered a bit more clarity on what you can expect from Sapper's successor, SvelteKit.
|
||||||
|
|
||||||
|
<div class="max">
|
||||||
|
<figure style="max-width: 960px; margin: 0 auto">
|
||||||
|
<div style="height: 0; padding: 0 0 57.1% 0; position: relative; margin: 0 auto;">
|
||||||
|
<iframe style="position: absolute; width: 100%; height: 100%; left: 0; top: 0; margin: 0;" src="https://www.youtube-nocookie.com/embed/qSfdtmcZ4d0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<figcaption>'Futuristic Web Development' from <a href="https://sveltesummit.com/">Svelte Summit</a></figcaption>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
## What's Sapper?
|
||||||
|
|
||||||
|
[Sapper](https://sapper.svelte.dev) is an *app framework* (or 'metaframework') built on top of Svelte (which is a *component* framework). Its job is to make it easy to build Svelte apps with all the modern best practices like server-side rendering (SSR) and code-splitting, and to provide a project structure that makes development productive and fun. It uses *filesystem-based routing* (as popularised by [Next](https://nextjs.org/) and adopted by many other frameworks, albeit with some enhancements) — your project's file structure mirrors the structure of the app itself.
|
||||||
|
|
||||||
|
While the Svelte homepage and documentation encourages you to [degit](https://github.com/Rich-Harris/degit) the [sveltejs/template](https://github.com/sveltejs/template) repo to start building an app, Sapper has long been our recommended way to build apps; this very blog post is (at the time of writing!) rendered with Sapper.
|
||||||
|
|
||||||
|
|
||||||
|
## Why are we migrating to something new?
|
||||||
|
|
||||||
|
Firstly, the distinction between [sveltejs/template](https://github.com/sveltejs/template) and [sveltejs/sapper-template](https://github.com/sveltejs/sapper-template) is confusing, particularly to newcomers to Svelte. Having a single recommended way to start building apps with Svelte will bring enormous benefits: we simplify onboarding, reduce the maintenance and support burden, and can potentially begin to explore the new possibilities that are unlocked by having a predictable project structure. (This last part is deliberately vague because it will take time to fully understand what those possibilities are.)
|
||||||
|
|
||||||
|
Aside from all that, we've been tempted by the thought of rewriting Sapper for a while. This is partly because the codebase has become a little unkempt over the years ([Sapper started in 2017](/blog/sapper-towards-the-ideal-web-app-framework)), but mostly because the web has changed a lot recently, and it's time to rethink some of our foundational assumptions.
|
||||||
|
|
||||||
|
|
||||||
|
## How is this new thing different?
|
||||||
|
|
||||||
|
The first of those foundational assumptions is that you need to use a module bundler like [webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/) to build apps. These tools trace the dependency graph of your application, analysing and transforming code along the way (turning Svelte components to JS modules, for example), in order to create bundles of code that can run anywhere. As the original creator of Rollup, I can attest that it is a surprisingly complex problem with fiendish edge cases.
|
||||||
|
|
||||||
|
You certainly needed a bundler several years ago, because browsers didn't natively support the `import` keyword, but it's much less true today. Right now, we're seeing the rise of the *unbundled development* workflow, which is radically simpler: instead of eagerly bundling your app, a dev server can serve modules (converted to JavaScript, if necessary) *on-demand*, meaning startup is essentially instantaneous however large your app becomes.
|
||||||
|
|
||||||
|
[Snowpack](https://www.snowpack.dev/) is at the vanguard of this movement, and it's what powers SvelteKit. It's astonishingly fast, and has a beautiful development experience (hot module reloading, error overlays and so on), and we've been working closely with the Snowpack team on features like SSR. The hot module reloading is particularly revelatory if you're used to using Sapper with Rollup (which has never had first-class HMR support owing to its architecture, which prioritises the most efficient output).
|
||||||
|
|
||||||
|
That's not to say we're abandoning bundlers altogether. It's still essential to optimise your app for production, and SvelteKit uses Rollup to make your apps as fast and lean as they possibly can be (which includes things like extracting styles into static `.css` files).
|
||||||
|
|
||||||
|
The other foundational assumption is that a server-rendered app needs, well, a server. Sapper effectively has two modes — `sapper build`, which creates a standalone app that has to run on a Node server, and `sapper export` which bakes your app out as a collection of static files suitable for hosting on services like GitHub Pages.
|
||||||
|
|
||||||
|
Static files can go pretty much anywhere, but running a Node server (and monitoring/scaling it etc) is less straightforward. Nowadays we're witnessing a shift towards *serverless platforms*, in which you as the app author don't need to think about the server your code is running on, with all the attendant complexity. You can get Sapper apps running on serverless platforms, thanks to things like [vercel-sapper](https://github.com/thgh/vercel-sapper), but it's certainly not what you'd call idiomatic.
|
||||||
|
|
||||||
|
<aside><p>It'll still be possible to create both Node apps and fully pre-rendered (aka exported) sites</a></p></aside>
|
||||||
|
|
||||||
|
SvelteKit fully embraces the serverless paradigm, and will launch with support for all the major serverless providers, with an 'adapter' API for targeting any platforms that we don't officially cater to. In addition, we'll be able to do partial pre-rendering, which means that static pages can be generated at build time but dynamic ones get rendered on-demand.
|
||||||
|
|
||||||
|
|
||||||
|
## When can I start using it?
|
||||||
|
|
||||||
|
If you're feeling brave, you can start right now:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm init svelte@next
|
||||||
|
```
|
||||||
|
|
||||||
|
This will scaffold a new project and install the `@sveltejs/kit` CLI, which provides the tools for developing and building an app.
|
||||||
|
|
||||||
|
We don't recommend it though! There are no docs, and we won't be able to offer any form of support. It's also likely to break often.
|
||||||
|
|
||||||
|
The work is being done in a private monorepo while we're still in exploration mode. Our plan is to get a public beta ready and announce it here once we've closed a few issues — the repo itself will remain private at that time, but we'll create a place to collect feedback from the YOLO crowd. After that, we'll work towards a 1.0 release which will involve opening the repo up.
|
||||||
|
|
||||||
|
I'm not going to make any firm promises about timings, because I don't like to break promises. But I *think* we're talking about weeks rather than months.
|
||||||
|
|
||||||
|
|
||||||
|
## What if I don't want to use SvelteKit?
|
||||||
|
|
||||||
|
You won't have to — it will always be possible to use Svelte as a standalone package or via a bundler integration like [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte). We think it's essential that you can bend Svelte to fit your workflow, however esoteric, and use third-party app frameworks like [Elder.js](https://github.com/Elderjs/elderjs), [Routify](https://routify.dev/), [Plenti](https://plenti.co/), [Crown](https://crownframework.com/), [JungleJS](https://www.junglejs.org/) and others.
|
||||||
|
|
||||||
|
|
||||||
|
## TypeScript?
|
||||||
|
|
||||||
|
Don't worry, we won't launch without full TypeScript support.
|
||||||
|
|
||||||
|
|
||||||
|
## How can I migrate my existing Sapper apps?
|
||||||
|
|
||||||
|
For the most part, it should be relatively straightforward to migrate a Sapper codebase.
|
||||||
|
|
||||||
|
There are some unavoidable changes (being able to run on serverless platforms means we need to replace custom `server.js` files and `(req, res) => {...}` functions with more portable equivalents), and we're taking the opportunity to fix a few design flaws, but on the whole a SvelteKit app will feel very familiar to Sapper users.
|
||||||
|
|
||||||
|
Detailed migration guides will accompany the 1.0 launch.
|
||||||
|
|
||||||
|
|
||||||
|
## How can I contribute?
|
||||||
|
|
||||||
|
Keep your eyes peeled for announcements about when we'll launch the public beta and open up the repo. (Also, blog post TODO but I would be remiss if I didn't mention that we now have an [OpenCollective](https://opencollective.com/svelte) where you can contribute financially to the project if it's been valuable to you. Many, many thanks to those of you who already have.)
|
||||||
|
|
||||||
|
|
||||||
|
## Where can I learn more?
|
||||||
|
|
||||||
|
Follow [@sveltejs](https://twitter.com/sveltejs) and [@SvelteSociety](https://twitter.com/SvelteSociety) on Twitter, and visit [svelte.dev/chat](https://svelte.dev/chat). You should also subscribe to [Svelte Radio](https://www.svelteradio.com/), where Kevin and his co-hosts will grill me about this project on an upcoming episode (and between now and next week when we record it, [reply to this Twitter thread](https://twitter.com/Rich_Harris/status/1323376048571121665) with your additional questions).
|
@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: December 2020"
|
||||||
|
description: Better tooling, export maps and improvements to slots and context
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
It's the last "What's new in Svelte" of the year and there's lots to celebrate! This month's coverage includes updates from `rollup-plugin-svelte`, `Sapper` and `SvelteKit` and a bunch of showcases from the Svelte community!
|
||||||
|
|
||||||
|
## New features & impactful bug fixes
|
||||||
|
|
||||||
|
1. `$$props`, `$$restProps`, and `$$slots` are all now supported in custom web components (**3.29.5**, [Example](https://svelte.dev/repl/ad8e6f39cd20403dacd1be84d71e498d?version=3.29.5)) and `slot` components now support spread props: `<slot {...foo} />` (**3.30.0**)
|
||||||
|
2. A new `hasContext` lifecycle function makes it easy to check whether a `key` has been set in the context of a parent component (**3.30.0** & **3.30.1**, [Docs](https://svelte.dev/docs#run-time-svelte-hascontext))
|
||||||
|
3. There is now a new `SvelteComponentTyped` class which makes it easier to add strongly typed components that extend base Svelte components. Component library and framework authors rejoice! An example: `export class YourComponent extends SvelteComponentTyped<{aProp: boolean}, {click: MouseEvent}, {default: {aSlot: string}}> {}` (**3.31.0**, [RFC](https://github.com/sveltejs/rfcs/pull/37))
|
||||||
|
4. Transitions within `{:else}` blocks should now complete successfully (**3.29.5**, [Example](https://svelte.dev/repl/49cef205e5da459594ef2eafcbd41593?version=3.29.5))
|
||||||
|
5. Svelte now includes an export map, which explicitly states which files can be imported from its npm package (**3.29.5** with some fixes in **3.29.6**, **3.29.7** and **3.30.0**)
|
||||||
|
6. `rollup-plugin-svelte` had a new [7.0.0 release](https://github.com/sveltejs/rollup-plugin-svelte/blob/master/CHANGELOG.md). The biggest change is that the `css` option was removed. Users who were using that option should add another plugin like `rollup-plugin-css-only` as demonstrated [in the template](https://github.com/sveltejs/template/blob/5b1135c286f7a649daa99825a077586655051649/rollup.config.js#L48)
|
||||||
|
|
||||||
|
|
||||||
|
## What's going on in Sapper?
|
||||||
|
Lots of new TypeScript definition improvements to make editing Sapper apps even easier! CSS for dynamic imports also should now work in `client.js` files. (Unreleased)
|
||||||
|
|
||||||
|
## What's the deal with SvelteKit?
|
||||||
|
We're glad you asked! If you didn't catch Rich's blog post from early last month, [you can find it here](https://svelte.dev/blog/whats-the-deal-with-sveltekit)!
|
||||||
|
|
||||||
|
For all the features and bugfixes see the CHANGELOGs for [Svelte](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) and [Sapper](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [narration.studio](https://narration.studio/) (Chrome Only) is an automatic in-browser audio recording & editing platform for voice over narration.
|
||||||
|
- [Vippet](https://vippet.netlify.app/) is a video recording and editing tool for the browser.
|
||||||
|
- [Pattern Monster](https://pattern.monster/) is a simple online pattern generator to create repeatable SVG patterns.
|
||||||
|
- [Plant-based diets](https://planetbaseddiets.panda.org/) is a website from the World Wildlife Foundation (WWF) built with Svelte.
|
||||||
|
- [johnells.se](https://www.johnells.se/) is a Swedish fashion e-commerce site, built with [Crown](https://crownframework.com/) - a Svelte-powered framework.
|
||||||
|
- [sentence-length](https://sentence-length.netlify.app/) is a learning and analysis tool to show how some authors play with different lengths, while others stick with one.
|
||||||
|
- [svelte-presenter](https://github.com/stephane-vanraes/svelte-presenter) lets you quickly make good looking presentations using Svelte and mdsvex.
|
||||||
|
|
||||||
|
**Demos**
|
||||||
|
- [u/loopcake got SSR working in Java Spring Boot](https://www.reddit.com/r/sveltejs/comments/jkh5up/svelte_ssr_but_its_java_spring_boot_and_its_native/) for all the Java shops out there looking to render Svelte server-side.
|
||||||
|
- [svelte-liquid-swipe](https://github.com/tncrazvan/svelte-liquid-swipe) shows off a fancy interaction pattern using svg paths.
|
||||||
|
- [Crossfade Link Animation](https://svelte.dev/repl/7f68e148caf04b2787bb6f296208f870?version=3.29.7) demonstrates how to animate between navigation links using a crossfade (made by Blu, from the Discord community)
|
||||||
|
- [Clip-Path Transitions](https://svelte.dev/repl/b5ad281ae8024b629b545c70c9e8764d?version=3.29.7) showcases how to use clip paths and custom transitions to create magical in-and-out transitions (made by Faber, from the Discord community)
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
- [lihautan](https://www.youtube.com/channel/UCbmC3HP3FaAFdcZkui8YoMQ/featured) has been making easy-to-follow videos to share his in-depth knowledge of Svelte.
|
||||||
|
- [Lessons From Building a Static Site Generator](https://nicholasreese.com/lessons-from-building-a-static-site-generator/) shares the backstory and thinking behind Elder.js - and the design decision made along the way.
|
||||||
|
- [Svelte Tutorial and Projects Course ](https://www.udemy.com/course/svelte-tutorial-and-projects-course/) is a udemy course by John Smilga where students learn Svelte.js by building interesting projects.
|
||||||
|
- [Building Pastebin on IPFS - with FastAPI, Svelte, and IPFS](https://amalshaji.wtf/building-pastebin-on-ipfs-with-fastapi-svelte-and-ipfs) explains how to make a distributed pastebin-like application.
|
||||||
|
|
||||||
|
|
||||||
|
**Components, Libraries & Tools**
|
||||||
|
- [svelte-crossword](https://russellgoldenberg.github.io/svelte-crossword/) is a customizable crossword puzzle component for Svelte.
|
||||||
|
- [svelte-cloudinary](https://github.com/cupcakearmy/svelte-cloudinary) makes it easy to integrate Cloudinary with Svelte (including TypeScript and SSR support)
|
||||||
|
- [Svelte Nova](https://extensions.panic.com/extensions/sb.lao/sb.lao.svelte-nova/) extends the new Nova editor to support Svelte
|
||||||
|
- [saos](https://github.com/shiryel/saos) is a small svelte component to animate your elements on scroll.
|
||||||
|
- [Svelte-nStore](https://github.com/lacikawiz/svelte-nStore) is a general purpose store replacement that fulfills the Svelte store contract and adds getter and calculation features.
|
||||||
|
- [svelte-slimscroll](https://github.com/MelihAltintas/svelte-slimscroll) is a Svelte Action that transforms any div into a scrollable area with a nice scrollbar.
|
||||||
|
- [svelte-typewriter](https://github.com/henriquehbr/svelte-typewriter) is a simple and reusable typewriter effect for your Svelte applications
|
||||||
|
- [svelte-store-router](https://github.com/zyxd/svelte-store-router) is a store-based router for Svelte that suggests that routing is just another global state and History API changes are just an optional side-effects of this state.
|
||||||
|
- [Routify](https://routify.dev/blog/routify-2-released) just released version 2 of its Svelte router.
|
||||||
|
- [svelte-error-boundary](https://www.npmjs.com/package/@crownframework/svelte-error-boundary) provides a simple error boundary component for Svelte that can be can be used with both DOM and SSR targets.
|
||||||
|
- [svelte2dts](https://www.npmjs.com/package/svelte2dts) generates d.ts files from svelte files, creating truly shareable and well typed components.
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Got an idea for something to add to the Showcase? Want to get involved more with Svelte? We're always looking for maintainers, contributors and fanatics... Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!
|
||||||
|
|
||||||
|
That's all for the year, folks! See you in January 😎
|
@ -0,0 +1,86 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: January 2021"
|
||||||
|
description: A Svelte-packed showcase to kick-off the new year!
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Happy new year from Svelte! In the last month we made progress on Sapper's upcoming release, fine-tuned our `SvelteComponent` typings, and have seen some amazing apps, sites, and libraries coming out in the showcase.
|
||||||
|
|
||||||
|
## What's changed in Svelte?
|
||||||
|
|
||||||
|
A new minor release replaces the `SvelteComponent` class with a `SvelteComponentTyped` class. This renaming should help with backwards compatibility. We've updated [last month's blog post](https://svelte.dev/blog/whats-new-in-svelte-december-2020) to avoid any confusion with the name change.
|
||||||
|
|
||||||
|
If you're using `SvelteComponent` or the new `SvelteComponentTyped` in your project or library, let us know what you're using it for and we'll add it to the showcase!
|
||||||
|
|
||||||
|
|
||||||
|
## What's going on in Sapper?
|
||||||
|
|
||||||
|
More quality of life features are landing in the upcoming release every day. `0.29.0` will include new TypeScript definitions, fixes to scroll tracking and prefetching behavior, and improvements to the runtime router to support encoded query parameters.
|
||||||
|
|
||||||
|
If you're upgrading from 0.28.x, check out [the migration guide](https://sapper.svelte.dev/migrating/#0_28_to_0_29) for steps on updating to Sapper 0.29.
|
||||||
|
|
||||||
|
|
||||||
|
## Is SvelteKit ready yet?
|
||||||
|
|
||||||
|
To avoid too much churn during development, SvelteKit is still being worked on in a private repo. There will be an announcement on the Discord, blog and Twitter when it's ready for a larger group of users and contributors.
|
||||||
|
|
||||||
|
In the meantime, you can explore the current build by running `npm init svelte@next` from your command line.
|
||||||
|
|
||||||
|
As cautioned in _[What's the deal with SvelteKit?](https://svelte.dev/blog/whats-the-deal-with-sveltekit)_, there are no docs or support available yet... So use at your own risk / for your own enjoyment!
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
|
||||||
|
- [manitu.me](https://manitu.me/) is a background sound / pomodoro timer for focus and relaxation
|
||||||
|
- [Answer Socrates](https://answersocrates.com/) helps you find trending questions on the internet so that you can write the most relevant blog post, tweet, or billboard
|
||||||
|
- [multris](https://multris.s1h.org/) is a multiplayer Tetris game. You can read about its development [here](https://blog.s1h.org/svelte-multiplayer-game/)
|
||||||
|
- [weather-ab](https://github.com/ganochenkodg/weather-ab) compares the archive of weather in different cities of the world. Indispensable for people thinking about migration
|
||||||
|
- [Game Nibs](https://gamenibs.com/) is a platform for gamers to find and share concise bite-sized bits of gaming advice, tips, tricks, screenshots, builds, and much more
|
||||||
|
- [Ora](https://github.com/cupcakearmy/ora) is an open source website tracking and limiting tool for Chrome and Firefox
|
||||||
|
- [vscode-dms](https://github.com/techsyndicate/vscode-dms) is a group direct messaging chat app for VSCode
|
||||||
|
- [Zero.2](https://zero.oleksandrdemian.tech/) is a math-based challenge game where you try to get to zero as quickly as possible
|
||||||
|
- [Octave Compass](https://octavecompass.com/2741) is a chord table and scale explorer for many popular musical scales
|
||||||
|
- [Infinite Walking Bass Generator 2](https://github.com/elialbert/infinitewalkingbass2) is an online music player that generates a unique walking bass line
|
||||||
|
- [ListenAddict](https://www.listenaddict.com/) is a site that notifies you whenever a person has a new talk/interview on podcast
|
||||||
|
|
||||||
|
**Demos, Libraries & Components**
|
||||||
|
|
||||||
|
- [svelte-tiny-virtual-list](https://github.com/Skayo/svelte-tiny-virtual-list) speeds up long lists by only rendering visible items
|
||||||
|
- [svelte-query](https://github.com/TanStack/svelte-query) is a collection of helpful hooks for managing, caching and syncing asynchronous and remote data
|
||||||
|
- [svelte-previous](https://github.com/bryanmylee/svelte-previous) is a svelte store to remember previous values - helpful for transitions or a quick undo stack
|
||||||
|
- [Let's Build a Confetti Cannon](https://varun.ca/confetti/) explains how to build a particle system and integrate a Canvas based animation into a larger application
|
||||||
|
- [svelte-micro](https://github.com/ayndqy/svelte-micro) is a one-component router
|
||||||
|
- [svelte-standalone-router](https://github.com/hjalmar/svelte-standalone-router) is a standalone router with an API based on [standalone-router](https://github.com/hjalmar/standalone-router)
|
||||||
|
- [svelte-datepicker](https://github.com/beyonk-adventures/svelte-datepicker) is a datepicker component with variations for time selection, date ranges and responsive themes
|
||||||
|
- [svelte-slimscroll](https://github.com/MelihAltintas/svelte-slimscroll) is a action for Svelte.js, which can transforms any div into a scrollable area with a nice scrollbar.
|
||||||
|
- [Svelte Zoomable](https://svelte.dev/repl/58dfe87756ee4db897c281b52fdef7b7?version=3.31.0) is a custom transition with a nice zoom effect
|
||||||
|
|
||||||
|
**Have a component you'd like to share?** Check out the [Components](https://sveltesociety.dev/components) page on the Svelte Society site. You can contribute by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
- [Using Svelte to create a scroll video effect](https://blog.koenvangilst.nl/tutorial-svelte-scroll-video/) showcases how the `bind` command can be used to create a cool scroll video effect with very little code
|
||||||
|
- [How to make a flappybird game in svelte and typescript](https://www.youtube.com/watch?v=nhrYBoVI8pQ) is a video tutorial including docs and code for reference
|
||||||
|
- [Accessible Svelte Transition](https://www.youtube.com/watch?v=QK_QuRL7nSo&feature=youtu.be) walks through `prefers-reduced-motion` to make svelte transitions more accessible
|
||||||
|
- [Svelte's module scripts explained](https://codechips.me/svelte-module-scripts-explained/) is a great introduction to the module context, a common Sapper pattern
|
||||||
|
- [Awesome Svelte](https://github.com/TheComputerM/awesome-svelte#readme) is a curated list of Svelte resources
|
||||||
|
- [.NET Core and Svelte](https://dev.to/cainux/net-core-and-svelte-f8o) explains how to get Svelte up and running with .NET Core
|
||||||
|
- [A la découverte de Svelte JS](https://www.youtube.com/watch?v=SLpx1Y8e1ek&list=PLff5I1miao9ZEUhpqkrOx7k8RGAZt-nm9) is a svelte tutorial series in French!
|
||||||
|
- [Svelte for React Developers](https://soshace.com/svelte-for-react-developers/) explains Svelte's core concepts to folks who are used to React
|
||||||
|
- [Building a Svelte Static Website with Smooth Page Transitions](https://www.youtube.com/watch?v=dvPfmcGtmrI&feature=emb_title) shows how to build a static website with Svelte and add smooth page transitions using Three.js and GSAP.
|
||||||
|
- [Using Apollo Client in Sapper](https://bjornlu.com/blog/using-apollo-client-in-sapper/) explains the "simplest" solutions to integrate the Apollo query client into Sapper
|
||||||
|
- [Reactive web apps with Crystal + Svelte](https://www.youtube.com/watch?v=i1xjLd6z7BU) explores how to build full-stack, server-rendered Svelte apps with a [Crystal](https://crystal-lang.org) backend
|
||||||
|
|
||||||
|
**Related Projects**
|
||||||
|
|
||||||
|
- [Snowpack's v3 release candidate](https://www.snowpack.dev/posts/2020-12-03-snowpack-3-release-candidate) is out now in preparation for a January 6 release date. Check out the [Getting Started with Svelte](https://www.snowpack.dev/tutorials/svelte) for more info on how to use Snowpack.
|
||||||
|
- [Uppy](https://uppy.io/blog/2020/12/1.24/), the open source file uploader, announced Svelte support in its new version 1.24
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Want to add your work to the Showcase? Want to contribute to Svelte? Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!
|
@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: March 2021"
|
||||||
|
description: Call for Svelte Summit Speakers! Improved SSR, non-HTML5 compilation targets, and ESLint TypeScript support
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Lots to cover this month with releases from across the Svelte ecosystem. Most importantly, Svelte Summit Spring 2021 has an [Open Call for Speakers](https://sessionize.com/svelte-summit-spring-2021). **The deadline is March 14** so if you have an idea for a talk, submit it now!
|
||||||
|
|
||||||
|
Let's dive into the news 🐬
|
||||||
|
|
||||||
|
## What's new in `sveltejs/svelte`
|
||||||
|
* SSR store handling has been reworked to subscribe and unsubscribe as in DOM mode. SSR stores should work much more consistently now (**3.31.2**, see [custom stores](https://svelte.dev/examples/custom-stores) and [Server-side component API ](https://svelte.dev/docs#run-time-server-side-component-api))
|
||||||
|
* Multiple instances of the same action are now allowed on an element (**3.32.0**, [example](https://svelte.dev/repl/01a14375951749dab9579cb6860eccde?version=3.32.0))
|
||||||
|
* The new `foreign` namespace should make it easier for alternative compile targets (like Svelte Native and SvelteGUI) by disabling certain HTML5-specific behaviour and checks (**3.32.0**, [more info](https://github.com/sveltejs/svelte/pull/5652))
|
||||||
|
* Support for inline comment sourcemaps in code from preprocessors (**3.32.0**)
|
||||||
|
* Destructured defaults are now allowed to refer to other variables (**3.33.0**, [example](https://svelte.dev/repl/0ee7227e1b45465b9b47d7a5ae2d1252?version=3.33.0))
|
||||||
|
* Custom elements will now call `onMount` functions when connecting and clean up when disconnecting (**3.33.0**, checkout [this PR](https://github.com/sveltejs/svelte/pull/4522) for an interesting conversation on how folks are using Svelte with Web Components)
|
||||||
|
* A `cssHash` option has been added to the compiler options to control the classname used for CSS scoping (**3.34.0**, [docs](https://svelte.dev/docs#compile-time-svelte-compile))
|
||||||
|
* Continued improvement to TypeScript definitions
|
||||||
|
|
||||||
|
For a complete list of changes, including bug fixes and links to PRs, check out [the CHANGELOG](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md)
|
||||||
|
|
||||||
|
|
||||||
|
## New from `sveltejs/language-tools`
|
||||||
|
|
||||||
|
- For language server clients that don't support `didChangeWatchedFiles`, a fallback file watcher will be used instead
|
||||||
|
- New highlighting rules for store accessors and element directives (like `bind:` and `class:`)
|
||||||
|
- HTML tags can now be renamed together
|
||||||
|
- Mustache tags parsing is now more robust and will provide better intellisense in more situations
|
||||||
|
|
||||||
|
Haven't tried the language-tools yet? Check out [Svelte Extension for VSCode](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) or find a plugin for your favorite IDE!
|
||||||
|
|
||||||
|
## Other changes from `sveltejs/*`
|
||||||
|
|
||||||
|
- [eslint-plugin-svelte3](https://github.com/sveltejs/eslint-plugin-svelte3) now supports TypeScript as of 3.1.0
|
||||||
|
- [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte/) released a number of minor versions to address whitespace and comment trimming issues.
|
||||||
|
- [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess/) bug fixes this month include fixes to postcss transformations and support for both v2 and v3 of `postcss-load-config`
|
||||||
|
- [sapper](https://github.com/sveltejs/sapper/)'s 0.29.1 release fixes some bad imports in type definitions, updates typings to be compatible with express/polka, and restores hashing of all CSS file names.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
|
||||||
|
- [Tracking the Coronavirus](https://www.nytimes.com/interactive/2021/us/new-york-city-new-york-covid-cases.html) from NYTimes is an example of SvelteKit in production
|
||||||
|
- [Budibase](https://github.com/Budibase/budibase) is an open-source low-code platform, helping developers and IT professionals build, automate, and ship internal tools 50x faster on their own infrastructure.
|
||||||
|
- [Track the Parcel](https://tracktheparcel.com/) is a one-stop tool for tracking parcel status with all major package shippers.
|
||||||
|
- [Memo](https://sendmemo.app/features/) is a replacement for email that uses Svelte for modern messaging
|
||||||
|
- [Userscripts Safari](https://github.com/quoid/userscripts) is an open-source userscript editor for Safari... a native Svelte app for Mac OS!
|
||||||
|
- [SVGX](https://svgx.app/) is "the desktop SVG asset manager designers and developers wished they had."
|
||||||
|
- [Armoria](https://azgaar.github.io/Armoria/) is a procedural heraldry generator and editor
|
||||||
|
- [FictionBoard](https://www.fictionboard.com) is a virtual table top (VTT) platform that just released fillable and responsive character sheets
|
||||||
|
- [Castles & Crusades Treasure Generator](https://treasure.playaheadgames.com/) is a treasure generator for the table top RPG: Castles and Crusades.
|
||||||
|
- [NESBit Studio](https://jensa.org/NESBitStudio-web/graphics/spritesheets) is a toolkit to help the development of homebrew NES games
|
||||||
|
- [ElectroBlocks](https://electroblocks.org/) is an online Arduino IDE with a built-in simulator (Chrome Only)
|
||||||
|
- [Goblin.life](https://store.steampowered.com/app/552180/GoblinLife/) is a 3D world builder whose UI is built with Svelte
|
||||||
|
- [farmbox](https://farmbox.ae/) is a UAE-based grocery delivery services
|
||||||
|
- [heroeswearmasks.fun](https://heroeswearmasks.fun/) is a client-side machine learning tool that determines whether or not you're wearing a mask.
|
||||||
|
- [weatherify](https://brdtheo-weatherify.netlify.app/) is a very pretty (and [open source](https://github.com/brdtheo/weatherify)) weather app
|
||||||
|
- [DSN Live](https://dsn-live.netlify.app/#/) lets you monitor connections between NASA/JPL and interplanetary spacecraft missions in real time.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Demos, Libraries, Tools & Components**
|
||||||
|
|
||||||
|
- [spc](https://github.com/khang-nd/spc) is a special characters picker component for the web
|
||||||
|
- [svelte-injector](https://www.npmjs.com/package/svelte-injector) lets you inject Svelte components in React, Angular, Vue, jQuery, Vanilla JS.
|
||||||
|
- [Felte](https://felte.dev/) is a form library for Svelte with simple validation reporting.
|
||||||
|
- [svelte-use-form](https://github.com/noahsalvi/svelte-use-form#readme) is form library that "is easy to use and has 0 boilerplate."
|
||||||
|
- [Formula](https://formula.svelte.codes/) provides "Zero Configuration Reactive Forms for Svelte."
|
||||||
|
- [Houdini](https://github.com/AlecAivazis/houdini) is "the disappearing GraphQL client built for Sapper and Sveltekit."
|
||||||
|
- [svelte-split-pane](https://www.reddit.com/r/sveltejs/comments/leoe33/sveltesplitpane/) is a draggable split pane component
|
||||||
|
- [svelte-virtualized-auto-sizer](https://github.com/micha-lmxt/svelte-virtualized-auto-sizer) is a high-order component that automatically adjusts the width and height of a single child.
|
||||||
|
- [svelte-window](https://github.com/micha-lmxt/svelte-window) are components for efficiently rendering large, scrollable lists and tabular data.
|
||||||
|
- [Svelte Persistent store](https://github.com/MacFJA/svelte-persistent-store) is a Svelte store that keep its value through pages and reloads
|
||||||
|
- [Svelte Dark](https://marketplace.visualstudio.com/items?itemName=NickScialli.svelte-dark) is a VSCode theme inspired by the svelte.dev REPL
|
||||||
|
- [Import Cost](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost) has been updated to support Svelte libraries and help developers keep their bundle size under control.
|
||||||
|
- [Tree-sitter-svelte](https://github.com/Himujjal/tree-sitter-svelte) provides tree-sitter grammar for svelte
|
||||||
|
- [Svelte Ripple](https://svelte.dev/repl/b73224a0fd4248178e3eab41943d41a9?version=3.31.2) is a Material Design ripple effect that doesn't depend on `@material/ripple` (made by @karakara in the Svelte Discord)
|
||||||
|
- [Analog SVG Clock](https://svelte.dev/repl/270e83f43e7a48918d8f2d497760904f?version=3.32.1) is a great example of easing functions (made by @tonmcg in the Svelte Discord)
|
||||||
|
- [Console Log Styler](https://svelte.dev/repl/11f609d0d90746f08da6d3d90bba84fc?version=3.32.0) lets you generate a styled console log using pseudo HTML and CSS (made by @EmNudge in the Svelte Discord)
|
||||||
|
- [svelte-heroicons](https://github.com/martinse/svelte-heroicons) is a handy wrapper for the Heroicons icon library
|
||||||
|
- [supabase-ui-svelte](https://github.com/joshnuss/supabase-ui-svelte) are UI components for Supabase authentication
|
||||||
|
|
||||||
|
**Have your own Svelte Component to share?** Check out the [Components](https://sveltesociety.dev/components) page on the Svelte Society site. You can contribute by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources & Starters**
|
||||||
|
|
||||||
|
- [The **unofficial** SvelteKit docs](https://sk-incognito.vercel.app/learn/what-is-sveltekit) were built using SvelteKit and are [open for contributions](https://github.com/GrygrFlzr/kit-docs)
|
||||||
|
- [📦 Svelte Store](https://www.youtube.com/playlist?list=PLoKaNN3BjQX3fG-XOSwsPHtnV8FUY6lgK) course by lihautan covers the basics of Svelte Stores and best practices.
|
||||||
|
- [Svelte Events](https://www.youtube.com/watch?v=cbxxbBofjAw&feature=youtu.be) by WebJeda explains how directives like `on:` can be used to listen to DOM events.
|
||||||
|
- [How to Set Up Protected Routes in Your Svelte Application](https://www.webtips.dev/how-to-set-up-protected-routes-in-your-svelte-application) describes how to authenticate your users to access your routes
|
||||||
|
- [Using Fauna's streaming feature to build a chat with Svelte](https://dev.to/fauna/using-fauna-s-streaming-feature-to-build-a-chat-with-svelte-1gkd) demonstrates how to setup and configure Fauna to build a real-time chat interface with Svelte
|
||||||
|
- [Using TakeShape with Sapper](https://www.takeshape.io/articles/using-takeshape-with-sapper/) demonstrates how to connect the TakeShape CMS with Sapper
|
||||||
|
- [YastPack](https://github.com/rodabt/yastpack) is Yet Another Snowpack-Svelte-TailwindCss-Routify Template Pack
|
||||||
|
- [S2T2](https://ralphbliu.medium.com/s2t2-snowpack-svelte-tailwindcss-typescript-8928caa5af6c) is a Snowpack + Svelte + TailwindCSS + TypeScript template
|
||||||
|
- [tonyketcham/sapper-tailwind2-template](https://github.com/tonyketcham/sapper-tailwind2-template) is a Sapper Template w/ Tailwind 2.0, TypeScript, ESLint, and Prettier
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Got something to add? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!
|
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
title: SvelteKit is in public beta
|
||||||
|
description: And we'd love to have your feedback
|
||||||
|
author: Rich Harris
|
||||||
|
authorURL: https://twitter.com/rich_harris
|
||||||
|
---
|
||||||
|
|
||||||
|
<aside><p>Previously: <a href="/blog/whats-the-deal-with-sveltekit">What's the deal with SvelteKit?</a></p></aside>
|
||||||
|
|
||||||
|
It's time. After five months and hundreds of commits, you're finally invited to try out the SvelteKit beta. It's not finished — there are a few known bugs and several missing features — but we're really happy with how it's shaping up and can't wait for you to try it.
|
||||||
|
|
||||||
|
Starting a new project is easy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# create the project
|
||||||
|
mkdir my-app
|
||||||
|
cd my-app
|
||||||
|
npm init svelte@next
|
||||||
|
|
||||||
|
# install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# start dev server and open a browser tab
|
||||||
|
npm run dev -- --open
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll find documentation at [kit.svelte.dev/docs](https://kit.svelte.dev/docs). If you have a [Sapper](https://sapper.svelte.dev) app that you'd like to migrate to SvelteKit, you'll find instructions at [kit.svelte.dev/docs/migrating](https://kit.svelte.dev/docs/migrating).
|
||||||
|
|
||||||
|
The source code is available at [github.com/sveltejs/kit](https://github.com/sveltejs/kit). Issues and pull requests are disabled while we finish getting our house in order, but we'll be making it fully open in the near future.
|
||||||
|
|
||||||
|
|
||||||
|
## Wait, what is SvelteKit?
|
||||||
|
|
||||||
|
Think of it as [Next](https://nextjs.org/) for Svelte. It's a framework for building apps with Svelte, complete with server-side rendering, routing, code-splitting for JS and CSS, adapters for different serverless platforms and so on.
|
||||||
|
|
||||||
|
If you're familiar with [Sapper](https://sapper.svelte.dev), SvelteKit is Sapper's successor.
|
||||||
|
|
||||||
|
## From Snowpack to Vite
|
||||||
|
|
||||||
|
One thing that might seem surprising after the [announcement video](/blog/whats-the-deal-with-sveltekit), in which I waxed lyrical about [Snowpack](https://www.snowpack.dev/), is that SvelteKit uses [Vite](https://vitejs.dev) under the hood. When we tried Snowpack back when we started thinking about what form SvelteKit should take, it was love at first sight.
|
||||||
|
|
||||||
|
Snowpack created an entirely new category of dev tooling. Rather than _bundling_ your app in development, as we've been doing with webpack and Rollup for the last several years, Snowpack is an _unbundled dev server_ that uses the browser's native `import` and does 1:1 transformations of things like Svelte components on the fly. As a result you get quick startup, simple caching and instant hot module reloading. Once you experience this way of working, it will ruin you for anything else.
|
||||||
|
|
||||||
|
Vite falls into the same category as Snowpack. While Vite 1 wasn't suitable for SvelteKit — it was Vue-centric (Vite and Vue are both created by [Evan You](https://twitter.com/youyuxi)) and made server-side rendering difficult — Vite 2 is framework-agnostic and designed with SSR at the core. It also has powerful features, like CSS code-splitting, that we previously had to implement ourselves. When we evaluated the two technologies side-by-side we were forced to conclude that Vite is a closer match for SvelteKit's requirements and would give us the best chance to deliver the framework of our imaginations.
|
||||||
|
|
||||||
|
We owe a deep debt of gratitude to the Snowpack team, both for the close collaboration earlier in development and for lighting the path that web development will take over the next few years. It's a wonderful tool, and you should absolutely try it out.
|
||||||
|
|
||||||
|
|
||||||
|
## Dogfooding as extreme sport
|
||||||
|
|
||||||
|
SvelteKit is very much in beta, but that doesn't mean it hasn't been used in production.
|
||||||
|
|
||||||
|
My day job is at the New York Times, where I've spent much of the last twelve months working on our [coronavirus tracker](https://www.nytimes.com/interactive/2020/us/coronavirus-us-cases.html). It uses a customised version of the workflow that powers the majority of graphics at the Times, which isn't designed for large multi-page projects. When we decided late last year to create pages for each of the ~3,000 counties in the US, we quickly realised we would need to completely rearchitect the project.
|
||||||
|
|
||||||
|
Even though it was far from ready, SvelteKit was the only framework that matched our esoteric requirements. (Anyone who has worked in a newsroom and done battle with their CMS will know what I'm talking about.) Today it powers our [county risk pages](https://www.nytimes.com/interactive/2021/us/tom-green-texas-covid-cases.html) and we're in the process of migrating existing pages to the SvelteKit app.
|
||||||
|
|
||||||
|
<aside><p>I am eternally grateful for my coworkers' forbearance.</p></aside>
|
||||||
|
|
||||||
|
Using unfinished software to build an app that will be seen by millions of people is a risk, and in general I don't recommend it. But it has enabled us to develop the app much faster, and has made the framework itself much stronger than it otherwise would be.
|
||||||
|
|
||||||
|
## The road to 1.0
|
||||||
|
|
||||||
|
You can see the list of outstanding issues with the 1.0 milestone on our [issue tracker](https://github.com/sveltejs/kit/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0). Alongside that work, we plan to upgrade the documentation and add more [adapters](https://kit.svelte.dev/docs/adapters).
|
||||||
|
|
||||||
|
Most importantly though, we need your feedback to help us make the best possible app framework. Try it out, and let us know which pieces are missing.
|
||||||
|
|
||||||
|
Many thanks to everyone who has tried SvelteKit out despite the 'here be dragons' warnings and lack of documentation; your back-channel feedback has been invaluable. In particular, I want to acknowledge the work of [GrygrFlzr](https://github.com/GrygrFlzr), who maintained unofficial docs and a fork that added Windows support when we lacked it; and [dominikg](https://github.com/dominikg) whose work on [Svite](https://github.com/svitejs/svite) laid essential groundwork for SvelteKit's Vite integration. Both have now been welcomed onto the team.
|
@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: April 2021"
|
||||||
|
description: SvelteKit beta and new way to use slots
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Two projects that have been months (even years) in the making have made their way out into the world. SvelteKit is now in public beta and slotted components are now available in Svelte!
|
||||||
|
|
||||||
|
## What's up with SvelteKit?
|
||||||
|
[SvelteKit](https://kit.svelte.dev/) - Svelte's versatile framework for building SSR, serverless applications, or SPAs - is now officially in public beta. Expect bugs! Lots more detail in the [latest blog post](https://svelte.dev/blog/sveltekit-beta). Want to know when 1.0 is close? Check out the milestone on [github](https://github.com/sveltejs/kit/milestone/2).
|
||||||
|
|
||||||
|
Want to learn more about how to get started, what's different compared to Sapper, new features and migration paths? Check out this week's [episode of Svelte Radio](https://www.svelteradio.com/episodes/svelte-kit-public-beta) for a deep dive with Antony, Kev and Swyx.
|
||||||
|
|
||||||
|
## New in Svelte & Language Tools
|
||||||
|
- Slotted components, including `<svelte:fragment slot="...">` lets component consumers target specific slots with rich content (**Svelte 3.35.0, Language Tools [104.5.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.5.0)**, check out the [docs](https://svelte.dev/docs#template-syntax-svelte-fragment) and the [tutorial](https://svelte.dev/tutorial/svelte-fragment))
|
||||||
|
- Linked editing now works for HTML in Svelte files (**Language Tools, [104.6.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.6.0)**)
|
||||||
|
- Type definitions `svelte.d.ts` are now resolved in order, allowing library authors to ship type definitions with their svelte components (**Language Tools, [104.7.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.7.0)**)
|
||||||
|
- [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte) is available for general use of Svelte in Vite. `npm init @vitejs/app` includes Svelte options using this plugin.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
|
||||||
|
- [Nagato](https://nagato.app/) is a task management tool that connects popular time tracking and to-do tools all in one place.
|
||||||
|
- [type-kana](https://type-kana.cass.moe/setup) is a quiz app to help you learn ひらがな (hiragana) and カタカナ (katakana), the Japanese syllabaries.
|
||||||
|
- [Pittsburgh Steps](https://pittsburgh-steps.samlearner.com/) is an interactive map of the more than 800 sets of public outdoor stairways in Pittsburgh, PA.
|
||||||
|
- [Music Mode Wheels](https://tobx.github.io/music-mode-wheels/) is a website that displays music modes as interactive wheels.
|
||||||
|
- [Critical Notes](https://www.critical-notes.com/) helps game masters and players keep track of their roleplaying games campaigns and adventures.
|
||||||
|
- [Svelte Game of Life](https://github.com/alanrsoares/svelte-game-of-life) is an educational implementation of Conway's Game of Life in TypeScript + Svelte
|
||||||
|
- [foxql](https://github.com/foxql) is a peer to peer full text search engine that runs on your browser.
|
||||||
|
|
||||||
|
|
||||||
|
**Demos, Libraries, Tools & Components**
|
||||||
|
|
||||||
|
- [svelte-nodegui](https://github.com/nodegui/svelte-nodegui) is a way to build performant, native and cross-platform desktop applications with Node.js and Svelte
|
||||||
|
- [Svelte Story Format](https://www.npmjs.com/package/@storybook/addon-svelte-csf) allows you to write your "stories" in Storybook using the Svelte syntax. More info in the [Storybook blog](https://storybook.js.org/blog/storybook-for-svelte/)
|
||||||
|
- [SelectMadu](https://github.com/pavish/select-madu) is a replacement for the select menu, with support for searching, multiple selections, async data loading and more.
|
||||||
|
- [Svelte Checklist](https://www.npmjs.com/package/svelte-checklist) is a customizable CheckList built with Svelte.
|
||||||
|
- [Suspense for Svelte](https://www.npmjs.com/package/@jamcart/suspense) is a Svelte component that implements the core idea of React's `<Suspense>`.
|
||||||
|
- [MiniRx](https://spierala.github.io/mini-rx-store/) is a RxJS Redux Store that works with Svelte and TypeScript
|
||||||
|
- [svelte-formly](https://github.com/arabdevelop/svelte-formly) generates dynamic forms for Svelte and Sapper
|
||||||
|
- [7ty](https://www.npmjs.com/package/@jamcart/7ty) is a static site generator that uses Svelte, supports partial hydration of components, and uses file based routing resembling Sapper and 11ty.
|
||||||
|
|
||||||
|
**Want to contribute your own component?** Submit a [Component](https://sveltesociety.dev/components) to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
|
||||||
|
|
||||||
|
|
||||||
|
**Starters**
|
||||||
|
|
||||||
|
- [sveltekit-electron](https://github.com/FractalHQ/sveltekit-electron) is a starter kit for Electron using SvelteKit
|
||||||
|
- [sveltekit-tailwindcss-external-api](https://github.com/acidlake/sveltekit-tailwindcss-external-api) is everything you need to build a Svelte project with TailwindCSS and an external API, powered by create-svelte.
|
||||||
|
- [Sapper Netlify](https://www.npmjs.com/package/sapper-netlify) is a Sapper project that can run on a Netlify function.
|
||||||
|
|
||||||
|
|
||||||
|
**Looking for a particular starter?** Check out [svelte-adders](https://github.com/svelte-add/svelte-adders) and a number of other template examples at the community site [sveltesociety.dev](https://sveltesociety.dev/templates/)
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
- [How to Build a Website with Svelte and SvelteKit](https://prismic.io/blog/svelte-sveltekit-tutorial) is a step-by-step tutorial walking through the new SvelteKit setup.
|
||||||
|
- [A Svelte store for prefers-reduced-motion](https://geoffrich.net/posts/svelte-prefers-reduced-motion-store/) demonstrates how to make a custom Svelte store whose value will indicate whether the user has requested reduced motion and improve accessibility.
|
||||||
|
- [TypeScript support in Svelte](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript) is an MDN guide to using TypeScript in Svelte.
|
||||||
|
- [How to merge cells with svelte-window](https://gradientdescent.de/merging-cells/) is a walkthrough of svelte-window, a port of the popular react-window tool for merging table cells. For more on this migration, see [from react-window 1:1 to svelte-window](https://gradientdescent.de/porting-react-window/).
|
||||||
|
- [Easy-to-Embed Svelte Components](https://codeandlife.com/2021/03/06/easy-to-embed-svelte-components/) explains how to use Rollup and a script tag to embed Svelte components anywhere.
|
||||||
|
- [Convert Svelte project from Rollup to Snowpack](https://www.youtube.com/watch?v=-sHcqj4YLeQ) walks through a common migration pattern on video.
|
||||||
|
- [How to internationalize routing in Svelte & Sapper](https://www.leaf.cloud/blog/how-to-internationalize-routing-in-svelte-sapper?utm_medium=story&utm_source=reddit.com&utm_campaign=awareness&utm_content=sapper_routing) explains how leaf.cloud translated their site to Dutch.
|
||||||
|
- [Svelte Store: Reactive context using Svelte Store](https://www.youtube.com/watch?v=-rTnWlbdjoY) is a video answer to the question, "How do we make [a] context value reactive?"
|
||||||
|
- [Creating Social Sharing Images with Cloudinary and Svelte](https://www.youtube.com/watch?v=-Si5o-R7KHY) is a video from Cloudinary that demonstrates how to dynamically develop Open Graph images and Twitter Cards for a JAMstack website.
|
||||||
|
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Got something to add? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!
|
@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: May 2021"
|
||||||
|
description: Working toward SvelteKit 1.0 and a showcase full of SvelteKit sites!
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Last week, Svelte Summit blew us away with a mountain of content! [Check out the full recording](https://www.youtube.com/watch?v=fnr9XWvjJHw) or an audio-only (p)review [on Svelte Radio](https://www.svelteradio.com/episodes/svelte-summit-party-episode). Now let's get into this month's news...
|
||||||
|
|
||||||
|
## New features in the Svelte Compiler
|
||||||
|
- `:global()` is now supported as part of compound CSS selectors (**3.38.0**, [Example](https://svelte.dev/repl/54148fd2af484f2c84977c94e523c7c5?version=3.38.0))
|
||||||
|
- CSS custom properties can now be passed to components for use cases such as theming (**3.38.0**, [Docs coming soon](https://github.com/sveltejs/svelte/issues/6268))
|
||||||
|
|
||||||
|
## New in SvelteKit
|
||||||
|
- [kit.svelte.dev](https://kit.svelte.dev/) has a fresh new look and the [SvelteKit Demo Site](https://netlify.demo.svelte.dev/) got a fresh set of paint. Check it out by running `npm init svelte@next`
|
||||||
|
- You can now use `@sveltejs/adapter-static` to create a single-page app or SPA by specifying a fallback page ([PR](https://github.com/sveltejs/kit/pull/1181), [Docs](https://github.com/sveltejs/kit/tree/master/packages/adapter-static))
|
||||||
|
- Disable Server-side Rendering (SSR) app-wide or on a page-by-page basis ([PR](https://github.com/sveltejs/kit/pull/713))
|
||||||
|
- Error messages thrown during pre-rendering are now much more informative and readable ([PR](https://github.com/sveltejs/kit/pull/1062), [Docs](https://kit.svelte.dev/docs/layouts#error-pages))
|
||||||
|
- Layouts can now be reset to prevent pages from inheriting the root layout. This is useful if you have a specific layout for a page or i18n variation ([PR](https://github.com/sveltejs/kit/pull/1061), [Docs](https://kit.svelte.dev/docs/layouts#resets))
|
||||||
|
- `fetch` in SvelteKit code will now use the environment-provided implementation, whenever possible. If `fetch` is unavailable, it will be polyfilled by adapters ([PR](https://github.com/sveltejs/kit/pull/1066), [Docs](https://kit.svelte.dev/docs/loading#input-fetch))
|
||||||
|
|
||||||
|
## New in Svelte & Language Tools
|
||||||
|
- `svelte-preprocess` now supports the "extends" field of the tsconfig.json (4.7.2)
|
||||||
|
- HTML `style` attributes now have hover & auto-complete. Foreign namespaces and ESM configs are now supported in the Svelte language server & extensions
|
||||||
|
- The Svelte language tools can now infer slot/event types from their props if a generic relationship between them was defined
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
|
||||||
|
- [gitpod.io](https://github.com/gitpod-io/website) recently rewrote its site with SvelteKit
|
||||||
|
- [highlight eel](https://highlighteel.com/) is a web-based editor to mark your favorite parts of any YouTube video to clip and share with anyone
|
||||||
|
- [The Far Star Mission](https://thefarstar.apotheus.net/) is an interactive audiobook companion to the album, The Far Star by Apotheus
|
||||||
|
- [JavaScript quiz](https://github.com/nclskfm/javascript-quiz) is a small quiz application that saves your answers locally
|
||||||
|
- [ExtensionPay](https://extensionpay.com/) lets developers accept secure payments in browser extensions with no backend server code.
|
||||||
|
- [mk48.io](https://mk48.io/) is a naval warship game made with SvelteKit
|
||||||
|
- [Frog Safety](https://frog-safety.vercel.app/) is a guide for African Dwarf Frogs and the API freshwater master kit
|
||||||
|
- [Stardew Valley Character Preview](https://github.com/overscore-media/stardew-valley-character-preview) loads your character's attributes from your Stardew Valley savefile and lets you play around with different outfits, colours, and accessories.
|
||||||
|
|
||||||
|
|
||||||
|
**Demos, Libraries, Tools & Components**
|
||||||
|
|
||||||
|
- [svelte-parallax](https://github.com/kindoflew/svelte-parallax) is a spring-based parallax component for Svelte
|
||||||
|
- [@svelte-plugins/viewable](https://github.com/svelte-plugins/viewable) is a simple rule-based approach to tracking element viewability.
|
||||||
|
- [Sveltekit-JUI](https://github.com/Wolfr/sveltekit-jui) is a kit of UI components to be used in conjunction with Svelte and Svelte Kit.
|
||||||
|
- [EZGesture](https://github.com/mhmd-22/ezgesture#integrating-with-other-frameworks) makes it easy to add gestures functionality with simple native DOM events
|
||||||
|
|
||||||
|
**Want to contribute your own component?** Submit a [Component](https://sveltesociety.dev/components) to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
|
||||||
|
|
||||||
|
|
||||||
|
**Starters**
|
||||||
|
- [How to use Vercel Analytics with SvelteKit](https://ivoberger.com/posts/using-vercel-analytics-with-svelte-kit) teaches how to track Web Vitals across your users' devices
|
||||||
|
- [Asp.NETCore + Svelte + Vite](https://github.com/Kiho/aspcore-spa-cli/tree/master/samples/SviteSample) connects the three frameworks with SpaCliMiddleware (VS2019)
|
||||||
|
- [Add CoffeeScript to Svelte](https://github.com/Leftium/coffeescript-adder) is an experimental command to run to add CoffeeScript to your SvelteKit project or Vite-powered Svelte app
|
||||||
|
- [Adds Supabase to Svelte](https://github.com/joshnuss/svelte-supabase) is an experimental command to run to add Supabase to your SvelteKit project
|
||||||
|
- [svelte-babylon](https://github.com/SectorXUSA/svelte-babylon) lets you use BabylonJS like A-Frame through reactive Svelte Components
|
||||||
|
|
||||||
|
**Looking for a starter or integration?** Check out [svelte-adders](https://github.com/svelte-add/svelte-adders) and a number of other template examples at the community site [sveltesociety.dev](https://sveltesociety.dev/templates)
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
- [Amazing macOS Dock animation in Svelte](https://dev.to/puruvj/amazing-macos-dock-animation-in-svelte-5hfb) demonstrates how nice Svelte and popmotion look together
|
||||||
|
- [Solving the Tower of Hanoi with recursive Svelte templates](https://geoffrich.net/posts/svelte-tower-of-hanoi/) incorporates the `<svelte:self>` element into a common computer science problem
|
||||||
|
- [DIY SvelteKit CDK adapter](https://dev.to/juranki/diy-sveltekit-cdk-adapter-3enp) puts together SvelteKit and AWS CDK
|
||||||
|
- Fireship's [Svelte in 100 Seconds](https://www.youtube.com/watch?v=rv3Yq-B8qp4) is a quick and easy introduction to Svelte's core concepts
|
||||||
|
- [Tech Downtime](https://www.youtube.com/watch?v=tsePBA2JC7o&list=PLualcIC6WNK1LHIYx2Tg9AQfTQDv4zNPu) has been diving into SvelteKit in this playlist - from getting up and running to debugging.
|
||||||
|
- lihautan's latest video updates in the [Svelte 101](https://www.youtube.com/watch?v=rwYgOU0WmVk&list=PLoKaNN3BjQX3mxDEVG3oGJx2ByXnue_gR&index=59) and [Svelte Store](https://www.youtube.com/watch?v=p4GmT0trCPE&list=PLoKaNN3BjQX3fG-XOSwsPHtnV8FUY6lgK&index=19) playlists cover slots, stores and context - and when to use which
|
||||||
|
- [DavidParkerW](https://www.youtube.com/c/DavidParkerW/playlists) has been exploring Svelte, Sapper and SvelteKit in some real-world scenarios, like [displaying a blog post list from an API](https://www.youtube.com/watch?v=kAPVFgFnxaM&list=PLPqKsyEGhUna6cvm6d4vZNI6gbt_0S4Xx&index=15)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Got something to add? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!
|
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: June 2021"
|
||||||
|
description: Progress towards SvelteKit 1.0 and tighter TypeScript/Svelte integrations in language tools
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
This month, we saw lots of contributions to SvelteKit and its docs. The language tools also got some new features, most notably deeper integration with Svelte files within JavaScript or TypeScript files. Let's jump into the updates...
|
||||||
|
|
||||||
|
## New in SvelteKit
|
||||||
|
- `svelte.config.js` config files are now loaded in ESM format (`.js` instead of `.cjs`).
|
||||||
|
- AMP pages will now use the rendered CSS, rather than emitted CSS
|
||||||
|
- `svelte-check` has been added to the TypeScript template ([sveltejs/kit#1556](https://github.com/sveltejs/kit/pull/1556))
|
||||||
|
- Support for https keypair [sveltejs/kit#1456](https://github.com/sveltejs/kit/pull/1456)
|
||||||
|
- Now bundling Vite with SvelteKit and using an upgraded version. Remove Vite from your `package.json` if it's there
|
||||||
|
- Etags for binary responses [sveltejs/kit#1382](https://github.com/sveltejs/kit/pull/1382)
|
||||||
|
- Renamed `$layout` to `__layout` and `$error` to `__error`
|
||||||
|
- Removed `getContext` in favor of `request.locals`
|
||||||
|
- Renamed `.svelte` output directory to `.svelte-kit`. Update your `.gitignore` accordingly
|
||||||
|
- `trailingSlash: 'never' | 'always' | 'ignore'` is now available in the config. This should make it easier to build sites that work with static hosting providers that expect a trailing slash for `index.html` pages, and provides an escape hatch for anyone that needs more complex behaviour.
|
||||||
|
|
||||||
|
## Notable bug fixes in SvelteKit
|
||||||
|
- `adapter-netlify` got a fix [sveltejs/kit#1467](https://github.com/sveltejs/kit/pull/1467) and new documentation in the readme https://github.com/sveltejs/kit/tree/master/packages/adapter-netlify
|
||||||
|
- The router will no longer intercept navigation for URLs that the app does not own. This fixes a crash for apps that have `<a>` elements on the page with the same origin but don't share a base path with the app.
|
||||||
|
- Hash only changes are now handled by the router fixing the browser's "back" navigation between hash changes in some circumstances.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## New in Svelte & Language Tools
|
||||||
|
- Svelte 3.38.1 and 3.38.2 fixed an issue with hydration that was causing duplicate elements. If you're seeing this in your project, be sure to update the latest version!
|
||||||
|
- A new TypeScript plugin provides deeper integration with Svelte files within JavaScript or TypeScript files. This includes diagnostics, references and renaming of variables. It comes packaged with the VS Code extension but is turned off by default for now. You can enable it through [this setting](https://github.com/sveltejs/language-tools/tree/master/packages/svelte-vscode#svelteenable-ts-plugin). We encourage you to test it out and [provide feedback](https://github.com/sveltejs/language-tools/issues/580)
|
||||||
|
- In the latest version of `svelte-check` you can now provide the path to your `tsconfig.json` or `jsconfig.json`. Example: `svelte-check --tsconfig "./tsconfig.json"`. This ensures the diagnostics are only run on files that are referenced in that config. It also runs diagnostics on JavaScript and/or TypeScript files which removes the need to run another check (like `tsc --noEmit`) for non-Svelte files (`svelte-check` version [**1.6.0**](https://github.com/sveltejs/language-tools/releases/tag/svelte-check-1.6.0))
|
||||||
|
- The VS Code extension and `svelte-check` got a new major release. Previously, properties that had no initializer (`export let foo;`) were only required if the user was using both TypeScript and activated `strict` mode. This is changed now: People using TypeScript, and those using `checkJs` also in JavaScript files, will now always have these properties marked as required (`svelte-check` version [**2.0.0**](https://github.com/sveltejs/language-tools/releases/tag/svelte-check-2.0.0), extension version [**105.0.0**](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.0.0))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
|
||||||
|
- [vidu](https://github.com/pa-nic/vidu) is a minimal web analytics collector and dashboard
|
||||||
|
- [River Runner](https://river-runner.samlearner.com/) is a virtual way to follow rivers downstream - built with Mapbox and Svelte.
|
||||||
|
- [JSDoc Type Generator](https://rafistrauss.github.io/jsdoc-generator/) generates JSDoc types for valid JSON.
|
||||||
|
- [pagereview.io](https://pagereview.io/) is a website feedback tool that lets you leave comments directly on the site being reviewed.
|
||||||
|
- [gamesroom.io](https://gamesroom.io/) is an online board game platform with video chat built-in.
|
||||||
|
- [Greedy Goblin](https://greedygoblin-fe11c.web.app/) is a recipe app for old-school Runescape players.
|
||||||
|
- [hashbrown.geopjr.dev](https://hashbrown.geopjr.dev/) is a GNOME-shell inspired webpage to learn about, explore the source code and download the Hashbrown GTK app ([link to source](https://github.com/GeopJr/Hashbrown/tree/website)).
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
|
||||||
|
- [svelte-image-crop](https://novacbn.github.io/svelte-image-crop/) is a simple click'n'drag image cropping library using Web APIs.
|
||||||
|
- [svelte-datepicker](https://github.com/andrew-secret/svelte-datepicker) is a lightweight and inclusive date picker build with Svelte.
|
||||||
|
- [svelte-regex-router](https://www.npmjs.com/package/svelte-regex-router) is a simple, lightweight library for you to easily handle routes in your Svelte application.
|
||||||
|
- [Svelte Micro](https://www.npmjs.com/package/svelte-micro) is a light & reactive one-component router for Svelte.
|
||||||
|
- [svelte-entity-store](https://www.npmjs.com/package/svelte-entity-store) is to provide a simple, generic solution for storing collections of entity objects.
|
||||||
|
- [svelte-animation-store](https://github.com/joshnuss/svelte-animation-store) is a store that is based on Svelte's tweened store, that lets you pause, continue, reset, replay, reverse or adjust speed of a tween.
|
||||||
|
|
||||||
|
|
||||||
|
**Want to contribute a component?** Submit a [Component](https://sveltesociety.dev/components) to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
|
||||||
|
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Did we miss something? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!
|
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: July 2021"
|
||||||
|
description: Keeping cool with fixes, TypeScript tooling and tonnes of new features
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
As the northern hemisphere heats up, Svelte has stayed cool with lots of performance and bug fixes, better TypeScript support, and lots of new components & tools from around the ecosystem. Let's take a peek 👀
|
||||||
|
|
||||||
|
## New in SvelteKit
|
||||||
|
- `adapter-node` now precompresses assets using gzip & brotli ([#1693](https://github.com/sveltejs/kit/pull/1693))
|
||||||
|
- Support for TypeScript transpilation has been added to the `svelte-kit package` tooling ([#1633](https://github.com/sveltejs/kit/pull/1633))
|
||||||
|
- Improved caching defaults in `adapter-node` ([#1416](https://github.com/sveltejs/kit/pull/1416))
|
||||||
|
- Allow configuring Rollup output options ([#1572](https://github.com/sveltejs/kit/pull/1572))
|
||||||
|
- Fixed usage of SSL with HMR ([#1517](https://github.com/sveltejs/kit/pull/1517))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Features & bug fixes from around svelte/*
|
||||||
|
- [Svelte 3.38.3](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md#3383) (released June 22) includes a bunch of performance and bug fixes - including hydration optimizations, `this` preservation in bubbled events, and more!
|
||||||
|
- The latest language tools releases added support for prop renaming from outside of a component, PostCSS syntax grammar, and a `.d.ts` output target in `svelte2tsx` which can be used to create type definitions from Svelte files.
|
||||||
|
- Also in language tools, some long-awaited experimental features for enhanced TypeScript support were added - including explicitly typing all possible component events or slots, and using generics. Have a look at [the RFC](https://github.com/sveltejs/rfcs/pull/38) for more details and leave feedback in [this issue](https://github.com/sveltejs/language-tools/issues/442) if you are using it.
|
||||||
|
- `svelte-scroller` got some quality-of-life fixes in 2.0.7 - fixing an initial width bug and updating its `index` more conservatively
|
||||||
|
|
||||||
|
|
||||||
|
## Coming soon to Svelte
|
||||||
|
- Constants in markup ([RFC](https://github.com/sveltejs/rfcs/blob/master/text/0000-markup-constants.md)): Adds a new `{@const ...}` tag that defines a local constant ([PR](https://github.com/sveltejs/svelte/pull/6413))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [SvelteThemes](https://sveltethemes.dev/) is a curated list of Svelte themes and templates built using svelte, sveltekit, elderjs, routify etc.
|
||||||
|
- [Beatbump](https://github.com/snuffyDev/Beatbump) is an alternative frontend for YouTube Music created using Svelte/SvelteKit.
|
||||||
|
- [Sveltuir](https://github.com/webspaceadam/sveltuir) is an app help you memorize the guitar fretboard
|
||||||
|
|
||||||
|
|
||||||
|
**Educational Content**
|
||||||
|
- [Svelte Radio: A Jolly Good Svelte Summer](https://share.transistor.fm/s/60880542) is a conversation about what's new in Svelte and a celebration of Svelte Radio's 1-year anniversary
|
||||||
|
- [Class properties in Svelte](https://navillus.dev/blog/svelte-class-props) is a refresher on the power of `class` for developers switching over to Svelte from React
|
||||||
|
- [Sveltekit Tutorial for Beginners](https://www.youtube.com/playlist?list=PLm_Qt4aKpfKjf77S8UD79Ockhwp_699Ms) is a video playlist for learning SvelteKit by WebJeda
|
||||||
|
- [How To Cache Dynamic Pages On Demand With A Service Worker In SvelteKit](https://jochemvogel.medium.com/how-to-cache-dynamic-pages-on-demand-with-a-service-worker-in-sveltekit-4b4a7652583d) walks through the power of service workers when used within SvelteKit for on-demand caching
|
||||||
|
- [Vue vs Svelte: Comparing Framework Internals](https://www.vuemastery.com/blog/vue-vs-svelte-comparing-framework-internals/) dives deep into the differences between Vue and Svelte from the inside out
|
||||||
|
- [Setting up a development environment for SvelteKit with Docker and Docker Compose](https://jenyus.web.app/blog/2021-05-30-setting-up-a-development-environment-for-sveltekit-with-docker-and-compose) walks through how to use Docker to create reusable development environments, no matter what kind of device you run your code on
|
||||||
|
- Scalable Scripts released three videos this month documenting how to deploy dockerized Svelte Apps to [AWS](https://youtu.be/VOs2Od5jYOc), [Azure](https://youtu.be/gdg4ne_uDm8) and [Google Cloud](https://youtu.be/_-uBb61Tikw)
|
||||||
|
- [Render Katex with Svelte from zero to hero](https://www.youtube.com/watch?v=euowJs9CblA) demonstrates how to implement Katex in a Svelte project
|
||||||
|
- [Using Custom Elements in Svelte](https://css-tricks.com/using-custom-elements-in-svelte/) shows some of the quirks to look out for when using custom elements in a Svelte site
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [svelte-pipeline](https://github.com/novacbn/svelte-pipeline) provides custom JavaScript contexts and the Svelte Compiler as Svelte Stores, for REPLs, Editors, etc.
|
||||||
|
- [Sveltotron](https://github.com/Salemmous/sveltotron) is an Electron-based app made to inspect your Svelte app
|
||||||
|
- [svelte-qr-reader-writer](https://github.com/pleasemarkdarkly/svelte-qr-reader-writer) is a Svelte component that helps read and write data from QR codes
|
||||||
|
- [svelte-stack-router](https://www.npmjs.com/package/svelte-stack-router) Aims to make Svelte apps feel more native by routing with Stacks
|
||||||
|
- [svelte-typed-context](https://www.npmjs.com/package/svelte-typed-context) provides an interface which, when provided to `getContext` or `setContext`, allows for stricter types
|
||||||
|
- [svelte-modals](https://svelte-modals.mattjennings.io/) is a simple, flexible, zero-dependency modal manager for Svelte
|
||||||
|
|
||||||
|
|
||||||
|
**Want to contribute a component? Interested in helping make Svelte's presence on the web better?** Submit a Component to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety-2021/blob/main/src/routes/components/components.json) or check out [the list of open issues](https://github.com/svelte-society/sveltesociety-2021/issues) if you'd like to contribute to the Svelte Society rewrite in SvelteKit.
|
||||||
|
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Want more updates? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs)!
|
@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: August 2021"
|
||||||
|
description: Shadow DOM, export and await - oh my!
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
From The Changelog ([JS Party Ep. 182](https://changelog.com/jsparty/182)) to Svelte Radio (Episodes [29](https://share.transistor.fm/s/adc23e84) and [30](https://share.transistor.fm/s/6316622d)), it seems that folks couldn't help but talk about Svelte, this month! Also, shadow DOM support and new export and await functionality are new in Svelte.
|
||||||
|
|
||||||
|
## New in Svelte
|
||||||
|
|
||||||
|
July was the most active month for the Svelte core repo since late 2019 as we really worked to reduce the number of outstanding PRs and saw the release of Svelte 3.39.0, 3.40.0, and 3.41.0. Tons of bug fixes were added as well as the following new features:
|
||||||
|
|
||||||
|
- The `|trusted` event modifier allows you to check if an event is trusted before it's called ([#6137](https://github.com/sveltejs/svelte/issues/6137))
|
||||||
|
- The new `svelte/ssr` package to support work on improving SvelteKit SSR ([#6416](https://github.com/sveltejs/svelte/pull/6416))
|
||||||
|
- A new `errorMode` compiler option to support improved preprocessing of TypeScript files ([#6194](https://github.com/sveltejs/svelte/pull/6194))
|
||||||
|
- You can now specify a `ShadowRoot` as the `target` when creating a component - making it possible to render Svelte components inside the shadow DOM ([#5869](https://github.com/sveltejs/svelte/issues/5869))
|
||||||
|
- The `export { ... } from` ([#2214](https://github.com/sveltejs/svelte/issues/2214)), `export let { ... } =` ([#5612](https://github.com/sveltejs/svelte/issues/5612)) and `{#await ... then/catch}` ([#6270](https://github.com/sveltejs/svelte/issues/6270)) syntaxes are all now supported in Svelte components
|
||||||
|
|
||||||
|
For a full list of features and bug fixes, check out the [Svelte changelog](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
## SvelteKit Updates
|
||||||
|
- `prerender.force` is now `prerender.onError` which lets you fine-tune which errors fail the build and which do not ([#2007](https://github.com/sveltejs/kit/pull/2007))
|
||||||
|
- esbuild's configuration is now exposed for use with SvelteKit adapters ([#1914](https://github.com/sveltejs/kit/pull/1914))
|
||||||
|
- Error messages are friendlier now for common config errors ([#1910](https://github.com/sveltejs/kit/pull/1910)) and compiler errors ([#1827](https://github.com/sveltejs/kit/pull/1827))
|
||||||
|
- Cookies will only be passed through if the target host is the same as the SvelteKit application or a more specific subdomain of it ([#1847](https://github.com/sveltejs/kit/pull/1847))
|
||||||
|
- index.js exports will now be changed to directory exports when packaging - making for nicer imports ([#1905](https://github.com/sveltejs/kit/pull/1905))
|
||||||
|
- Vite.js's `mode` is now exposed from `$app/env` ([#1789](https://github.com/sveltejs/kit/pull/1789))
|
||||||
|
- Better types across the board ([#1778](https://github.com/sveltejs/kit/pull/1778), [#1791](https://github.com/sveltejs/kit/pull/1791), [#1646](https://github.com/sveltejs/kit/pull/1646))
|
||||||
|
|
||||||
|
To see all updates to SvelteKit, check out the [SvelteKit changelog](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).
|
||||||
|
|
||||||
|
## Features & bug fixes from around svelte/*
|
||||||
|
- Language Tools now better support the "Workplace Trust" functionality (used in VS Code)
|
||||||
|
- In svelte2tsx, ambient type declarations are now renamed to avoid conflicting declarations in the future. Users are now expected to provide the ambient type definitions themselves - fixing JS output
|
||||||
|
- Sapper released v0.29.2 which fixes regex routes, status codes when requesting a directory, and exports when a user has not provided a `base` tag ([changelog](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [Parsnip](https://www.parsnip.ai/) is a mobile-first, progressive-web-app that helps you to learn to cook at home. Check out the [conversation on Reddit](https://www.reddit.com/r/sveltejs/comments/oearb9/learning_to_cook_at_home_with_parsnip_built/) for all the geeky details.
|
||||||
|
- [Central Bank Digital Currency (CBDC) tracker](https://www.atlanticcouncil.org/cbdctracker/) is a site that keeps track of how countries around the world are adopting digital currencies.
|
||||||
|
- [Svelte Commerce](https://github.com/itswadesh/svelte-commerce) is an advanced frontend platform for eCommerce based on Sveltekit.
|
||||||
|
- [neovimcraft](https://neovimcraft.com/) is a SvelteKit site dedicated to neovim plugins
|
||||||
|
|
||||||
|
**Looking for a Svelte project to work on? Interested in helping make Svelte's presence on the web better?** Check out [the list of open issues](https://github.com/svelte-society/sveltesociety-2021/issues) if you'd like to contribute to the Svelte Society rewrite in SvelteKit.
|
||||||
|
|
||||||
|
**Educational Content**
|
||||||
|
- [How I Built a Cross-Platform Desktop Application with Svelte, Redis, and Rust](https://css-tricks.com/how-i-built-a-cross-platform-desktop-application-with-svelte-redis-and-rust/) is a blog post by Luke Edwards, Svelte maintainer and Developer Advocate from Cloudflare.
|
||||||
|
- [How to Create a Blog with SvelteKit and Strapi](https://strapi.io/blog/how-to-create-a-blog-with-svelte-kit-strapi) is a step-by-step tutorial by Aarnav Pai from Strapi
|
||||||
|
- [Sveltekit Markdown Blog](https://www.youtube.com/watch?v=sKKgT0SEioI&list=PLm_Qt4aKpfKgonq1zwaCS6kOD-nbOKx7V) is a YouTube tutorial series by WebJeda.
|
||||||
|
- [Using Custom Elements in Svelte](https://css-tricks.com/using-custom-elements-in-svelte/) is a deep dive into custom elements by Geoff Rich.
|
||||||
|
- [learn / graphql / svelte](https://hasura.io/learn/graphql/svelte-apollo/introduction/) is a free 2-hour GraphQL course from Hasura.
|
||||||
|
- [How to add Magic Link to a SvelteKit application](https://magic.link/posts/magic-svelte) is a guide to the popular password-less login pattern.
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [Svelte-Capacitor](https://github.com/drannex42/svelte-capacitor/) just released v2.0.0 - making it even easier to build hybrid mobile apps for iOS and Android using Svelte and Capacitor with near native performance.
|
||||||
|
- [svelte-remixicon](https://github.com/ABarnob/svelte-remixicon) is an icon library for Svelte based on Remix Icon, consisting of more than 2000 icons.
|
||||||
|
- [SveltePress](https://github.com/GeopJr/SveltePress) is a documentation tool built on top of SvelteKit.
|
||||||
|
- [Svelte Starter Kit](https://github.com/one-aalam/svelte-starter-kit/tree/auth-supabase) is a boilerplate to quickly get up and running with Svelte, with Auth and User Profiles powered by Supabase.
|
||||||
|
- [Kahi UI](https://github.com/novacbn/kahi-ui) is a Svelte-first UI kit with Dark Mode built-in.
|
||||||
|
- [typesafe-i18n](https://github.com/ivanhofer/typesafe-i18n) is an opinionated, fully type-safe, lightweight localization library for TypeScript and JavaScript projects with no external dependencies.
|
||||||
|
|
||||||
|
Check out the community site [sveltesociety.dev](https://sveltesociety.dev/templates/) for more templates, adders and adapters from across the Svelte ecosystem.
|
||||||
|
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Want more updates? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs)!
|
@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: September 2021"
|
||||||
|
description: StackOverflow's most loved web framework
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
This month, Svelte was [voted StackOverflow's most loved web framework](https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-web-frameworks), Tan Li Hau [talked to Svelte Radio](https://share.transistor.fm/s/84c7521b) about his [Svelte-filled YouTube channel](https://www.youtube.com/channel/UCbmC3HP3FaAFdcZkui8YoMQ), and SvelteKit made even more progress towards its 1.0 release!
|
||||||
|
|
||||||
|
## New in Svelte
|
||||||
|
|
||||||
|
- `use:actions` can now be used on `<svelte:body>` (**3.42.0**)
|
||||||
|
- `HTMLElement`, `SVGElement` (**3.42.2**) and `BigInt` (**3.42.3**) are now known globals
|
||||||
|
- There is less code in Svelte's output thanks to the following improvements in **3.42.2**:
|
||||||
|
- Whitespace is now collapsed in class and style attributes
|
||||||
|
- Hydrated components have been updated to only rely upon helpers for creating the types of elements present in the component
|
||||||
|
- Scaling is now accounted for in `flip` animations (**3.42.2**)
|
||||||
|
- All `<option>`s in a `<select>` are now deselected when the bound value doesn't match any of them (**3.42.2**)
|
||||||
|
|
||||||
|
For a full list of features and bug fixes, check out the [Svelte changelog](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
## SvelteKit Updates
|
||||||
|
|
||||||
|
Svelte maintainers are [looking for help getting SvelteKit to 1.0](https://github.com/sveltejs/kit/issues/2100). We've knocked out over 100 issues that were on the 1.0 milestone. There's only a couple dozen left and we'd love a hand making that list a bit shorter!
|
||||||
|
|
||||||
|
If you'd like to help, please consider working on any of the [1.0 milestone issues](https://github.com/sveltejs/kit/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0).
|
||||||
|
|
||||||
|
The focus this past month was on continuing to iron out any kinks, with well over 100 PRs merged. A few new features went in as well...
|
||||||
|
|
||||||
|
- SvelteKit will now detect if a prerendered app is trying to access a query parameter and return an error instead of failing silently ([#2104](https://github.com/sveltejs/kit/pull/2104))
|
||||||
|
- `adapter-node` now lets you [add the Kit middleware to your own server](https://kit.svelte.dev/faq#integrations) for use with other middleware. You can also [add middleware in dev mode](https://kit.svelte.dev/faq#how-do-i-use-x-with-sveltekit-how-do-i-use-middleware) with more improvements to come in this area
|
||||||
|
- The new [`sequence` helper lets you chain together multiple `handle` calls](https://kit.svelte.dev/docs/modules#sveltejs-kit-hooks)
|
||||||
|
- A new [`handleError` hook](https://kit.svelte.dev/docs/hooks#handleerror) gives you the option to send data to an error tracking service, or to customise the formatting before printing the error to the console.
|
||||||
|
- `adapter-node` can now listen on socket path ([#2048](https://github.com/sveltejs/kit/pull/2048))
|
||||||
|
|
||||||
|
To see all updates to SvelteKit, check out the [SvelteKit changelog](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [macos-web](https://github.com/PuruVJ/macos-web) by @puruvjdev has been rebuilt with Svelte from the ground up. Check out all the details in this [Twitter thread](https://twitter.com/puruvjdev/status/1426267327687847939)
|
||||||
|
- [Brave Search](https://search.brave.com/) is using Svelte
|
||||||
|
- [exatorrent](https://github.com/varbhat/exatorrent) is a self-hostable, easy-to-use, lightweight and feature-rich torrent client written in Go and Svelte
|
||||||
|
- [json2TsTypes](https://github.com/jatinhemnani01/json2TsTypes) is a simple tool which will convert your JSON to TypeScript Types/Interfaces
|
||||||
|
- [Histogram.dev](https://histogram.dev/) generates histograms for each feature in a CSV
|
||||||
|
- [cybernetic.dev](https://cybernetic.dev/) is a collection of data-centric UI experiments made while learning Svelte
|
||||||
|
- [LunaNotes](https://chrome.google.com/webstore/detail/lunanotes-youtube-video-n/oehoffnnkgcdacmbkhmlbjedinpampak?hl=en) is a Chrome extension to help with taking YouTube video notes
|
||||||
|
- [theia.games](https://theia.games/#dev)'s built-in 3D environment editor lets you create a VR world with a menu built in Svelte
|
||||||
|
- [Ferrum](https://github.com/probablykasper/ferrum) is a music library and player available for Mac, Windows or Linux
|
||||||
|
- [Fluid Earth](https://github.com/byrd-polar/fluid-earth) is an interactive WebGL application for visualizing Earth's atmosphere and oceans
|
||||||
|
|
||||||
|
**Looking for a Svelte project to work on? Interested in helping make Svelte's presence on the web better?** Check out [the list of open issues](https://github.com/svelte-society/sveltesociety-2021/issues) if you'd like to contribute to the Svelte Society rewrite in SvelteKit.
|
||||||
|
|
||||||
|
**Educational Content**
|
||||||
|
- [Tauri with Standard Svelte or SvelteKit](https://medium.com/@cazanator/tauri-with-standard-svelte-or-sveltekit-ad7f103c37e7) walks through how to setup Svelte with Tauri, a new light-weight framework for developing cross-platform hybrid desktop applications
|
||||||
|
- [Svelte - Web App Development Reimagined [An Intro to Svelte]](https://www.youtube.com/watch?v=4CGzFwHoD0A&list=PLEx5khR4g7PKSASVAXXiAhkyx02_OeruP) is a great intro talk from the goto; conference
|
||||||
|
- [LevelUpTuts - Even More 5 Things I Like More In Svelte Than React](https://www.youtube.com/watch?v=ISmnG2sIOeM) highlights Svelte's approach to refs (don't need them), meta tags and more
|
||||||
|
- [State Management in Svelte Applications](https://auth0.com/blog/state-management-in-svelte-applications/) is a tutorial on how to use the Svelte state management store to manage state in Svelte applications
|
||||||
|
- [Migrating from Sapper to SvelteKit](https://shipbit.de/blog/migrating-from-sapper-to-svelte-kit/) is a review and retrospective of ShipBit's migration from Sapper
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [svelte-stripe-js](https://github.com/joshnuss/svelte-stripe-js) is everything you need to add Stripe to your Svelte project. 100% SvelteKit compatible
|
||||||
|
- [svelte-steps](https://github.com/shaozi/svelte-steps) is a customizable step component written in Svelte
|
||||||
|
- [simple-optics-module](https://gitlab.com/Samzelot/simple-optics-module) is an online open source optics tool for experimenting and teaching geometrical optics
|
||||||
|
- [inlang](https://github.com/samuelstroschein/inlang) is an internationalization (i18n) tool for SvelteKit apps
|
||||||
|
- [Sveno](https://github.com/pocinnovation/sveno) is a component transpiler that transforms React components to Svelte components
|
||||||
|
- [svelte-useactions](https://github.com/paolotiu/svelte-useactions) is a fully typed library for passing actions to components
|
||||||
|
- [Svelte-Element-Query](https://github.com/leveluptuts/Svelte-Element-Query) is a 322b library/action for element queries
|
||||||
|
- [svelte-meta-tags](https://github.com/oekazuma/svelte-meta-tags) is a plug-in that makes managing SEO easier in Svelte projects
|
||||||
|
- [svelte-domtree](https://github.com/alex-knyaz/svelte-domtree) lets you visualize the DOM - similar to DOM tree in Chrome DevTools
|
||||||
|
- [Diffx](https://github.com/jbjorge/diffx/tree/master/svelte), a cross-framework state management library, just added Svelte support
|
||||||
|
- [svelte-ionic-starter](https://github.com/Zettexe/svelte-ionic-starter) a project template for Svelte + Ionic + CapacitorJS apps with live reload and iOS/Android build targets
|
||||||
|
- [demo-sveltekit-sanity](https://github.com/stephane-vanraes/demo-sveltekit-sanity/) is a starter kit for SvelteKit and Sanity, an open source React CMS
|
||||||
|
|
||||||
|
Check out the community site [sveltesociety.dev](https://sveltesociety.dev/templates/) for more templates, adders and adapters from across the Svelte ecosystem.
|
||||||
|
|
||||||
|
|
||||||
|
## See you next month!
|
||||||
|
|
||||||
|
Want more updates? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs)!
|
@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: October 2021"
|
||||||
|
description: A whole year of "What's new in Svelte"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Hey y'all 👋 It's been 1 year since "What's new in Svelte" started being cross-posted to the Svelte blog. I wanted to take this moment at the top to thank all of you for reading and for all the contributors every month. From the maintainers to everyone who posts their work in the Discord and Reddit, it's amazing to witness all the effort that goes into making the Svelte community great.
|
||||||
|
|
||||||
|
Keep up the good work, everyone! Now, let's dive into this month's news...
|
||||||
|
|
||||||
|
## New around Svelte
|
||||||
|
|
||||||
|
- New additions to Svelte's export map now expose no-op versions of lifecycle functions for SSR (Svelte **3.43.0**)
|
||||||
|
- Custom components with a `src` attribute no longer break `svelte-native` builds (Svelte **3.42.4**)
|
||||||
|
- Svelte plugin users without [the TypeScript plugin](https://www.npmjs.com/package/typescript-svelte-plugin) enabled will now be prompted to enable it. It enhances TypeScript and JavaScript files with additional intellisense to interact with Svelte files. [Please leave feedback](https://github.com/sveltejs/language-tools/issues/580) if you are using it (Svelte extensions **105.4.0**)
|
||||||
|
- Event modifiers have been added to intellisense as autocomplete and hover info (Svelte extensions **105.4.0**)
|
||||||
|
- TypeScript users no longer have to strictly separate type imports and value imports when using Svelte version 3.39 or higher and `svelte-preprocess` version 4.9.5 or higher. This means you can now write `import { MyInterface, myValue } from './somewhere'` instead of `import type { MyInterface } from './somewhere'; import { myValue } from './somewhere'`. Huge thanks to community member [@SomaticIT](https://github.com/SomaticIT) who mainly implemented this!
|
||||||
|
|
||||||
|
For a full list of features and bug fixes, check out the [Svelte changelog](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
## SvelteKit Updates
|
||||||
|
|
||||||
|
Nearly 100 PRs committed again this past month, but there's still lots to do and Svelte maintainers are [looking for help getting SvelteKit to 1.0](https://github.com/sveltejs/kit/issues/2100). Antony said it well in a [recent comment](https://github.com/sveltejs/kit/issues/2100#issuecomment-895446285) on the issue:
|
||||||
|
|
||||||
|
> If you think you are too n00b to contribute (you're not), then add tests, or write tests for the feature you want to add, before you add it! Start small, and learn the codebase that way.
|
||||||
|
|
||||||
|
If you'd like to help, please consider working on any of the [1.0 milestone issues labeled with "help wanted"](https://github.com/sveltejs/kit/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0+label%3A%22help+wanted%22).
|
||||||
|
|
||||||
|
Notable SvelteKit improvements this month include...
|
||||||
|
|
||||||
|
- Service workers are now allowed to access files using the `$lib` alias ([#2326](https://github.com/sveltejs/kit/pull/2326))
|
||||||
|
- Svelte libraries should now work out-of-the-box without any Vite configuration ([#2343](https://github.com/sveltejs/kit/pull/2343))
|
||||||
|
- Improvements to package exports field ([#2345](https://github.com/sveltejs/kit/pull/2345) and [#2327](https://github.com/sveltejs/kit/pull/2327))
|
||||||
|
- [breaking] The `prerender.pages` config option has been renamed to `prerender.entries` ([#2380](https://github.com/sveltejs/kit/pull/2380))
|
||||||
|
- A new generic argument has been added to allow typing Body from hooks ([#2413](https://github.com/sveltejs/kit/pull/2413))
|
||||||
|
- The `svelte` field will be added to package.json when running the package command ([#2431](https://github.com/sveltejs/kit/pull/2431))
|
||||||
|
- [breaking] The `context` parameter of the load function was renamed to `stuff` ([#2439](https://github.com/sveltejs/kit/pull/2439))
|
||||||
|
- Added an `entryPoint` option for building a custom server with `adapter-node` ([#2414](https://github.com/sveltejs/kit/pull/2414))
|
||||||
|
- `vite-plugin-svelte` improved support for [useVitePreprocess](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#usevitepreprocess), which uses Vite to automatically preprocess TypeScript, PostCSS, Scss, etc in Svelte components ([#173](https://github.com/sveltejs/vite-plugin-svelte/pull/173))
|
||||||
|
|
||||||
|
To see all updates to SvelteKit, check out the [SvelteKit changelog](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [radiofrance](https://www.radiofrance.fr/) just migrated their website to SvelteKit
|
||||||
|
- [FLAYKS](https://flayks.com/) is the portfolio site for Félix Péault made with SvelteKit, Sanity, and Anime.js
|
||||||
|
- [hirehive](https://www.hirehive.com/) is a candidate and job tracking site
|
||||||
|
- [Microsocial](https://microsocial.xyz/) is an experimental Peer-to-Peer Social Platform
|
||||||
|
- [Dylan Ipsum](https://www.dylanlyrics.app/) is a random text generator to replace lorem ipsum with Bob Dylan lyrics
|
||||||
|
- [Chip8 Svelte](https://github.com/mikeyhogarth/chip8-svelte) is a CHIP-8 emulator frontend, built on top of CHIP8 TypeScript
|
||||||
|
|
||||||
|
**Looking for a Svelte project to work on? Interested in helping make Svelte's presence on the web better?** Check out [the list of open issues](https://github.com/svelte-society/sveltesociety-2021/issues) if you'd like to contribute to the Svelte Society rewrite in SvelteKit.
|
||||||
|
|
||||||
|
**Podcasts Featuring Svelte**
|
||||||
|
- [Syntax Podcast: From React to SvelteKit](https://podcasts.apple.com/us/podcast/from-react-to-sveltekit/id1253186678?i=1000536276106) Scott talks with Wes about moving Level Up Tutorials from React to SvelteKit — why he did it, how, benefits, things to watch out for, and more!
|
||||||
|
- [Web Rush Podcast: Svelte Tools and Svelte Society](https://www.webrush.io/episodes/episode-150-svelte-tools-and-svelte-society) Kevin Åberg Kultalahti talks about what Svelte Society is, what he's excited about with Svelte, how important documentation is to any product, and much _much_ more
|
||||||
|
- [Svelte: The Compiled Future of Front End](https://www.arahansen.com/the-compiled-future-of-front-end/) details the history of component-based frontends and how a compiler changes everything
|
||||||
|
- [Svelte Radio: Contributing to Svelte with Martin 'Grygrflzr' Krisnanto Putra](https://share.transistor.fm/s/10aa305c) Grygrflzr shares his journey to becoming a maintainer and his views on React, Vite and a host of other things
|
||||||
|
- [Svelte Radio: Routify 3 with Jake and Willow](https://share.transistor.fm/s/10aa305c) the Svelte Radio crew sits down with the maintainers of Routify and discusses the just-released Routify 3
|
||||||
|
- [JS Party: 1Password](https://twitter.com/geoffrich_/status/1441816829853253640?s=20) mentioned on the latest episode of The Changelog's JS Party that they use Svelte to power their in-page suggestions
|
||||||
|
|
||||||
|
**Educational Content**
|
||||||
|
- [How I built a blog with Svelte and SvelteKit](https://fantinel.dev/blog-development-sveltekit/) is an introduction to Svelte, SvelteKit and Progressive Enhancement with code examples
|
||||||
|
- [I built a decentralized chat dapp](https://www.youtube.com/watch?v=J5x3OMXjgMc) is a tutorial on how to use popular web3 technologies like GUN to build a decentralized web app (dapp)
|
||||||
|
- [Writing a Svelte Store with TypeScript](https://javascript.plainenglish.io/writing-a-svelte-store-with-typescript-22fa1c901a4) is a deep dive into writing Svelte stores with TypeScript
|
||||||
|
- [How Svelte scopes component styles](https://geoffrich.net/posts/svelte-scoped-styles/) explains scoping using classes and more complex CSS specifiers
|
||||||
|
- [SvelteKit Hooks](https://www.youtube.com/watch?v=RarufLoEL08) shows how to use hooks.js in Sveltekit.. When you're done, check out [Part 2](https://www.youtube.com/watch?v=RmIBG3G0-VY)
|
||||||
|
- [An early look at SvelteKit](https://www.infoworld.com/article/3630395/an-early-look-at-sveltekit.html) is a post from Infoworld walking through the features and onboarding of SvelteKit
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [sveltekit-netlify-cms](https://github.com/buhrmi/sveltekit-netlify-cms) is a SvelteKit skeleton app configured for use with Netlify CMS
|
||||||
|
- [SvelteFireTS](https://github.com/jacobbowdoin/sveltefirets) is a SvelteKit + TypeScript + Firebase library inspired by Fireship.io
|
||||||
|
- [stores-x](https://github.com/Anyass3/stores-x) lets you use Svelte stores just like vueX
|
||||||
|
- [sveltekit-snippets](https://github.com/stordahl/sveltekit-snippets) is a VSCode extension that provides snippets for common patterns in SvelteKit & Vanilla Svelte
|
||||||
|
- [svelte-xactor](https://github.com/wobsoriano/svelte-xactor) is a middleware that allows you to easily convert your xactor machines into a global store that implements the store contract
|
||||||
|
- [vite-plugin-pages-svelte](https://github.com/aldy505/vite-plugin-pages-svelte) is a vite plugin for automatic filesystem-based routing
|
||||||
|
- [sveltio](https://www.npmjs.com/package/sveltio) is a Svelte wrapper for valtio - a proxy-state library
|
||||||
|
- [svelte-transition-classes](https://github.com/rmarscher/svelte-transition-classes) is a custom Svelte transition for adding and swapping CSS classes
|
||||||
|
- [Svelte-Boring-Avatars](https://github.com/paolotiu/svelte-boring-avatars) is Svelte port of the popular [Boring Avatars](https://github.com/boringdesigners/boring-avatars) React project
|
||||||
|
- [Svelte DataTables](https://github.com/homescriptone/svelte-datatables) brings DataTable, a popular JavaScript library allowing you to easily display your data in a user-friendly table, into your Svelte project.
|
||||||
|
- [focus-svelte](https://github.com/chanced/focus-svelte) is a focus trap for Svelte with zero dependencies
|
||||||
|
- [filedrop-svelte](https://github.com/chanced/filedrop-svelte) is a file dropzone action & component for Svelte
|
||||||
|
|
||||||
|
|
||||||
|
Check out the community site [sveltesociety.dev](https://sveltesociety.dev/templates/) for more templates, adders and adapters from across the Svelte ecosystem.
|
||||||
|
|
||||||
|
|
||||||
|
## Before you go, answer the call for speakers!
|
||||||
|
|
||||||
|
Svelte Summit Fall 2021 (happening 20 November 2021) is looking for speakers. Submit your talk proposal before 30 October... all are welcome to present and attend.
|
||||||
|
|
||||||
|
### More info on the [sessionize site](https://sessionize.com/svelte-summit-fall-2021/)
|
||||||
|
|
||||||
|
Can't wait for the summit? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs)!
|
@ -0,0 +1,91 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: December 2021"
|
||||||
|
description: "Svelte Summit Fall 2021 Recap, Rich Harris joins Vercel, and Kevin goes full-time on Svelte Society"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
With SvelteKit getting more and more stable each day, there's not much to cover in terms of code changes other than bug fixes... So, in this month's newsletter, we'll be covering Svelte Summit Fall 2021!
|
||||||
|
|
||||||
|
If you want to dive deep into the last month's worth of bug fixes, check out the [Svelte](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) and [SvelteKit](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md) changelogs, respectively.
|
||||||
|
|
||||||
|
|
||||||
|
## What happened at Svelte Summit?
|
||||||
|
|
||||||
|
If you missed Svelte Summit, you can watch the entire live stream on [YouTube](https://www.youtube.com/watch?v=1Df-9EKvZr0) and catch a recap in the [#svelte-summit channel on Discord](https://discord.gg/YmHcdnhu).
|
||||||
|
|
||||||
|
Here are the highlights:
|
||||||
|
- [Rich Harris](https://twitter.com/rich_harris) took us through a tour of Svelte's history and announced [his move to Vercel](https://vercel.com/blog/vercel-welcomes-rich-harris-creator-of-svelte) - where he will be helping maintain Svelte full-time! ([20:00](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=1200s))
|
||||||
|
- [Steph Dietz](https://twitter.com/steph_dietz_) explained how Svelte's simple abstractions makes it easy for beginners and experts alike to learn and use JavaScript - without the boilerplate ([29:00](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=1740s))
|
||||||
|
- [Kevin Bridges](https://twitter.com/kevinast) dove deep into Svelte's reactivity logic by visualizing it through `ReflectiveCounter` and showing how to "fine tune" it, as needed. A full "syllabus" for the presentation is available on [Kevin's site](https://wiibridges.com/presentations/ResponsiveSvelte/). ([42:55](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=2575s))
|
||||||
|
- [Mateo Morris](https://twitter.com/_mateomorris) launched [Primo](https://primo.af/), an all-in-one SvelteKit CMS to help build and manage static sites ([1:12:34](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=4354s))
|
||||||
|
- [Guillermo Rauch](https://vercel.com/about/rauchg) explained Vercel's commitment to Svelte, what it means to have Rich on the team, and what's coming next from the company... ([1:21:54](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=4914s))
|
||||||
|
- [Geoff Rich](https://twitter.com/geoffrich_) introduced various ways to modify motion and transitions within Svelte to be more accessible to all users of the web. Slides and a full transcription of the talk are available on [Geoff's site](https://geoffrich.net/posts/svelte-summit-2021/). ([1:32:30](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=5550s))
|
||||||
|
- [Dean Fogarty](https://df.id.au/) demoed a number of different use-cases for custom stores - transforming data to and from storage mechanisms within Svelte. Transcript and code is available on [Dean's GitHub](https://github.com/angrytongan/svelte-summit-2021). ([1:43:06](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=6186s))
|
||||||
|
- [Kellen Mace](https://twitter.com/kellenmace) shared how we can let content creators keep using WordPress, while leveraging Svelte on the frontend to provide a phenomenal user experience ([1:49:30](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=6570ss))
|
||||||
|
- [Ben Holmes](https://twitter.com/bholmesdev) explained the "islands" architecture and how 11ty + [Slinkity](https://slinkity.dev/) can bring these islands to any HTML template ([2:17:15](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=8235s))
|
||||||
|
- [Scott Tolinski](https://twitter.com/stolinski) shared the lessons learned from rewriting the React-based LevelUpTutorials in Svelte and "found developer bliss" ([3:16:35](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=11795s))
|
||||||
|
- [Svelte Sirens](https://sveltesirens.dev) was announced as the new Svelte community for women, non-binary and allies. Their first event was on November 29th - all future events can be found on [the Svelte Sirens website](https://sveltesirens.dev/events) ([3:50:45](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=13845s))
|
||||||
|
- [Rich Harris](https://twitter.com/rich_harris) discussed creating libraries with SvelteKit, better ways to link packages when developing, and how SvelteKit helps with modern JavaScript library development ([3:56:00](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=14160s))
|
||||||
|
- [Ken Kunz](https://twitter.com/kennethkunz) explained how finite state machines (and the svelte-fsm library) can make managing Svelte component states more... manageable. Examples from the talk are available on [Ken's GitHub](https://github.com/kenkunz/svelte-fsm/wiki/Examples). ([4:07:18](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=14838s))
|
||||||
|
- [Austin Crim](https://twitter.com/crim_codes) connected learning to code on the web to learning how to play an instrument. By giving learners early wins and introducing the fundamentals through real-world apps, learning Svelte (and the fundamentals underneath) doesn't have to be a chore ([4:21:50](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=15710s))
|
||||||
|
- [Jesse Skinner](https://twitter.com/JesseSkinner) brought our legacy apps into the future by explaining how to use (and reuse) Svelte components within React (and even jQuery!) projects ([4:32:30](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=16350s))
|
||||||
|
- [Jim Fisk](https://twitter.com/jimafisk) and [Stephanie Luz](https://stephanie-luz.medium.com/) introduced [Plenti](https://plenti.co/) and its theming tools to make building new Svelte sites much faster ([4:59:00](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=17940s))
|
||||||
|
- [Evyatar Alush](https://twitter.com/evyataral) helped us all make (and maintain) better forms using a powerful validation library called [Vest](https://github.com/ealush/vest) ([5:08:55](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=18535s))
|
||||||
|
- Dominik G. presented a fresh take on icon libraries - one that reduces the bundle size of applications and opens up the entire iconify library for use in any Svelte app ([5:30:04](https://www.youtube.com/watch?v=1Df-9EKvZr0&t=19804s))
|
||||||
|
|
||||||
|
Thanks to [Kevin](https://twitter.com/kevmodrome) and all the Svelte Society volunteers for pulling together such an amazing event! Excitingly, [Kevin announced](https://twitter.com/kevmodrome/status/1463151477174714373) after the event that he will now be working full-time on Svelte Society! You can check out all the talks, broken up into individual videos for convenience, in [this Svelte Society YouTube Playlist](https://www.youtube.com/playlist?list=PL8bMgX1kyZTg2bI9IOMgfBc8lrU3v2itt).
|
||||||
|
|
||||||
|
If you have feedback on the Svelte Summit, Kev is [looking for feedback on the Svelte subreddit](https://www.reddit.com/r/sveltejs/comments/qzgo3k/svelte_summit_feedback/) 👀
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [pixeldrain](https://github.com/Fornaxian/pixeldrain_web) is a free-to-use file sharing platform
|
||||||
|
- [LifeHash](http://lifehash.info/) generates beautiful visual hashes from Blockchain Commons
|
||||||
|
- [simple-cloud-music](https://github.com/dufu1991/simple-cloud-music) is a lightweight third-party NetEase cloud music player for modern browsers (likely only works on Chrome)
|
||||||
|
- [palette.rocks](https://palette.rocks/) is a color palette generator with contrast-checking built-in
|
||||||
|
- [Kadium](https://github.com/probablykasper/kadium) is an app for staying on top of YouTube channel uploads
|
||||||
|
- [Multi-Monitor Calculator](https://multimonitorcalculator.com/) is a tool for planning your multi-monitor setup
|
||||||
|
- [Your Home](https://yourhome.fb.com/) is an interactive overview of Facebook's privacy settings
|
||||||
|
- [Svelte Crush](https://svelte-crush.netlify.app/) is a Candy Crush style match-3 game
|
||||||
|
- [100.000 Corona deaths in Germany](https://twitter.com/h_i_g_s_c_h/status/1463767113563353089?s=20) is a visualization made for Spiegel Gesundheit
|
||||||
|
|
||||||
|
**Looking for a Svelte project to work on? Interested in helping make Svelte's presence on the web better?** Check out [the list of open issues](https://github.com/svelte-society/sveltesociety-2021/issues) if you'd like to contribute to the Svelte Society rewrite in SvelteKit.
|
||||||
|
|
||||||
|
|
||||||
|
**Videos, Blogs and Podcasts**
|
||||||
|
- [How To Make and Publish a Svelte Library](https://www.youtube.com/watch?v=_TymiadmPrc)
|
||||||
|
- [SvelteKit is now fully supported in WebContainers](https://blog.stackblitz.com/posts/sveltekit-supported-in-webcontainers/)
|
||||||
|
- [Introducing Svelte, and Comparing Svelte with React and Vue](https://joshcollinsworth.com/blog/introducing-svelte-comparing-with-react-vue)
|
||||||
|
- [Testing a Svelte app with Jest](https://www.roboleary.net/2021/11/18/svelte-app-testing-jest.html)
|
||||||
|
- [How to create a toast notification library package with SvelteKit](https://www.sarcevic.dev/blog/toasting-in-svelte)
|
||||||
|
- [Svelte training: Here you can learn Svelte](https://sustainablewww.org/principles/svelte-training-here-you-can-learn-svelte)
|
||||||
|
- [Introduction to Svelte Actions](https://blog.logrocket.com/svelte-actions-introduction/)
|
||||||
|
- [Enjoy making DAPPs using SvelteWeb3](https://chiuzon.medium.com/enjoy-making-dapps-using-svelteweb3-b78dfea1d902)
|
||||||
|
- [Svelte creator: Web development should be more fun](https://www.infoworld.com/article/3639521/svelte-creator-web-development-should-be-more-fun.html)
|
||||||
|
- [Svelte Radio: Rich Harris is now working full-time on Svelte 🤯](https://share.transistor.fm/s/d9b04961)
|
||||||
|
- [Web Rush: Svelte and Elder.js with Nick Reese](https://webrush.io/episodes/episode-158-svelte-and-elderjs-with-nick-reese)
|
||||||
|
- [Building SvelteKit applications with Serverless Redis](https://blog.upstash.com/svelte-with-serverless-redis)
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [svelte-cubed](https://github.com/Rich-Harris/svelte-cubed) is a Three.js component library for Svelte - created by Rich Harris for his presentation at Svelte Summit Fall 2021
|
||||||
|
- [svelte-fsm](https://github.com/kenkunz/svelte-fsm) is a tiny, simple, expressive, pragmatic Finite State Machine (FSM) library, optimized for Svelte
|
||||||
|
- [bromb](https://github.com/samuelstroschein/bromb) is a feedback widget for websites/web apps that is small and easy to integration/self-host
|
||||||
|
- [Spaper](https://github.com/Oli8/spaper) is a set of PaperCSS components for Svelte
|
||||||
|
- [svelte-intl-precompile](https://github.com/cibernox/svelte-intl-precompile) is an i18n library for Svelte that analyzes and compiles your translations at build time
|
||||||
|
- [svelte-preprocess-svg](https://github.com/svitejs/svelte-preprocess-svg) automatically optimizes inline svg in Svelte components for better performance and reduced file size
|
||||||
|
- [svelte-subcomponent-preprocessor](https://github.com/srmullen/svelte-subcomponent-preprocessor) allows you to write more than one component within a svelte file
|
||||||
|
- [svelte-pdfjs](https://github.com/gtm-nayan/svelte-pdfjs) is a crude implementation of a Svelte PDF viewer component
|
||||||
|
- [svelte-inview](https://github.com/maciekgrzybek/svelte-inview) is a Svelte action that monitors an element enters or leaves the viewport/parent element
|
||||||
|
- [sveltekit-adapter-wordpress-shortcode](https://github.com/tomatrow/sveltekit-adapter-wordpress-shortcode) is an adapter for SvelteKit which turns your app into a wordpress shortcode
|
||||||
|
- [svelte-websocket-store](https://github.com/arlac77/svelte-websocket-store) is a Svelte store with a websocket backend
|
||||||
|
- [Svelte Auto Form](https://github.com/leveluptuts/auto-form) is a fast and fun form library focused on ease of use, rather than flexibility.
|
||||||
|
- [set-focus](https://www.npmjs.com/package/@svackages/set-focus) is an Svelte action that will set focus on `<a>` or `<button>` elements as soon as they mount - useful for some experiences and testing
|
||||||
|
|
||||||
|
Got an idea for SvelteKit? Check out the new [GitHub Discussions](https://github.com/sveltejs/kit/discussions) in the Svelte repo. You can also join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs).
|
||||||
|
|
||||||
|
See you next ~~month~~ year!
|
@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: January 2022"
|
||||||
|
description: "Faster builds with SvelteKit and a much anticipated REPL feature"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Happy new year, Svelte Community! Lots to share this month across Svelte, SvelteKit, Language Tools and the Showcase. Thanks to everyone who made 2021 a great year to use Svelte. Looking forward to the next one 🚀
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- `@sveltejs/adapter-static` for SvelteKit now has a `precompress` option to make brotli compression of assets and pages easier to do out of the box ([#3079](https://github.com/sveltejs/kit/pull/3079))
|
||||||
|
- Concurrency mode in SvelteKit will now prerender pages in parallel ([#3120](https://github.com/sveltejs/kit/pull/3120)). It is enabled by default in `1.0.0-next.205` and later
|
||||||
|
- CSS is now automatically included before JS for improved page performance ([d13efe](https://github.com/sveltejs/kit/commit/d138efe21692f5925f1e89afc0a33f42d6a1a711))
|
||||||
|
- A new config option adds the ability to disable service worker registration to do your own custom registration ([#2988](https://github.com/sveltejs/kit/pull/2988))
|
||||||
|
- SSR route-splitting is here - breaking monolithic builds into smaller pieces for improved startup and routing performance ([#2931](https://github.com/sveltejs/kit/pull/2931))
|
||||||
|
- `request.origin/path/query` is now `request.url` - simplifying the config and page `load` functions ([#3126](https://github.com/sveltejs/kit/pull/3126))
|
||||||
|
- After the [update to Vite 2.7](https://github.com/sveltejs/kit/pull/3018), SvelteKit users are [reporting significant performance improvements](https://www.reddit.com/r/sveltejs/comments/rljhfc/sveltekit_massive_compiler_improvement_by/) and loading third-parties libraries in SSR has also been greatly improved
|
||||||
|
- SvelteKit server will now automatically restart when the config files is changed ([vite-plugin-svelte#237](https://github.com/sveltejs/vite-plugin-svelte/pull/237))
|
||||||
|
|
||||||
|
|
||||||
|
## Other new bits from `svelte/*`
|
||||||
|
- [Svelte 3.44.3](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md#3443) is out with a few bug fixes in the binding and loop code
|
||||||
|
- Svelte Language Tools has introduced support for the then/catch shorthands from Svelte 3.41 and TypeScript's "go to" functionality ([105.8.0 and later](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.8.0))
|
||||||
|
- The Svelte REPL got a nice upgrade as well - letting you delete saved REPLs. Try it out by logging in at [svelte.dev/apps](https://svelte.dev/apps)
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [Discover Twitter Spaces](https://github.com/navneetsharmaui/discover-twitter-spaces) is a tool that helps you find the Twitter Spaces
|
||||||
|
- [Modern Fluid Typography Editor](https://github.com/codeAdrian/modern-fluid-typography-editor) helps create beautiful fluid typography using CSS clamp
|
||||||
|
- [Unnwhiteboard](https://github.com/AviKKi/unnwhiteboard) is a job board for companies (or teams) that don't do "whiteboard" interviews
|
||||||
|
- [Secret Santa](https://gitlab.com/arturoguzman/secret-santa-sveltekit) is a gift giving coordination app developed with easiness in mind
|
||||||
|
- [LogSnag](https://logsnag.com/) notifies you of your projects' events and provides you with a timeline to keep track of anything important that happens
|
||||||
|
- [Version 0.2 of Tangent](http://tangentnotes.com/Download), a Svelte-based note writing app, is now in beta
|
||||||
|
- [Intl Explorer](https://github.com/jesperorb/intl-explorer) is a tool for viewing output for all possible formatters for Intl
|
||||||
|
|
||||||
|
A lot of work this month has gone into migrating the Svelte main website and Svelte REPL to live in the https://github.com/sveltejs/sites repository - including a brand new homepage for [svelte.dev](https://svelte.dev/). Thanks to all the contributors who made this possible!
|
||||||
|
|
||||||
|
If you're looking for a fun SvelteKit project to work on, [you can contribute to the Svelte Society site rewrite](https://github.com/svelte-society/sveltesociety-2021/issues) 💅
|
||||||
|
|
||||||
|
|
||||||
|
**Learning and Listening**
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Mutating Query Params in SvelteKit Without Page Reloads or Navigations](https://dev.to/mohamadharith/mutating-query-params-in-sveltekit-without-page-reloads-or-navigations-2i2b) by Mohamad Harith
|
||||||
|
- [Svelte for Reactaholics : A guide for React developers](https://www.100ms.live/blog/svelte-guide-for-react-developers) by Puru Vijay
|
||||||
|
- [Svelte's lifecycle methods can be used anywhere](https://geoffrich.net/posts/svelte-lifecycle-examples/) and [The many meanings of $ in Svelte](https://geoffrich.net/posts/svelte-$-meanings/) by Geoff Rich
|
||||||
|
- [Vercel and Svelte: A Perfect Match for Web Developers](https://thenewstack.io/vercel-and-svelte-a-perfect-match-for-web-developers/) by Darryl K. Taft
|
||||||
|
- [User-defined TailwindCSS Color Scheme with Svelte Stores](https://blog.dayslice.io/user-defined-tailwindcss-color-scheme-with-svelte-stores-ad80ca2cf038) by jeremy zaborowski
|
||||||
|
- [Ionic 6 + Svelte 🚀](https://medium.com/@raymondboswel/ionic-6-svelte-ae904caa82df) by Raymond Boswel
|
||||||
|
- [What happened in #Svelte language tools this year](https://twitter.com/dummdidumm_/status/1474158105395179525?t=ytj2K2Q52iD5-lNyLnQaAQ&s=19) by Simon H
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [The Future of Svelte (Interview with Rich Harris)](https://www.youtube.com/watch?v=uQntFkK8Z54) by Lee Robinson, Director of Developer Relations at Vercel
|
||||||
|
- [Svelte is becoming the go-to framework](https://www.youtube.com/watch?v=fo6BKY2xR2w&t=1834s) for Obsidian plugin developers
|
||||||
|
- [Sveltekit WordPress Headless Blog](https://www.youtube.com/watch?v=c0UDVgjPxFw) by WebJeda
|
||||||
|
- [Getting started with SvelteKit](https://www.youtube.com/watch?v=i2suPKMPUFA) by Lihau Tan
|
||||||
|
- [Deploy a full-stack SvelteKit app on Cloudflare Pages](https://www.youtube.com/watch?v=Wc1_U6Dy5Tw) by 1nf
|
||||||
|
|
||||||
|
_To Listen To_
|
||||||
|
- [Syntax podcast: How To Do Things In Svelte](https://podcasts.apple.com/ca/podcast/how-to-do-things-in-svelte/id1253186678?i=1000544796072)
|
||||||
|
- [JS Party #205: So much Sveltey goodness (w/ Rich Harris)](https://changelog.com/jsparty/205)
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [svelte-headlessui](https://github.com/rgossiaux/svelte-headlessui) is an unofficial, complete Svelte port of the Headless UI component library
|
||||||
|
- [svelte-forms v2](https://chainlist.github.io/svelte-forms/) has been released - the author is [looking for feedback](https://www.reddit.com/r/sveltejs/comments/r6354j/svelteforms_v2_has_been_released/)
|
||||||
|
- [Percival](https://github.com/ekzhang/percival) is a declarative data query and visualization language
|
||||||
|
- [Svelte FlatList](https://github.com/snuffyDev/svelte-flatlist) is a mobile-friendly, simple, and customizable draggable menu
|
||||||
|
- [svelte-keyed](https://github.com/bryanmylee/svelte-keyed) is a writable derived store for objects and arrays
|
||||||
|
- [Svemix](https://github.com/svemix/svemix) is Remix for Svelte - providing server scripts inside your Svelte components/routes, which will be transformed into endpoints
|
||||||
|
|
||||||
|
Want to add something to the showcase? Need help bringing your next idea to life in Svelte? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs).
|
||||||
|
|
||||||
|
See ya next month!
|
@ -0,0 +1,106 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: February 2022"
|
||||||
|
description: "Rapid-fire releases across Svelte, SvelteKit and the community"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Happy February, everyone! Over the last month or so, we've seen Svelte and SvelteKit [develop at rapid speed](accelerating-sveltes-development), new community rules across the [Reddit](https://www.reddit.com/r/sveltejs/comments/s9n8ou/new_rules/), [GitHub](https://github.com/sveltejs/community/blob/main/CODE_OF_CONDUCT.md) and [Discord](https://discord.com/channels/457912077277855764/831611707667382303/935264550436102315), and quite a few amazing apps, tutorials and libraries.
|
||||||
|
|
||||||
|
Let's take a look...
|
||||||
|
|
||||||
|
## Highlights from the Svelte changelog
|
||||||
|
- **3.45.0** brought a [new a11y warning `a11y-no-redundant-roles`](https://svelte.dev/docs#accessibility-warnings-a11y-no-redundant-roles), destructuring and caching fixes
|
||||||
|
- **3.46.0** added the much requested [`{@const}` tag](https://svelte.dev/docs#template-syntax-const) and [`style:` directive](https://svelte.dev/docs#template-syntax-element-directives-style-property)
|
||||||
|
- Check out **3.46.1 - 3.46.3** for fixes to the `{@const}` tag and `style:` directive, along with a number of fixes to animations
|
||||||
|
- [AST output is now available in the Svelte REPL](https://svelte.dev/repl/hello-world)
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- `inlineStyleThreshold` allows you to specify where inline stylesheets are inserted into the page ([Docs](https://kit.svelte.dev/docs/configuration#inlinestylethreshold), [#2620](https://github.com/sveltejs/kit/pull/2620))
|
||||||
|
- `beforeNavigate`/`afterNavigate` lifecycle functions lets you add functionality before or after a page navigation ([Docs](https://kit.svelte.dev/docs/modules#$app-navigation), [#3293](https://github.com/sveltejs/kit/pull/3293))
|
||||||
|
- Platform context can now be passed from adapters ([Docs](https://kit.svelte.dev/docs/adapters#supported-environments-platform-specific-context), [#3429](https://github.com/sveltejs/kit/pull/3429))
|
||||||
|
- Hooks now have an `ssr` parameter in `resolve` to make it easier to skip SSR, when needed ([Docs](https://kit.svelte.dev/docs/hooks#handle), [#2804](https://github.com/sveltejs/kit/pull/2804))
|
||||||
|
- `$page.stuff` provides a mechanism for pages to pass data 'upward' to layouts ([Docs](https://kit.svelte.dev/docs/loading#input-stuff), [#3252](https://github.com/sveltejs/kit/pull/3252))
|
||||||
|
- Fallthrough routes let you specify where to route when an route can't be loaded ([Docs](https://kit.svelte.dev/docs/routing#advanced-routing-fallthrough-routes), [#3217](https://github.com/sveltejs/kit/pull/3217))
|
||||||
|
|
||||||
|
**New configs**
|
||||||
|
- Content Security Policy (CSP) is now supported for increased security when using inline javascript or stylesheets ([Docs](https://kit.svelte.dev/docs/configuration#csp), [#3499](https://github.com/sveltejs/kit/pull/3499))
|
||||||
|
- `kit.routes` config allows you to customise public/private modules during build ([Docs](https://kit.svelte.dev/docs/configuration#routes), [#3576](https://github.com/sveltejs/kit/pull/3576))
|
||||||
|
- `prerender.createIndexFiles` config lets you prerender index.html files as their subfolder's name ([Docs](https://kit.svelte.dev/docs/configuration#prerender), [#2632](https://github.com/sveltejs/kit/pull/2632))
|
||||||
|
- HTTP methods can now be overridden using `kit.methodOverride` ([Docs](https://kit.svelte.dev/docs/routing#endpoints-http-method-overrides), [#2989](https://github.com/sveltejs/kit/pull/2989))
|
||||||
|
|
||||||
|
**Config changes**
|
||||||
|
- `config.kit.hydrate` and `config.kit.router` are now nested under `config.kit.browser` ([Docs](https://kit.svelte.dev/docs/configuration#browser), [3578](https://github.com/sveltejs/kit/pull/3578))
|
||||||
|
|
||||||
|
**Breaking change**
|
||||||
|
- use `Request` and `Response` objects in endpoints and hooks ([#3384](https://github.com/sveltejs/kit/pull/3384))
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [timb(re)](https://paullj.github.io/timb) is a live music programming environment
|
||||||
|
- [Music for Programming](https://musicforprogramming.net/latest/) is a series of mixes intended for listening while `${task}` to focus the brain and inspire the mind
|
||||||
|
- [Team Tale](https://teamtale.app/) allows two authors to write the same story in a tag-team sort of fashion
|
||||||
|
- [Puzzlez](https://www.puzzlez.io/) is an online place to play Sudoku and Wordle
|
||||||
|
- [Closed Caption Creator](https://www.closedcaptioncreator.com/) makes it easy to add subtitles to your video on Windows, Mac and Google Chrome
|
||||||
|
- [SC3Lab](https://sc3-lab.netlify.app/) is a code generator for experimenting with svelte-cubed and three.js
|
||||||
|
- [Donkeytype](https://github.com/0ql/Donkeytype) is a minimalistic and lightweight typingtest inspired by Monkeytype.
|
||||||
|
- [Above](https://above.silas.pro/) is a visual routine timer built for the ADHD/autistic mind
|
||||||
|
- [base.report](https://base.report/) is a modern research platform for serious investors
|
||||||
|
- [String](https://string.kampsy.xyz/) turns your Phone into a secure portable audio recorder, making it easy to capture and share personal notes, family moments, classroom lectures, and more
|
||||||
|
- [The Raytracer Challenge REPL](https://github.com/jakobwesthoff/the_raytracer_challenge_repl) provides a live editor interface to configure a raytraced scene and render it live in any modern browser
|
||||||
|
- [awesome-svelte-kit](https://github.com/janosh/awesome-svelte-kit) is a list of awesome examples of SvelteKit in the wild
|
||||||
|
- [Map Projection Explorer](https://www.geo-projections.com/) lets you explore different map projections and explains their differences
|
||||||
|
- [Rubiks](https://github.com/MeharGaur/rubiks) is a Rubik's Cube simulator
|
||||||
|
- [Pianisto](https://pianisto.net/) is a working piano made with SVG, ToneJS and a lot of patience
|
||||||
|
|
||||||
|
Want to work on a SvelteKit site with others, [try contributing to the Svelte Society site](https://github.com/svelte-society/sveltesociety-2021/issues)!
|
||||||
|
|
||||||
|
|
||||||
|
**Learning and Listening**
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Accelerating Svelte's Development](https://svelte.dev/blog/accelerating-sveltes-development) by Ben McCann
|
||||||
|
- [Storybook for Vite](https://storybook.js.org/blog/storybook-for-vite/)
|
||||||
|
- [Let's learn SvelteKit by building a static Markdown blog from scratch](https://joshcollinsworth.com/blog/build-static-sveltekit-markdown-blog) by Josh Collinsworth
|
||||||
|
- [Building an iOS app with Svelte, Capacitor and Firebase](https://harryherskowitz.com/2022/01/05/tapedrop-app.html) by Harry Herskowitz
|
||||||
|
- [Mutating Query Params in SvelteKit Without Page Reloads or Navigations](https://dev.to/mohamadharith/mutating-query-params-in-sveltekit-without-page-reloads-or-navigations-2i2b) and [Workaround for Bubbling Custom Events in Svelte](https://dev.to/mohamadharith/workaround-for-bubbling-custom-events-in-svelte-3khk) by Mohamad Harith
|
||||||
|
- [How to build a full stack serverless application with Svelte and GraphQL](https://dev.to/shadid12/how-to-build-a-full-stack-serverless-application-with-svelte-graphql-and-fauna-5427) by Shadid Haque
|
||||||
|
- [How to Deploy SvelteKit Apps to GitHub Pages](https://sveltesaas.com/articles/sveltekit-github-pages-guide/)
|
||||||
|
- [Creating a dApp with SvelteKit](https://anthonyriley.org/2021/12/31/creating-a-dapp-with-sveltekit/) by Anthony Riley
|
||||||
|
- [Comparing Svelte Reactivity Options](https://opendirective.net/2022/01/06/comparing-svelte-reactivity-options/) by Steve Lee
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [Integrating Storybook with SvelteKit](https://www.youtube.com/watch?v=Kc1ULlfyUcw) and [Integrating FaunaDB with Svelte](https://www.youtube.com/watch?v=zaoLZc76uZM) by the Svelte Sirens
|
||||||
|
- [SvelteKit Crash Course Tutorial](https://www.youtube.com/watch?v=9OlLxkaeVvw&list=PL4cUxeGkcC9hpM9ARM59Ve3jqcb54dqiP) by The Net Ninja
|
||||||
|
- [Svelte for Beginners](https://www.youtube.com/watch?v=BrkrOjknC_E&list=PLA9WiRZ-IS_ylnMYxIFCsZN6xVVSvLuHk) by Joy of Code
|
||||||
|
- [SvelteKit For Beginners | Movie App Tutorial](https://www.youtube.com/watch?v=ydR_M0fw9Xc) by Dev Ed
|
||||||
|
- [SvelteKit $app/stores](https://www.youtube.com/watch?v=gBPhr1xbgaQ) by lihautan
|
||||||
|
- [Sveltekit - Get All Routes/Pages](https://www.youtube.com/watch?v=Y_NE2R3HuOU) by WebJeda
|
||||||
|
|
||||||
|
_To Listen To_
|
||||||
|
- [New Year, New Svelte!?](https://share.transistor.fm/s/36212cdc) from Svelte Radio
|
||||||
|
- [So much Sveltey goodness (featuring Rich Harris)](https://changelog.com/jsparty/205) from JS Party
|
||||||
|
- [The Other Side of Tech: A Documentarian Perspective (with Stefan Kingham)](https://codingcat.dev/podcast/2-4-the-other-side-of-tech-a-documentarian-perspective) from Purrfect.dev
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [threlte](https://github.com/grischaerbe/threlte) is a three.js component library for Svelte
|
||||||
|
- [svelte-formify](https://github.com/nodify-at/svelte-formify) is a library to manage and validate forms that uses decorators to define validations
|
||||||
|
- [gQuery](https://github.com/leveluptuts/gQuery) is a GraphQL Fetcher & Cache for Svelte Kit
|
||||||
|
- [Unlock-protocol](https://github.com/novum-insights/sveltekit-unlock-firebase) is an integration to help login with MetaMask, Firebase, and paywall customers
|
||||||
|
- [AgnosticUI](https://github.com/AgnosticUI/agnosticui) is a set of UI primitives that start their lives in clean HTML and CSS
|
||||||
|
- [Vitebook](https://github.com/vitebook/vitebook) is a fast and lightweight alternative to Storybook that's powered by Vite
|
||||||
|
- [SwyxKit](https://swyxkit.netlify.app/) is an opinionated blog starter for SvelteKit + Tailwind + Netlify. Refreshed for 2022!
|
||||||
|
- [svelte-themes](https://github.com/beynar/svelte-themes) is an abstraction for themes in your SvelteKit app
|
||||||
|
- [svelte-transition](https://www.npmjs.com/package/svelte-transition) is a Svelte component to make using CSS class based transitions easier - ideally suited for use with TailwindCSS
|
||||||
|
- [Svelte Inview](https://www.npmjs.com/package/svelte-inview) is a Svelte action that monitors an element enters or leaves the viewport/parent element
|
||||||
|
- [svelte-inline-compile](https://github.com/DockYard/svelte-inline-compile) is a babel transform that allows for a much more pleasant experience when testing svelte components using Jest and `@testing-library/svelte`
|
||||||
|
- [@feltcoop/svelte-mutable-store](https://github.com/feltcoop/svelte-mutable-store) is a Svelte store for mutable values with an `immutable` compiler option
|
||||||
|
- [headless-svelte-ui](https://www.npmjs.com/package/@bojalelabs/headless-svelte-ui) is a group of headless components that can be used in building Svelte Apps.
|
||||||
|
|
||||||
|
Did we miss something? Need help bringing your next idea to life in Svelte? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs).
|
||||||
|
|
||||||
|
See ya next month!
|
@ -0,0 +1,87 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: March 2022"
|
||||||
|
description: "Svelte Summit Spring is coming... and page endpoints are here!"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
Just announced: [Svelte Summit Spring](https://www.sveltesummit.com/) will be taking place on April 30, 2022. The 5th Virtual Svelte Conference is [looking for speakers](https://www.sveltesummit.com/#speakers) and [sponsors](https://www.sveltesummit.com/sponsors)... so it's time to dust off those proposals!
|
||||||
|
|
||||||
|
Also, some long-requested features were added to SvelteKit this month... including page endpoints! This change in how the `load` function works makes it easier to fetch data required for basic pages, redirect from POST responses and handle 404s and other errors.
|
||||||
|
|
||||||
|
More on that and other new features and fixes below!
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- The docs are now searchable and multipage with type definitions and hoverable code examples - Check them out at [kit.svelte.dev/docs](https://kit.svelte.dev/docs/)
|
||||||
|
- Page endpoints significantly decrease the boilerplate needed when loading a page ([Issue](https://github.com/sveltejs/kit/issues/3532), [PR](https://github.com/sveltejs/kit/pull/3679), [Docs](https://kit.svelte.dev/docs/routing#endpoints-page-endpoints))
|
||||||
|
- Application versioning and update detection support lets you determine what to do when a route fails to load after an app update ([Issue](https://github.com/sveltejs/kit/issues/87), [PR](https://github.com/sveltejs/kit/pull/3412), [Docs](https://kit.svelte.dev/docs/configuration#version))
|
||||||
|
- A new option in `npm init svelte@next` will now set up Playwright automatically for testing ([PR](https://github.com/sveltejs/kit/pull/4056))
|
||||||
|
|
||||||
|
|
||||||
|
**Breaking Changes**
|
||||||
|
- The `target` option is no longer available. Instead, the `init` script hydrates its `parentNode` ([#3674](https://github.com/sveltejs/kit/pull/3674))
|
||||||
|
- App-level types now live in the `App` namespace which allows you to type global types like `Stuff` or `Session` ([#3670](https://github.com/sveltejs/kit/pull/3670))
|
||||||
|
- `JSONString` is now `JSONValue` ([#3683](https://github.com/sveltejs/kit/pull/3683))
|
||||||
|
- `createIndexFiles` has been removed — it is now controlled by the `trailingSlash` option ([#3801](https://github.com/sveltejs/kit/pull/3801))
|
||||||
|
- SvelteKit will no longer exclude root-relative external links from prerendering, which will cause 404s if these URLs are intended to be served by a separate app. Use a custom [`prerender.onError`](https://kit.svelte.dev/docs/configuration#prerender) handler if you need to ignore them ([#3826](https://github.com/sveltejs/kit/pull/3826))
|
||||||
|
|
||||||
|
|
||||||
|
## New in Language Tools
|
||||||
|
- Accessing properties in markups has been improved in the Svelte language tools ([105.12.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.12.0)) - working around some known issues with autocomplete ([#538](https://github.com/sveltejs/language-tools/issues/538) / [#1302](https://github.com/sveltejs/language-tools/issues/1302))
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [SvelteStorm](https://github.com/open-source-labs/SvelteStorm) is specifically tailored to provide all of the essential tools a Svelte developer needs to build a Svelte application
|
||||||
|
- [Supachat](https://github.com/Lleweraf/supachat) is a real-time chat app using Svelte and Supabase
|
||||||
|
- [Radicle](https://radicle.xyz/) is a peer-to-peer stack for building software together
|
||||||
|
- [The Making Known](https://the-making-known.com/) is a narrated encounter with posters designed by the Nazi German government to communicate with the occupied nations of Belgium, France, and Luxembourg during the Second World War
|
||||||
|
- [Svelte Kanban](https://github.com/V-Py/svelte-kanban) is a simple Svelte Kanban made in pure CSS
|
||||||
|
- [fngrng](https://github.com/nvlgzr/fngrng) is a typing trainer focussed on accuracy over speed
|
||||||
|
- [Generative grids](https://svelte.dev/repl/873988ce33db43f097c0ca69df57b3ac?version=3.46.4) is a neat little generative SVG grid in a Svelte REPL, with randomly generated color palettes and shapes
|
||||||
|
- [LifeHash](https://github.com/BlockchainCommons/lifehash.info) is a method of hash visualization that creates beautiful, deterministic icons
|
||||||
|
- [TypedWebhook.tools](https://typedwebhook.tools/) is a webhook testing tool for checking payloads, with automatic type generation
|
||||||
|
- [Speedskating](https://github.com/spiegelgraphics/speedskating) is an animation widget to show olympic speedskating runs. Built with Svelte, D3 and regl
|
||||||
|
- [Web tail](https://github.com/mishankov/web-tail) is a web application to view lines from file on local system or on remote server
|
||||||
|
|
||||||
|
Want to work on a SvelteKit site with others? [Contribute to the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)!
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Svelte Components as Web Components](https://medium.com/@yesmeno/svelte-components-as-web-components-b400d1253504) by Matias Meno
|
||||||
|
- [Simple Svelte Routing with Reactive URLs](https://bjornlu.com/blog/simple-svelte-routing-with-reactive-urls) by Bjorn Lu
|
||||||
|
- [Leveling Up my Sveltekit / Sanity.io Blog Content with Featured Videos and Syntax Highlighting](https://ryanboddy.net/level-up-blog) by Ryan Boddy
|
||||||
|
- [How This Blog Makes the Most of GitHub](https://paullj.github.io/posts/how-this-blog-makes-the-most-of-github/) by paullj
|
||||||
|
- [FullStack JWT Auth: Introducing SvelteKit](https://dev.to/sirneij/fullstack-jwt-introducing-sveltekit-3jcn) by John Idogun
|
||||||
|
- [Svelte-Cubed: Adding Motion to 3D Scenes](https://dev.to/alexwarnes/svelte-cubed-adding-motion-to-3d-scenes-51lo) by Alex Warnes
|
||||||
|
- [Creating a RSS feed with Sanity and Svelte Kit](https://ghostdev.xyz/posts/creating-a-rss-feed-with-sanity-and-svelte-kit) by GHOST
|
||||||
|
- [How to use Svelte's style directive](https://geoffrich.net/posts/style-directives/) by Geoff Rich
|
||||||
|
- [SvelteKit and the "Client pattern"](https://retro.cloud/sveltekit-and-the-client-pattern/) by Julian Laubstein
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [~~Shadow~~ Page Endpoints In Svelte Kit - Weekly Svelte](https://www.youtube.com/watch?v=PoYPZT7ruqI) by LevelUpTuts
|
||||||
|
- [Testing For Beginners (Playlist)](https://www.youtube.com/watch?v=y53wwdBr5AI&list=PLA9WiRZ-IS_z7KpqhPELfEMbhAGRwZrzn) by Joy of Code
|
||||||
|
- [KitQL - The native SvelteKit library for GraphQL](https://www.youtube.com/watch?v=6pH4fnFN70w) by Jean-Yves COUËT
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [gosvelte](https://github.com/sachinbhutani/gosvelte) is a proof of concept to serve Svelte-generated pages on GoLang HTTP server with server data being sent as props to svelte components
|
||||||
|
- [svelte-ethers-store](https://www.npmjs.com/package/svelte-ethers-store) uses the ethers.js library as a collection of readable Svelte stores for Svelte, Sapper or SvelteKit
|
||||||
|
- [Fluid Grid](https://fluid-grid.com/) is a CSS grid system for future web
|
||||||
|
- [stirstack](https://github.com/seeReadCode/stirstack) is an opinionated framework that combines Svelte.js, TailwindCSS, InertiaJS and Ruby on Rails
|
||||||
|
- [OATHqr](https://codeberg.org/vhs/oathqr) helps users create security credentials for use with 2FA/MFA and other OATH-enabled apps. Use it to generate scannable QR codes for one-time password authenticator apps such as Aegis or YubiKey
|
||||||
|
- [svelte-GridTiles](https://github.com/honeybeeSunshine/svelte-GridTiles) is a drag and drop resizable tiles library built on a responsive grid
|
||||||
|
- [Miscellaneous Svelte Components](https://github.com/alex-knyaz/Miscellaneous-svelte-components/) is a collection of miscellaneous svelte components alex-knyaz often use in my projects
|
||||||
|
- [walk-and-graph-svelte-components](https://github.com/j2l/walk-and-graph-svelte-components) is a CLI node script to walk svelte and js files, to draw a beautiful JPG of your dependencies aka "imports"
|
||||||
|
- [Felte](https://www.npmjs.com/package/felte) is a simple to use form library for Svelte
|
||||||
|
- [svelte-use-tooltip](https://github.com/untemps/svelte-use-tooltip) is a Svelte action to display a tooltip
|
||||||
|
- [persistent-svelte-store](https://github.com/omer-g/persistent-svelte-store) is a generic persistent writable store, built from scratch in TypeScript according to the Svelte store contract
|
||||||
|
|
||||||
|
What'd we miss? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to continue the conversation.
|
||||||
|
|
||||||
|
See y'all next month!
|
@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: April 2022"
|
||||||
|
description: "Goodbye fallthrough routes, hello param validators!"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
This month, we felt a shift in the way SvelteKit handles page properties. The last holdout of the use-cases that required fallthrough routes, validating parameter properties, has been replaced by a more specific solution.
|
||||||
|
|
||||||
|
More on that, and what else is new in Svelte, as we dive in...
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- Param matchers allow you to check if a url parameter matches before rendering a page - replacing the need for fallthrough routes for this purpose ([Docs](https://kit.svelte.dev/docs/routing#advanced-routing-matching), [#4334](https://github.com/sveltejs/kit/pull/4334))
|
||||||
|
- Explicit redirects can now be handled directly from endpoints ([#4260](https://github.com/sveltejs/kit/pull/4260))
|
||||||
|
- `svelte-kit sync` ([#4182](https://github.com/sveltejs/kit/pull/4182)), TypeScript 4.6 ([#4190](https://github.com/sveltejs/kit/pull/4190)) and Vite 2.9 were released - adding non-blocking dependency optimization and experimental CSS source maps in dev mode as well as a number of bug fixes contributed by the SvelteKit team ([#4468](https://github.com/sveltejs/kit/pull/4468))
|
||||||
|
|
||||||
|
|
||||||
|
**New Config Options**
|
||||||
|
- `outDir` fixes path issues in monorepos and other situations where the desired output directory is outside the project directory ([Docs](https://kit.svelte.dev/docs/configuration#outdir), [#4176](https://github.com/sveltejs/kit/pull/4176))
|
||||||
|
- `endpointExtensions` prevents files other than .js and .ts files from being treated as endpoints, unless you specify endpointExtensions ([Docs](https://kit.svelte.dev/docs/configuration#endpointextensions), [#4197](https://github.com/sveltejs/kit/pull/4197))
|
||||||
|
- `prerender.default` lets you prerender every page without having to write `export const prerender = true` in every page file ([Docs](https://kit.svelte.dev/docs/configuration#prerender), [#4192](https://github.com/sveltejs/kit/pull/4192))
|
||||||
|
|
||||||
|
|
||||||
|
**Breaking Changes**
|
||||||
|
- Fallthrough routes have been removed. For migration tips, check out the PR ([#4330](https://github.com/sveltejs/kit/pull/4330))
|
||||||
|
- `tabindex="-1"` is only added to `<body>` during navigation ([#4140](https://github.com/sveltejs/kit/pull/4140) and [#4184](https://github.com/sveltejs/kit/pull/4184))
|
||||||
|
- Adapters are now required to supply a `getClientAddress` function ([#4289](https://github.com/sveltejs/kit/pull/4289))
|
||||||
|
- `InputProps` and `OutputProps` can now be typed separately in generated `Load` ([#4305](https://github.com/sveltejs/kit/pull/4305))
|
||||||
|
- The `\$` character is no longer allowed in dynamic parameters ([#4334](https://github.com/sveltejs/kit/pull/4334))
|
||||||
|
- `svelte-kit package` has been marked as experimental so changes to it after Kit 1.0 will not be considered breaking ([#4164](https://github.com/sveltejs/kit/pull/4164))
|
||||||
|
|
||||||
|
|
||||||
|
## New across the Svelte ecosystem
|
||||||
|
- Svelte: Lots of new types for TypeScript and Svelte plugin users - including `style:` directives and Svelte Actions (**3.46.4** and **3.46.5**)
|
||||||
|
- Language Tools: Svelte project files are now importable/findable through references without having them imported in a TS file ([105.13.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.13.0))
|
||||||
|
- Language Tools: Region folding is now supported in html with `<!--#region-->`/`<!--#endregion-->` ([105.13.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.13.0))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites built with Svelte**
|
||||||
|
- [Launcher](https://launcher.team/) is an open-source app launcher powered by SvelteKit, Prisma, and Tailwind
|
||||||
|
- [Paaster](https://paaster.io/) is a secure by default end to end encrypted pastebin built with Svelte, Vite, TypeScript, Python, Starlette, rclone & Docker.
|
||||||
|
- [Simple AF Video Converter](https://github.com/berlyozzy/Simple-AF-Video-Converter) is an Electron wrapper around ffmpeg.wasm to make converting videos between formats easier
|
||||||
|
- [Streamchaser](https://github.com/streamchaser/streamchaser) seeks to simplify movie, series and documentary search through a centralized entertainment technology platform
|
||||||
|
- [Svelte Color Picker](https://github.com/V-Py/svelte-material-color-picker) is a simple color picker made with Svelte
|
||||||
|
- [ConcertMash](https://github.com/mcmxcdev/ConcertMash) is a small website that interacts with the Spotify API and generates new playlists based on the upcoming concerts you're attending
|
||||||
|
- [Modulus](https://modulus.vision/) is a Design+Code Think Tank conceived with the main mission to evolve design and technology
|
||||||
|
- [Multiply](https://www.multiply.us/) is an integrated PR and Social agency moving at the speed of culture
|
||||||
|
- [yia!](https://www.yia.co.nz/) is a Young Innovator Award competition in New Zealand
|
||||||
|
- [Write to Russia](https://www.writetorussia.org/index) is a community email writing platform to communicate with public `.ru` email addresses
|
||||||
|
- [Markdown Playground](https://github.com/Petros-K/markdown-playground) is an online playground dedicated for your markdown experiments.
|
||||||
|
- [RatherMisty](https://rathermisty.com/) is a no frills weather app with weather data from Open-Meteo
|
||||||
|
- [Minecraft Profile Pic (MCPFP)](https://github.com/MauritsWilke/mcpfp) is a site to generate Minecraft profile pictures with ease
|
||||||
|
- [WebGL Fluid Simulation](https://github.com/jpaquim/svelte-webgl-fluid-simulation) is a configurable fluid simulation built with Svelte and WebGL
|
||||||
|
- [This @NobelPeaceOslo exhibition](https://twitter.com/perbyhring/status/1504754949791621120) was built using printed graphics, projected motion graphics, particle animations and generative sound design
|
||||||
|
|
||||||
|
Itching to contribute to a modern SvelteKit website? [Help build the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)!
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_To Attend_
|
||||||
|
- [Svelte Summit: Spring](https://www.sveltesummit.com/) will take place on April 30, 2022! Join us for the 5th virtual Svelte conference on [YouTube](https://www.sveltesummit.com/) and Discord 🍾
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Svelte(Kit) TypeScript Showcase + general TypeScript tips](https://github.com/ivanhofer/sveltekit-typescript-showcase) by Hofer Ivan
|
||||||
|
- [Local constants in Svelte with the @const tag](https://geoffrich.net/posts/local-constants/) by Geoff Rich
|
||||||
|
- [Design Patterns for Building Reusable Svelte Components](https://render.com/blog/svelte-design-patterns) by Eric Liu
|
||||||
|
- [Svelte is better than React](https://labs.hamy.xyz/posts/svelte-is-better-than-react/) by Hamilton Greene
|
||||||
|
- [Making Visualizations Literally with Svelte and D3](https://www.connorrothschild.com/post/svelte-and-d3) by Connor Rothschild
|
||||||
|
- [Coordinating Multiple Elements with Svelte Deferred Transitions](https://imfeld.dev/writing/svelte_deferred_transitions) by Daniel Imfeld
|
||||||
|
- [Animate on scroll with Svelte Inview - Little Bits](https://dev.to/maciekgrzybek/animate-on-scroll-with-svelte-inview-266f) by Maciek Grzybek
|
||||||
|
- [Lazy-Loading Firebase with SvelteKit](https://www.captaincodeman.com/lazy-loading-firebase-with-sveltekit) and [HeadlessUI Components with Svelte](https://www.captaincodeman.com/headlessui-components-with-svelte) by Captain Codeman
|
||||||
|
- [SvelteKit Accessibility Testing: Automated CI A11y Tests](https://rodneylab.com/sveltekit-accessibility-testing/) by Rodney Lab
|
||||||
|
- [Getting Started with KitQL and GraphCMS](https://scottspence.com/posts/getting-started-with-kitql-and-graphcms) by Scott Spence
|
||||||
|
- [React ⇆ Svelte Cheatsheet](https://dev.to/joshnuss/react-to-svelte-cheatsheet-1a2a) lists the similarities and differences between the two libraries - by Joshua Nussbaum
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [Svelte Extravaganza | Async](https://www.youtube.com/watch?v=mT4CLVHgtSg) by pngwn
|
||||||
|
- [6 Svelte Packages You Should Know](https://www.youtube.com/watch?v=y5SrUKcX_Co) and [Basic React To Svelte Conversion](https://www.youtube.com/watch?v=DiSuwLlhOxs) by LevelUpTuts
|
||||||
|
- [Page/Shadow Endpoint in SvelteKit](https://www.youtube.com/watch?v=j-9D5UDyVOM) by WebJeda
|
||||||
|
- [Custom Svelte Store: Higher Order Store](https://www.youtube.com/watch?v=p1aPfVyZ1IY) by lihautan
|
||||||
|
- [SvelteKit For Beginners (Playlist)](https://www.youtube.com/watch?v=bLBHecY4-ak&list=PLA9WiRZ-IS_zXZZyW4qfj0akvOAtk6MFS) by Joy of Code - follow along with the [blog guide](https://joyofcode.xyz/sveltekit-for-beginners)
|
||||||
|
- [Fullstack SvelteKit Auth 🔐 with Firebase & Magic Links! 🪄](https://www.youtube.com/watch?v=MAHE4iQgh5Q) by Johnny Magrippis
|
||||||
|
- [Firebase Authentication in SvelteKit! Full Stack App](https://www.youtube.com/watch?v=N6Y3hqhZvNI) by Ryan Boddy
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [SvelTable](https://sveltable.io/) is a feature rich, data table component built with Svelte
|
||||||
|
- [svelte-cyberComp](https://github.com/Cybersteam00/svelte-cyberComp) is a powerful, lightweight component library written in Svelte and TypeScript
|
||||||
|
- [Flowbite Svelte](https://github.com/shinokada/flowbite-svelte) is an unofficial Flowbite component library for Svelte
|
||||||
|
- [Svelte-Tide-Project](https://github.com/jbertovic/svelte-tide-project) is a starter template for Svelte frontend apps with Rust Tide backend server
|
||||||
|
- [Fetch Inject](https://github.com/vhscom/fetch-inject#sveltekit) implements a performance optimization technique for managing asynchronous JavaScript dependencies - now with Svelte support
|
||||||
|
- [svelte-utterances](https://github.com/shinokada/svelte-utterances) is a lightweight comments widget built on GitHub issues
|
||||||
|
- [Liquivelte](https://github.com/malipetek/liquivelte-vscode) allows you to create your Shopify theme with Svelte-like components
|
||||||
|
- [@storyblok/svelte](https://github.com/storyblok/storyblok-svelte) is the Svelte SDK you need to interact with Storyblok API and enable the Real-time Visual Editing Experience
|
||||||
|
- [@svelte-on-solana/wallet-adapter](https://github.com/svelte-on-solana/wallet-adapter) is a modular TypeScript wallet adapter and UI components for Solana/Anchor applications using SvelteJS as framework
|
||||||
|
- [svelte-lookat](https://www.npmjs.com/package/svelte-lookat) creates a div which makes all its children follow the mouse cursor or the user's face when using a mobile phone
|
||||||
|
|
||||||
|
Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to continue the conversation.
|
||||||
|
|
||||||
|
See y'all next month!
|
@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: May 2022"
|
||||||
|
description: "Dynamically switch between HTML element types with `<svelte:element>`"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
With yesterday's Svelte Summit behind us, we've got a lot of news to share! Check out all of the recordings on the [Svelte Society YouTube Channel](https://www.youtube.com/sveltesociety) and the rest of this month's updates below...
|
||||||
|
|
||||||
|
## What's new in Svelte
|
||||||
|
- The `<svelte:element>` element lets you render an element of a dynamically specified type. This is useful, for example, when rendering rich text content from a CMS. Check out the [docs](https://svelte.dev/docs#template-syntax-svelte-element) or the [tutorial](https://svelte.dev/tutorial/svelte-element) for more info (**3.47.0**)!
|
||||||
|
|
||||||
|
|
||||||
|
## Language Tools updates
|
||||||
|
- `svelte:element` and `sveltekit:reload` are now supported
|
||||||
|
- Invalid Svelte import paths will now be automatically detected - see PR for getting back the old behavior ([#1448](https://github.com/sveltejs/language-tools/pull/1448))
|
||||||
|
- `source.sortImports` lets you sort imports without deleting unused imports ([#1338](https://github.com/sveltejs/language-tools/issues/1338))
|
||||||
|
- Hovering over HTML attributes will now show HTML hover info instead of the TS hover info - resulting in much more useful information ([#1447](https://github.com/sveltejs/language-tools/pull/1447))
|
||||||
|
- In VS Code, you can now wrap existing blocks of code in control flow tags using the `Insert Snippet` command ([#1373](https://github.com/sveltejs/language-tools/pull/1373))
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- Files and directories can now be named `__tests__` and `__test__` in the routes directory ([#4438](https://github.com/sveltejs/kit/pull/4438))
|
||||||
|
- Netlify Edge Functions ([#4657](https://github.com/sveltejs/kit/pull/4657)) and the Vercel build output API ([#4663](https://github.com/sveltejs/kit/pull/4663)) are now supported
|
||||||
|
- Custom `load` dependencies, array of strings representing URLs the page depends on, are now available when loading routes ([Docs](https://kit.svelte.dev/docs/loading#output-dependencies), [#4536](https://github.com/sveltejs/kit/pull/4536))
|
||||||
|
|
||||||
|
|
||||||
|
**Breaking Changes**
|
||||||
|
- Validators are now called "matchers" ([Docs](https://kit.svelte.dev/docs/routing#advanced-routing-matching), [#4358](https://github.com/sveltejs/kit/pull/4358))
|
||||||
|
- `__layout.reset` has been replaced by named layouts - which have much configurability for shared layout elements ([Docs](https://kit.svelte.dev/docs/layouts#named-layouts), [#4388](https://github.com/sveltejs/kit/pull/4388))
|
||||||
|
- Prerendering is now skipped for `rel="external"` links ([#4545](https://github.com/sveltejs/kit/pull/4545))
|
||||||
|
- `maxage` is now `cache` in `LoadOutput` ([#4690](https://github.com/sveltejs/kit/pull/4690))
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites built with Svelte**
|
||||||
|
- [polySpectra AR](https://ar.polyspectra.com/) lets you prototype faster 3D Printing with seamless AR file handoffs ([video demo](https://www.youtube.com/watch?v=VhYCeVGcG3E))
|
||||||
|
- [Pixel Art Together](https://github.com/liveblocks/pixel-art-together) is a free multiplayer pixel art editor powered by Liveblocks
|
||||||
|
- [Tooling Manager](https://tooling-manager.netlify.app/) lets you compare your JavaScript tech stack against industry standard boilerplates
|
||||||
|
- [Easy Portfolio](https://easy-portfolio.com/) generates a portfolio based on your GitHub profile
|
||||||
|
- [FLOAT](https://github.com/muttoni/float) is an attendance tracking program for events
|
||||||
|
- [The Coin Perspective](https://thecoinperspective.com/) is a cryptocurrency price tracker and portfolio management tool
|
||||||
|
- [Locutionis](https://github.com/pbouillon/locutionis) is a small, online reference of figures of speech (en français)
|
||||||
|
- [ASM Editor](https://asm-editor.specy.app/) is an all in one web editor for M68K and MIPS
|
||||||
|
- [Otium](https://github.com/alombi/otium) is a free and open source book manager and bookshelf organiser, that helps you managing your books and the ones you would like to read
|
||||||
|
- [Sinwaver](https://github.com/Hugo-Dz/Sinwaver) is an SVG sine wave generator
|
||||||
|
|
||||||
|
Want to contribute to a modern SvelteKit website? [Help build the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)!
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [4 tips for cleaner Svelte components](https://geoffrich.net/posts/clean-component-tips/) by Geoff Rich
|
||||||
|
- [Building a Clubhouse clone with Svelte and 100ms](https://www.100ms.live/blog/clubhouse-clone-with-svelte) By Seun Taiwo
|
||||||
|
- [SvelteKit uvu Testing: Fast Component Unit Tests](https://rodneylab.com/sveltekit-uvu-testing/) by Rodney Lab
|
||||||
|
- [SvelteKit JWT authentication tutorial](https://dev.to/pilcrowonpaper/sveltekit-jwt-authentication-tutorial-2m34) by pilcrowOnPaper
|
||||||
|
- [Converting a Rollup-based Svelte SPA to SvelteKit](https://github.com/sveltejs/kit/discussions/4595) by Simon H
|
||||||
|
- [Add Commitint, Commitizen, Standard Version, and Husky to SvelteKit Project](https://davipon.hashnode.dev/add-commitint-commitizen-standard-version-and-husky-to-sveltekit-project) by David Peng
|
||||||
|
|
||||||
|
_To Watch or Hear_
|
||||||
|
- [Rich Harris - The Road to SvelteKit 1.0 (Svelte Society NYC)](https://www.youtube.com/watch?v=s6a1pbTVcUs) by Svelte Society
|
||||||
|
- [Svelte Fundamentals - Intro to Svelte](https://codingcat.dev/course/intro-to-svelte) by Coding Cat
|
||||||
|
- [Svelte Components Using Custom Markdown Renderers - Weekly Svelte](https://www.youtube.com/watch?v=ZiEROAqobwM) by LevelUpTuts
|
||||||
|
- [Implementing {@const} in if block](https://www.youtube.com/watch?v=f5iReGqjmG0) by lihautan
|
||||||
|
- [Svelte and Contributing to Open-Source with Geoff Rich](https://podcast.20minjs.com/1952066/10417700-episode-6-svelte-and-contributing-to-open-source-with-geoff-rich) by 20minJS
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [KitDocs](https://github.com/svelteness/kit-docs) is a documentation integration for SvelteKit - like VitePress for Svelte.
|
||||||
|
- [Svelte Copy](https://github.com/ghostdevv/svelte-copy) is a click/tap-to-copy library that makes it easy to copy to the clipboard
|
||||||
|
- [Svend3r](https://github.com/oslabs-beta/svend3r) provides beautiful visualizations that harness the power of D3 to bring your data to life while abstracting away its imperative-style code
|
||||||
|
- [Svelte Hamburgers](https://github.com/ghostdevv/svelte-hamburgers) is the easy to use Hamburger menu component for Svelte
|
||||||
|
- [Svelte Droplet](https://github.com/probablykasper/svelte-droplet) is a file dropzone for Svelte
|
||||||
|
- [Svelte MP3](https://www.npmjs.com/package/svelte-mp3) is a light blazingly fast yet simple minimalistic audio player for Svelte
|
||||||
|
- [SvelteUI](https://github.com/Brisklemonade/svelteui) is a component library for building fully functional & accessible web applications faster than ever
|
||||||
|
- [svelte-spotlight](https://github.com/beynar/svelte-spotlight) is a headless spotlight component to help you build your site's global search box in minutes
|
||||||
|
- [svelte-pdf-simple](https://github.com/gspasov/svelte-pdf-simple) is a simple svelte library for displaying PDFs and giving you all the control
|
||||||
|
- [persistent-svelte-store](https://github.com/omer-g/persistent-svelte-store) is a generic persistent writable store, built from scratch in TypeScript according to the Svelte store contract
|
||||||
|
- [svelte-exmarkdown](https://github.com/ssssota/svelte-exmarkdown) is Svelte component to render markdown dynamically
|
||||||
|
- [Bookit](https://github.com/leveluptuts/bookit) is a storybook-like component rendering environment - finely tuned to work directly within your SvelteKit projects
|
||||||
|
|
||||||
|
Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to continue the conversation.
|
||||||
|
|
||||||
|
If you'd prefer to join us in person, Svelte Summit is finally transitioning properly into the real world. Come join us for two days of awesome Svelte content! [Get your tickets now!](https://ti.to/svelte/svelte-summit-fall-edition)
|
||||||
|
|
||||||
|
See y'all next month!
|
@ -0,0 +1,113 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: June 2022"
|
||||||
|
description: "Cancellable dispatched events, deeper {@const} declarations and more!"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
With last month's [Svelte Summit](https://www.youtube.com/watch?v=qqj2cBockqE) behind us, we're ready to apply everything we learned in this new month of June! Also new this month are some quality-of-life changes to `createEventDispatcher`, `@const` declarations and tons of progress toward SvelteKit 1.0.
|
||||||
|
|
||||||
|
Let's dive in!
|
||||||
|
|
||||||
|
## What's new in Svelte
|
||||||
|
- Custom events can now be cancelled in the `createEventDispatcher` function (**3.48.0**, [Docs](https://svelte.dev/docs#run-time-svelte-createeventdispatcher), [PR](https://github.com/sveltejs/svelte/pull/7064))
|
||||||
|
- The `{@const}` tag can now be used in `{#if}` blocks to conditionally define variables (**3.48.0**, [Docs](https://svelte.dev/docs#template-syntax-const), [PR](https://github.com/sveltejs/svelte/pull/7451))
|
||||||
|
- Lots of bug fixes across `<svelte:element>`, animations and various DOM elements. Check out the [CHANGELOG](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md#3480) for a deeper dive!
|
||||||
|
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- Vite 2.9.9 was released as one of the last Vite 2 releases. The Svelte team has been hard at work contributing to the Vite 3 release to make the integration between SvelteKit and Vite smoother than ever ([Vite 3.0 Milestone](https://github.com/vitejs/vite/milestone/5))
|
||||||
|
- `config.kit.alias` lets you more easily declare a custom alias to replace values in `import` statements ([Docs](https://kit.svelte.dev/docs/configuration#alias), [PR](https://github.com/sveltejs/kit/pull/4964))
|
||||||
|
- Pages marked for prerendering will now fail during SSR at runtime ([PR](https://github.com/sveltejs/kit/pull/4812))
|
||||||
|
|
||||||
|
**Breaking Changes**
|
||||||
|
- Node 14 is no longer supported ([PR](https://github.com/sveltejs/kit/pull/4922))
|
||||||
|
- Requests to `/favicon.ico` will no longer be suppressed and will instead be handled as a valid route ([PR](https://github.com/sveltejs/kit/pull/5046))
|
||||||
|
- AMP support has been moved to a separate `@sveltejs/amp` package ([Docs](https://kit.svelte.dev/docs/seo#manual-setup-amp), [PR](https://github.com/sveltejs/kit/pull/4710))
|
||||||
|
- Generated types are now written to `_types` directories - update your imports accordingly ([PR](https://github.com/sveltejs/kit/pull/4705))
|
||||||
|
- `%svelte.head%` and `%svelte.body%` are now `%sveltekit.head%` and `%sveltekit.body%` in `app.html` ([Docs](https://kit.svelte.dev/docs/migrating#project-files-src-template-html), [PR](https://github.com/sveltejs/kit/pull/5016/))
|
||||||
|
- `LoadInput` is now `LoadEvent`
|
||||||
|
- Dropped support for Wrangler 1 in favor of Wrangler 2 ([PR](https://github.com/sveltejs/kit/pull/4887))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites built with Svelte**
|
||||||
|
- [Plantarium](https://github.com/jim-fx/plantarium) is a tool for the procedural generation of 3D plants.
|
||||||
|
- [SPATULA](https://github.com/AlexWarnes/lamina-spatula) is a tool for building shading materials that are exportable as code material in any project that uses lamina and threejs
|
||||||
|
- [Waaard](https://waaard.com/) lets you create and send protected links with a variety of SSO providers
|
||||||
|
- [Magidoc](https://github.com/magidoc-org/magidoc) is a fast and highly customizable GraphQL documentation generator
|
||||||
|
- [myMarkmap](https://github.com/eyssette/myMarkmap) is a custom editor for Markmap, built with SvelteKit
|
||||||
|
- [PassShare](https://passshare.mynt.pw/) is a way for you to share your passwords to your friends, securely and effortlessly
|
||||||
|
- [DashingOS](https://beta.dashingos.com/) is a tool (like Notion + CodeSandbox) to make it quick and easy to prototype and document your work all in one place
|
||||||
|
- [worker-kit-email](https://github.com/miunau/worker-kit-email) helps you develop transactional emails quickly using regular SvelteKit routes
|
||||||
|
- [kaios-weather-svelte](https://github.com/cyan-2048/kaios-weather-svelte) is a very familiar looking weather app for KaiOS
|
||||||
|
- [svelte-gantt](https://github.com/ANovokmet/svelte-gantt) is a lightweight and fast interactive gantt chart/resource booking component
|
||||||
|
- [Miru](https://github.com/ThaUnknown/miru) is a BitTorrent streaming software for cats
|
||||||
|
|
||||||
|
Looking for a great SvelteKit website to contribute to? [Help build the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)!
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Component party](https://component-party.dev/) is a site that compares common patterns in different frameworks
|
||||||
|
- [Quick tip: style prop defaults](https://geoffrich.net/posts/style-prop-defaults/) by Geoff Rich
|
||||||
|
- [Working with reduced motion in Svelte](https://ghostdev.xyz/posts/working-with-reduced-motion-in-svelte) by GHOST
|
||||||
|
- [Building a Musical Instrument with the Web Audio API](https://www.taniarascia.com/musical-instrument-web-audio-api/) by Tania Rascia
|
||||||
|
- [Svelte-Cubed: Creating an Accessible and Consistent Experience Across Devices](https://dev.to/alexwarnes/svelte-cubed-creating-an-accessible-and-consistent-experience-across-devices-42ae) and [Svelte-Cubed: Loading Your glTF Models](https://dev.to/alexwarnes/svelte-cubed-loading-your-gltf-models-14lf) by Alex Warnes
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
|
||||||
|
From Svelte Society:
|
||||||
|
- [The Svelte Summit Spring 2022 stream recording](https://www.youtube.com/watch?v=qqj2cBockqE) has been updated with chapter markers to make it easy to watch again and again
|
||||||
|
- [The full recording of Svelte London, April 2022](https://www.youtube.com/watch?v=zIxzJzTnoxA) is up! Check out the amazing talks from across the Svelte London community
|
||||||
|
- [Persian Svelte Society](https://www.youtube.com/channel/UCfWH9lCsXN3j8oXq8dru82Q) is making Persian-language videos about Svelte
|
||||||
|
- Svelte Sirens has been talking monthly to creators and contributors across the Svelte Community:
|
||||||
|
- [SvelteKit + Sanity.io: a match made in heaven](https://www.youtube.com/watch?v=j0_1hfiEVWA&list=PL8bMgX1kyZThkJ_Rk6AAFI4eY24g5XKwK&index=5) on May 13
|
||||||
|
- [Slicing up your Svelte Sites with Prismic](https://www.youtube.com/watch?v=FUbHwwMALkk) on May 20
|
||||||
|
- [Rendering your Svelte apps on Render](https://www.youtube.com/watch?v=SnV_hMLVyqs) on May 24
|
||||||
|
- [The story behind the (unofficial) Svelte newsletter](https://www.youtube.com/watch?v=aK0xXm3hPxk&list=PL8bMgX1kyZThkJ_Rk6AAFI4eY24g5XKwK&index=7) on May 27
|
||||||
|
|
||||||
|
|
||||||
|
Across the Web:
|
||||||
|
- [Building vite-plugin-svelte-inspector](https://www.youtube.com/watch?v=udYB24IMtsY), [What is Singleton?](https://www.youtube.com/watch?v=xhi0m1QZue0) and [What is Navigation?](https://www.youtube.com/watch?v=Ym-OnGUps2c) by lihautan
|
||||||
|
- [Auto Import Components In Svelte Kit - Weekly Svelte](https://www.youtube.com/watch?v=JXvKBtTPr64) by LevelUpTuts
|
||||||
|
- [🧪 Test SvelteKit with TDD & VITEST 🧪](https://www.youtube.com/watch?v=5bQD3dCoyHA) by Johnny Magrippis
|
||||||
|
- [Google Analytics With SvelteKit](https://www.youtube.com/watch?v=l-x6H0fnqqQ), [Using WebSockets With SvelteKit](https://www.youtube.com/watch?v=mAcKzdW5fR8), [SvelteKit Authentication Using Cookies](https://www.youtube.com/watch?v=T935Ya4W5X0) and [Svelte Headless UI Component Library](https://www.reddit.com/r/sveltejs/comments/ueu849/svelte_headless_ui_component_library/) by Joy of Code
|
||||||
|
- [Named Layouts In Nested Routes in SvelteKit](https://www.youtube.com/watch?v=hKg_V3jouLk) by The Svelte Junction
|
||||||
|
- [SvelteKit Shiki Syntax Highlighting: Markdown Codeblocks](https://rodneylab.com/sveltekit-shiki-syntax-highlighting/) and [Svelte Capsize Styling: Typography Tooling](https://rodneylab.com/svelte-capsize-styling/) by Rodney Lab
|
||||||
|
|
||||||
|
_To Hear_
|
||||||
|
- Svelte Radio has been putting out weekly episodes:
|
||||||
|
- [The Adventures of Running a Svelte Meetup](https://www.svelteradio.com/episodes/the-adventures-of-running-a-svelte-meetup)
|
||||||
|
- [The other Rich! Geoff! (feat. Geoff Rich)](https://www.svelteradio.com/episodes/the-other-rich-geoff)
|
||||||
|
- [Inspecting Svelte Code with Dominik G.](https://www.svelteradio.com/episodes/inspecting-svelte-code-with-dominik-g)
|
||||||
|
- [Stores Galore](https://www.svelteradio.com/episodes/stores-galore)
|
||||||
|
- [Svelte and the Future of Frontend Development (feat. Rich Harris)](https://thenewstack.io/svelte-and-the-future-of-front-end-development/) from The New Stack
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [vite-plugin-svelte-console-remover](https://github.com/jhubbardsf/vite-plugin-svelte-console-remover) is a Vite plugin that removes all console statements (log, group, dir, error, etc) from Svelte, JS, and TS files during build so they don't leak into production
|
||||||
|
- [Svelte Headless Tables](https://github.com/bryanmylee/svelte-headless-table) is an unopinionated and extensible data tables for Svelte
|
||||||
|
- [y-presence](https://github.com/nimeshnayaju/y-presence) is a lightweight set of libraries to easily add presence (live cursors/avatars) to any web application (now with Svelte support!)
|
||||||
|
- [Svelcro](https://github.com/oslabs-beta/Svelcro) is a component performance tracker for Svelte applications
|
||||||
|
- [Svelte-Splitpanes](https://github.com/orefalo/svelte-splitpanes) lets you create dynamic and predictable view panels to layout an application
|
||||||
|
- [svelte-miniplayer](https://github.com/ThaUnknown/svelte-miniplayer) is a lightweight, fast, resizable and draggable miniplayer for media
|
||||||
|
- [svelte-keybinds](https://github.com/ThaUnknown/svelte-keybinds) is a minimalistic keybinding interface, with rebinding and saving
|
||||||
|
- [svelte-speech-recognition](https://github.com/jhubbardsf/svelte-speech-recognition) converts speech from the microphone to text and makes it available to your Svelte components
|
||||||
|
|
||||||
|
**Special Feature: Svelte Stores**
|
||||||
|
There were lots of Svelte stores released this month from a number of authors...
|
||||||
|
|
||||||
|
- [svelte-mutable-store](https://github.com/feltcoop/svelte-mutable-store) is a Svelte store for mutable values with the `immutable` compiler option
|
||||||
|
- [svelte-damped-store](https://github.com/aredridel/svelte-damped-store) is a derived writable store that can suspend updates while [svelte-lens-store](https://github.com/aredridel/svelte-lens-store) is a functional lens over Svelte stores
|
||||||
|
- [svelte-persistent-store](https://github.com/furudean/svelte-persistent-store) is a writable svelte store that saves and loads data from `Window.localStorage` or `Window.sessionStorage`.
|
||||||
|
|
||||||
|
|
||||||
|
Did we miss anything? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to add your voice.
|
||||||
|
|
||||||
|
Don't forget that you can also join us in-person at the Svelte Summit in Stockholm! Come join us for two days of awesome Svelte content! [Get your tickets now](https://ti.to/svelte/svelte-summit-fall-edition).
|
||||||
|
|
||||||
|
See y'all next month!
|
@ -0,0 +1,98 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: July 2022"
|
||||||
|
description: "Faster SSR, language tools improvements and a new paid contributor!"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
From faster SSR to support for Vitest and Storybook in SvelteKit, there's a lot to cover in this month's newsletter...
|
||||||
|
|
||||||
|
So let's dive in!
|
||||||
|
|
||||||
|
## OpenCollective funding drives Svelte forward
|
||||||
|
|
||||||
|
Svelte supporters have donated approximately $80,000 to [the project on OpenCollective](https://opencollective.com/svelte). We're happy to share that the funds are being drawn on to move Svelte forward in a meaningful way. **[@gtm-nayan](https://github.com/gtm-nayan)** has begun triaging and fixing SvelteKit issues this past month as a paid contributor to the project to help us get SvelteKit to a 1.0 level of stability! @gtm-nayan has been an active member of the Svelte community for quite some time and is well known for writing the bot that helps keep our Discord server running. We're happy that this funding has allowed Svelte to get much more of his time.
|
||||||
|
|
||||||
|
We will also be utilizing OpenCollective funds to allow Svelte core maintainers to attend [Svelte Summit](https://www.sveltesummit.com/) in person this fall. Thanks to everyone who has donated so far!
|
||||||
|
|
||||||
|
## What's new in Svelte & Language Tools
|
||||||
|
- [learn.svelte.dev](https://learn.svelte.dev/) is a new way to learn Svelte and SvelteKit from the ground up that is currently in development
|
||||||
|
- Faster SSR is coming in the next Svelte release. A PR two years in the making, resulting in up to 3x faster rendering in some benchmarking tests! ([PR](https://github.com/sveltejs/svelte/pull/5701))
|
||||||
|
- "Find File References" ([0.14.28](https://github.com/sveltejs/language-tools/releases/tag/language-server-0.14.28)) and "Find Component References" ([0.14.29](https://github.com/sveltejs/language-tools/releases/tag/language-server-0.14.29)) in the latest versions of the Svelte extension shows where Svelte files and components have been imported and used ([Demo](https://twitter.com/dummdidumm_/status/1532459709604716544/photo/1))
|
||||||
|
- The Svelte extension now supports CSS path completion ([0.14.29](https://github.com/sveltejs/language-tools/releases/tag/language-server-0.14.29))
|
||||||
|
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- Introduced `@sveltejs/kit/experimental/vite` which allows SvelteKit to interoperate with other tools in the Vite ecosystem like Vitest and Storybook ([#5094](https://github.com/sveltejs/kit/pull/5094)). Please [leave feedback](https://github.com/sveltejs/kit/issues/5184) as to whether the feature works and is helpful as we consider taking it out of experimental and making `vite.config.js` required for all users
|
||||||
|
- Streaming in endpoints is now supported ([#3419](https://github.com/sveltejs/kit/issues/3419)). This was enabled by switching to the Undici `fetch` implementation ([#5117](https://github.com/sveltejs/kit/pull/5117))
|
||||||
|
- Static assets can now be symlinked in development environments ([#5089](https://github.com/sveltejs/kit/pull/5089))
|
||||||
|
- `server` and `prod` environment variables are now available as a corollary to `browser` and `dev` ([#5251](https://github.com/sveltejs/kit/pull/5251))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites built with Svelte**
|
||||||
|
- [Virtual Maker](https://www.virtualmaker.net/) lets you make interactive 3D and VR scenes in your browser
|
||||||
|
- [Apple Beta Music](https://www.reddit.com/r/sveltejs/comments/v7ic2s/apple_beta_music_uses_svelte/) appears to have been written in some combination of Svelte and web components
|
||||||
|
- [Itatiaia](https://www.itatiaia.com.br/), the largest radio station in the country of Brazil just relaunched its news portal in SvelteKit
|
||||||
|
- [Pronauns](https://www.pronauns.com) helps you learn pronunciation online with IPA to speak better and sound more native
|
||||||
|
- [Immich](https://www.immich.app/) is an open source, high performance self-hosted backup solution for videos and photos on your mobile phone
|
||||||
|
- [Pendek](https://github.com/leovoon/link-shortener) is a link shortener built with SvelteKit, Prisma and PlanetScale
|
||||||
|
- [Grunfy](https://grunfy.com/tools) is a set of guitar tools - recently migrated to SvelteKit
|
||||||
|
- [Radiant: The Future of Radio](https://play.google.com/store/apps/details?id=co.broadcastapp.Radiant) is a personal radio station app built with Svelte and Capacitor
|
||||||
|
- [Imperfect Reminders](https://imperfectreminders.mildlyupset.com/) is a todo list for things that are only sort of time sensitive
|
||||||
|
- [Periodic Table](https://github.com/janosh/periodic-table) is a dynamic Periodic Table component written in Svelte
|
||||||
|
- [Svelvet](https://github.com/open-source-labs/Svelvet) is a lightweight Svelte component library for building interactive node-based diagrams
|
||||||
|
- [publint](https://github.com/bluwy/publint) lints for packaging errors to ensure compatibility across environments
|
||||||
|
- [Playlistr](https://github.com/alextana/spotify-playlist-creator) helps manage and create Spotify playlists
|
||||||
|
- [Geoff Rich's page transitions demo](https://twitter.com/geoffrich_/status/1534980702785003520) shows how SvelteKit's `beforeNavigate`/`afterNavigate` hooks can make smooth document transitions in the latest Chrome Canary
|
||||||
|
- [Menger Sponge](https://twitter.com/a_warnes/status/1536215896078811137) is a fractal built with Threlte
|
||||||
|
|
||||||
|
Want to contribute to a site using the latest SvelteKit features? [Help build the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)!
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_Starring the Svelte team_
|
||||||
|
- [Svelte Origins: A JavaScript Documentary](https://www.youtube.com/watch?v=kMlkCYL9qo0) by OfferZen Origins
|
||||||
|
- [Full Stack Documentation (announcing learn.svelte.dev)](https://portal.gitnation.org/contents/full-stack-documentation) by Rich Harris @ JSNation 2022
|
||||||
|
- [All About the Sirens](https://www.svelteradio.com/episodes/all-about-the-sirens) by Svelte Radio
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [SvelteKit Page Endpoints](https://www.youtube.com/watch?v=yQRf2wmTu5w), [Named Layouts](https://www.youtube.com/watch?v=UHX9TJ0BxZY) and [Passing data from page component to layout component with $page.stuff](https://www.youtube.com/watch?v=CXaCstU5pcw) by lihautan
|
||||||
|
- [🍞 & 🧈: Magically load data with SvelteKit Endpoints](https://www.youtube.com/watch?v=f6prqYlbTE4) by Johnny Magrippis
|
||||||
|
- [Svelte for React developers](https://www.youtube.com/watch?v=7tsrwrx5HtQ) by frontendtier
|
||||||
|
- [Learn Svelte JS || JavaScript Compiler for Building Front end Applications](https://www.youtube.com/watch?v=1rKRarJJFrY&list=PLIGDNOJWiL1-7zCgdR7MKuho-tPC6Ra6C&index=1) by Code with tsksharma
|
||||||
|
- [SvelteKit Authentication](https://www.youtube.com/watch?v=T935Ya4W5X0&list=PLA9WiRZ-IS_zKrDzhOhV5RGKKTHNIyTDO&index=1) by Joy of Code
|
||||||
|
- [Svelte + websockets: Build a real-time Auction app](https://www.youtube.com/watch?v=CqgsWFrwQIU) by Evgeny Maksimov
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Up-To-Date Analytics on a Static Website](https://paullj.github.io/posts/up-to-date-analytics-on-a-static-website) and [Fast, Lightweight Fuzzy Search using Fuse.js](https://paullj.github.io/posts/fast-lightweight-fuzzy-search-using-fuse.js) by paullj
|
||||||
|
- [Use SvelteKit as a handler in the ExpressJs project](https://chientrm.medium.com/use-sveltekit-as-a-handler-in-the-expressjs-project-15524b01128f) by Tran Chien
|
||||||
|
- [Creating a desktop application with Tauri and SvelteKit](https://github.com/Stijn-B/tauri-sveltekit-example) by Stijn-B
|
||||||
|
- [List of awesome Svelte stores](https://github.com/samuba/awesome-svelte-stores) by samuba
|
||||||
|
- [SvelteKit Content Security Policy: CSP for XSS Protection](https://rodneylab.com/sveltekit-content-security-policy/) by Rodney Lab
|
||||||
|
- [SvelteKit Hooks. Everything You Need To Know](https://kudadam.com/blog/understanding-sveltekit-hooks) by Lucretius K. Biah
|
||||||
|
- [3 tips for upgrading the performance of your Svelte stores](https://www.mathiaspicker.com/posts/3-tips-for-upgrading-the-performance-of-your-svelte-stores) by Mathias Picker
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [Svend3r](https://github.com/oslabs-beta/svend3r) is a plug and play D3 charting library for Svelte
|
||||||
|
- [Svelte Hover Draw SVG](https://github.com/davipon/svelte-hover-draw-svg) is a lightweight Svelte component to draw SVG on hover
|
||||||
|
- [Svelte French Toast](https://svelte-french-toast.com/) provides buttery smooth toast notifications that are lightweight, customizable, and beautiful by default
|
||||||
|
- [SVooltip](https://svooltip.vercel.app/) is a basic Svelte tooltip directive, powered by Floating UI
|
||||||
|
- [Svelte Brick Gallery](https://github.com/anotherempty/svelte-brick-gallery) is a masonry-like image gallery component for Svelte
|
||||||
|
- [use-vest](https://github.com/enyo/use-vest) is a Svelte action for Vest - a library that makes it easy to validate forms and show errors when necessary
|
||||||
|
- [Svelidate](https://github.com/svelidate/svelidate) is a simple and lightweight form validation library for Svelte with no dependencies
|
||||||
|
- [Svve11](https://github.com/oslabs-beta/Svve11) is an "accessibility-first" component library for Svelte
|
||||||
|
- [Slidy](https://github.com/Valexr/Slidy) is a simple, configurable & reusable carousel sliding action script with templates & some useful plugins
|
||||||
|
- [Svelte Component Snippets](https://marketplace.visualstudio.com/items?itemName=brysonbw.svelte-component-snippets) is a VS Code extension with access to common Svelte snippets
|
||||||
|
- [Svelte Confetti](https://github.com/Mitcheljager/svelte-confetti) adds a little bit of flair to your app with some confetti 🎊
|
||||||
|
|
||||||
|
|
||||||
|
What did we miss? Let us know on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to add your voice.
|
||||||
|
|
||||||
|
Don't forget that you can also join us in-person at the Svelte Summit in Stockholm! Come join us for two days of awesome Svelte content! [Get your tickets now](https://www.sveltesummit.com/).
|
||||||
|
|
||||||
|
See y'all next month!
|
@ -0,0 +1,119 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: August 2022"
|
||||||
|
description: "Changes to SvelteKit's `load` before 1.0 plus support for Vite 3 and `vite.config.js`!"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
There's a lot to cover this month... big changes are coming to SvelteKit's design before 1.0 can be completed. If you haven't already, check out Rich's Discussion, [Fixing `load`, and tightening up SvelteKit's design before 1.0 #5748](https://github.com/sveltejs/kit/discussions/5748).
|
||||||
|
|
||||||
|
Also, [@dummdidumm](https://github.com/dummdidumm) (Simon H) [has joined Vercel to work on Svelte full-time](https://twitter.com/dummdidumm_/status/1549041206348222464) and [@tcc-sejohnson](https://github.com/tcc-sejohnson) has joined the group of SvelteKit maintainers! We're super excited to have additional maintainers now dedicated to working on Svelte and SvelteKit and have already been noticing their impact. July was the third largest month for SvelteKit changes since its inception!
|
||||||
|
|
||||||
|
Now onto the rest of the updates...
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- Dynamically imported styles are now included during SSR ([#5138](https://github.com/sveltejs/kit/pull/5138))
|
||||||
|
- Improvements to routes and prop updates to prevent unnecessary rerendering ([#5654](https://github.com/sveltejs/kit/pull/5654), [#5671](https://github.com/sveltejs/kit/pull/5671))
|
||||||
|
- Lots of improvements to error handling ([#4665](https://github.com/sveltejs/kit/pull/4665), [#5622](https://github.com/sveltejs/kit/pull/5622), [#5619](https://github.com/sveltejs/kit/pull/5619), [#5616](https://github.com/sveltejs/kit/pull/5616))
|
||||||
|
- Custom Vite modes are now respected in SSR builds ([#5602](https://github.com/sveltejs/kit/pull/5602))
|
||||||
|
- Custom Vite config locations are now supported ([#5705](https://github.com/sveltejs/kit/pull/5705))
|
||||||
|
- Private environment variables (aka "secrets") are now much more secure. Now if you accidentally import them to client-side code, you'll see an error ([#5663](https://github.com/sveltejs/kit/pull/5663), [Docs](https://kit.svelte.dev/docs/configuration#env))
|
||||||
|
- Vercel's v3 build output API is now being used in `adapter-vercel` ([#5514](https://github.com/sveltejs/kit/pull/5514))
|
||||||
|
- `vite-plugin-svelte` has reached 1.0 and now supports Vite 3. You'll notice new default ports for `dev` (port 5173) and `preview` (port 4173) ([#5005](https://github.com/sveltejs/kit/pull/5005), [vite-plugin-svelte CHANGELOG](https://github.com/sveltejs/vite-plugin-svelte/blob/main/packages/vite-plugin-svelte/CHANGELOG.md))
|
||||||
|
|
||||||
|
**Breaking changes:**
|
||||||
|
- `mode`, `prod` and `server` are no longer available in `$app/env` ([#5602](https://github.com/sveltejs/kit/pull/5602))
|
||||||
|
- `svelte-kit` CLI commands are now run using the `vite` command and `vite.config.js` is required. This will allow first-class support with other projects in the Vite ecosystem like Vitest and Storybook ([#5332](https://github.com/sveltejs/kit/pull/5332), [Docs](https://kit.svelte.dev/docs/project-structure#project-files-vite-config-js))
|
||||||
|
- `endpointExtensions` is now `moduleExtensions` and can be used to filter param matchers ([#5085](https://github.com/sveltejs/kit/pull/5085), [Docs](https://kit.svelte.dev/docs/configuration#moduleextensions))
|
||||||
|
- Node 16.9 is now the minimum version for SvelteKit ([#5395](https://github.com/sveltejs/kit/pull/5395))
|
||||||
|
- %-encoded filenames are now allowed. If you had a `%` in your route, you must now encode it with `%25` ([#5056](https://github.com/sveltejs/kit/pull/5056))
|
||||||
|
- Endpoint method names are now uppercased to match HTTP specifications ([#5513](https://github.com/sveltejs/kit/pull/5513), [Docs](https://kit.svelte.dev/docs/routing#endpoints))
|
||||||
|
- `writeStatic` has been removed to align with Vite's config ([#5618](https://github.com/sveltejs/kit/pull/5618))
|
||||||
|
- `transformPage` is now `transformPageChunk` ([#5657](https://github.com/sveltejs/kit/pull/5657), [Docs](https://kit.svelte.dev/docs/hooks#handle))
|
||||||
|
- The `prepare` script is no longer needed in `package.json` ([#5760](https://github.com/sveltejs/kit/pull/5760))
|
||||||
|
- `adapter-node` no longer does any compression while we wait for a [bug fix in the `compression` library](https://github.com/expressjs/compression/pull/183) ([#5560](https://github.com/sveltejs/kit/pull/5506))
|
||||||
|
|
||||||
|
For a full list of changes, check out kit's [CHANGELOG](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).
|
||||||
|
|
||||||
|
|
||||||
|
## What's new in Svelte & Language Tools
|
||||||
|
- The `@layer` [CSS at-rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) is now supported in Svelte components (**3.49.0**, [PR](https://github.com/sveltejs/svelte/issues/7504))
|
||||||
|
- The `inert` [HTML attribute](https://html.spec.whatwg.org/multipage/interaction.html#the-inert-attribute) is now supported in Svelte's language tools and plugins (**105.20.0**, [PR](https://github.com/sveltejs/language-tools/pull/1565))
|
||||||
|
- The Svelte plugin will now use `SvelteComponentTyped` typings, if available (**105.19.0**, [PR](https://github.com/sveltejs/language-tools/pull/1548))
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites built with Svelte**
|
||||||
|
- [PocketBase](https://github.com/pocketbase/pocketbase) is an open source Go backend with a single file and an admin dashboard built with Svelte
|
||||||
|
- [Hondo](https://www.playhondo.com/how-to-play) is a word guessing game with multiple rounds
|
||||||
|
- [Hexapipes](https://github.com/gereleth/hexapipes) is a site for playing hexagonal pipes puzzle
|
||||||
|
- [Mail Must Move](https://www.mordon.app/) is an email made for those who want to get more done
|
||||||
|
- [Jot Down](https://github.com/brysonbw/vscode-jot-down) is a Visual Studio Code extension for quick and simple note taking
|
||||||
|
- [Kadium](https://kadium.kasper.space/) is an app for staying on top of YouTube channels' uploads
|
||||||
|
- [Samen zjin we #1metS10](https://1mets10.avrotros.nl/) is a campaign website to support S10, the dutch Eurovision finalist, by sending a drawing or a wish
|
||||||
|
- [On Writing Code](https://onwritingcode.com/) is an interactive website to learn programming design patterns
|
||||||
|
- [Svelte-In-Motion](https://github.com/novacbn/svelte-in-motion) lets you create Svelte-animated videos in your browser
|
||||||
|
- [Svelte Terminal](https://github.com/Nico-Mayer/svelte-terminal) is a terminal-like website
|
||||||
|
- [Bulletlist](https://bulletlist.com/) is a simple tool with a single purpose: making lists
|
||||||
|
- [Remind Me Again](https://github.com/probablykasper/remind-me-again) is an app for toggleable reminders on Mac, Linux and Windows
|
||||||
|
- [Heyweek](https://heyweek.com/) is a timetracking app built for freelancers craving that extra pizzazz
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_Starring the Svelte team_
|
||||||
|
- [The Svelte Documentary is out!](https://www.svelteradio.com/episodes/the-svelte-documentary-is-out) on Svelte Radio
|
||||||
|
- [Beginner SvelteKit](https://vercel.com/docs/beginner-sveltekit) by Vercel
|
||||||
|
- [Challenge: Explore Svelte by Building a Bubble Popping Game](https://prismic.io/blog/try-svelte-build-game) by Brittney Postma
|
||||||
|
- [Let's write a Client-side Routing Library with Svelte](https://www.youtube.com/watch?v=3foVDSknGEY) by lihautan
|
||||||
|
- [Svelte Sirens July Talk - Testing in Svelte with Jess Sachs](https://sveltesirens.dev/event/testing-in-svelte)
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [10 Awesome Svelte UI Component Libraries](https://www.youtube.com/watch?v=RkD88ARvucM) by LevelUpTuts
|
||||||
|
- [Learn How SvelteKit Works](https://www.youtube.com/watch?v=VizuTy3uSNE) and [SvelteKit Endpoints](https://www.youtube.com/watch?v=XnVxDLTgCgo) by Joy of Code
|
||||||
|
- [SvelteKit using TS, and Storybook setup](https://www.youtube.com/watch?v=L4F5dSu0FcQ) by Jarrod Kane
|
||||||
|
- [Building Apps with Svelte!](https://www.youtube.com/watch?v=prsXVk1fdW4) by Simon Grimm
|
||||||
|
- [SvelteKit authentication, the better way - Tutorial](https://www.youtube.com/watch?v=Y98KipzwVdM) by Pilcrow
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Some assorted Svelte demos](https://geoffrich.net/posts/assorted-svelte-demos/) by Geoff Rich
|
||||||
|
- [Three ways to bootstrap a Svelte project](https://maier.tech/posts/three-ways-to-bootstrap-a-svelte-project) by Thilo Maier
|
||||||
|
- [Design & build an app with Svelte](https://bootcamp.uxdesign.cc/design-build-an-app-with-svelte-ecd7ed0729da) by Hugo
|
||||||
|
- [Define routes via JS in SvelteKit](https://dev.to/maxcore/define-routes-via-js-in-sveltekit-27e9) by Max Core
|
||||||
|
- [Integrating Telegram api with SvelteKit](https://dev.to/theether0/integrating-telegram-api-with-sveltekit-5gb) by Shivam Meena
|
||||||
|
- [SvelteKit SSG: how to Prerender your SvelteKit Site](https://rodneylab.com/sveltekit-ssg/) by Rodney Lab
|
||||||
|
- [ADEO Design System: Building a Web Component library with Svelte and Rollup](https://medium.com/adeo-tech/adeo-design-system-building-a-web-component-library-with-svelte-and-rollup-72d65de50163) by Mohamed Mokhtari
|
||||||
|
- [The Svelte Handbook](https://thevalleyofcode.com/svelte/) by The Valley of Code
|
||||||
|
- [Test Svelte Component Using Vitest & Playwright](https://davipon.hashnode.dev/test-svelte-component-using-vitest-playwright) by David Peng
|
||||||
|
- [Transitional Apps with Phoenix and Svelte](https://nathancahill.com/phoenix-svelte) by Nathan Cahill
|
||||||
|
|
||||||
|
_Tech Demos_
|
||||||
|
- [Bringing the best GraphQL experience to Svelte](https://www.the-guild.dev/blog/houdini-and-kitql) by The Guild
|
||||||
|
- [Style your Svelte website faster with Stylify CSS](https://stylifycss.com/blog/style-your-svelte-website-faster-with-stylify-css/) by Stylify
|
||||||
|
- [Revamped Auth Helpers for Supabase (with SvelteKit support)](https://supabase.com/blog/2022/07/13/supabase-auth-helpers-with-sveltekit-support) by Supabase
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [Lucia](https://github.com/pilcrowOnPaper/lucia-sveltekit) is a simple, JWT based authentication library for SvelteKit that connects your SvelteKit app with your database
|
||||||
|
- [Skeleton](https://github.com/Brain-Bones/skeleton) is a UI component library for use with Svelte + Tailwind
|
||||||
|
- [pass-composer](https://pass-composer.vercel.app/) helps you compose your postprocessing passes for threlte scenes
|
||||||
|
- [@crikey/stores-*](https://whenderson.github.io/stores-mono/) is a collection of libraries to extend Svelte stores for common use-cases
|
||||||
|
- [Svelte Chrome Storage](https://github.com/shaun-wild/svelte-chrome-storage) is a lightweight abstraction between Svelte stores and Chrome extension storage
|
||||||
|
- [Svelte Schema Form](https://github.com/restspace/svelte-schema-form) is a form generator for JSON schema
|
||||||
|
- [svelte-gesture](https://github.com/wobsoriano/svelte-gesture) is a library that lets you bind richer mouse and touch events to any component or view
|
||||||
|
- [Snap Layout](https://github.com/ThaUnknown/snap-layout) and [universal-title-bar](https://github.com/ThaUnknown/universal-title-bar) bring Windows 11 snap layout and title features to webapps and PWAs. Both can be imported as a `.svelte` module or as a web component
|
||||||
|
- [svelte-adapter-bun](https://github.com/gornostay25/svelte-adapter-bun) is an adapter for SvelteKit apps that generates a standalone Bun server
|
||||||
|
- [json2dir](https://www.npmjs.com/package/json2dir) converts JSON objects into directory trees
|
||||||
|
- [Svelte Command Palette](https://github.com/rohitpotato/svelte-command-palette) is a drop-in command palette component
|
||||||
|
- [svelte-use-drop-outside](https://github.com/untemps/svelte-use-drop-outside) is a Svelte action to drop an element outside an area
|
||||||
|
- [PowerTable](https://github.com/muonw/powertable) is a JavaScript component that turns JSON data into an interactive HTML table
|
||||||
|
- [svelte-slides](https://github.com/rajasegar/svelte-slides) is a slide show template for Svelte using Reveal.js
|
||||||
|
- [Svelte Theme Light](https://marketplace.visualstudio.com/items?itemName=webmaek.svelte-theme-light) is a Visual Studio Code theme based on the Svelte REPL
|
||||||
|
|
||||||
|
Did we miss anything? Let us know on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs)!
|
||||||
|
|
||||||
|
Still looking for something to do in September? Come join us at the Svelte Summit in Stockholm! [Get your tickets now](https://www.sveltesummit.com/).
|
||||||
|
|
||||||
|
See ya next month!
|
@ -0,0 +1,102 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: December 2022"
|
||||||
|
description: "Rounding the corner to SvelteKit 1.0"
|
||||||
|
author: Dani Sandoval
|
||||||
|
authorURL: https://dreamindani.com
|
||||||
|
---
|
||||||
|
|
||||||
|
SvelteKit 1.0 is just around the corner! With [99% of the milestone issues completed](https://github.com/sveltejs/kit/milestone/2), there's a lot of new changes from the last month to cover...
|
||||||
|
|
||||||
|
Let's get to it!
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- Use the `willUnload` property to find out if the navigation will result the app being unloaded (full page reload/closing/leaving to another page). ([#6813](https://github.com/sveltejs/kit/pull/6813))
|
||||||
|
- `__data.json` requests now allows for caching while ensuring we cache matching responses for all invalidation scenarios ([#7532](https://github.com/sveltejs/kit/pull/7532))
|
||||||
|
- Linking to `<a name="hash">` tags is now supported ([#7596](https://github.com/sveltejs/kit/pull/7596))
|
||||||
|
- Throwing redirects in the `handle` hook is now supported ([#7612](https://github.com/sveltejs/kit/pull/7612))
|
||||||
|
- A fallback component will now be added automatically for layouts without one ([#7619](https://github.com/sveltejs/kit/pull/7619))
|
||||||
|
- The new `preload` function within the `resolve` hook determines what files should be added to the <head> tag to preload it ([Docs](https://kit.svelte.dev/docs/hooks#server-hooks-handle), [#4963](https://github.com/sveltejs/kit/pull/4963), [#7704](https://github.com/sveltejs/kit/pull/7704))
|
||||||
|
- `version` is now available via `$app/environment` ([#7689](https://github.com/sveltejs/kit/pull/7689), [#7694](https://github.com/sveltejs/kit/pull/7694))
|
||||||
|
- `handleError` can now return a promise ([#7780](https://github.com/sveltejs/kit/pull/7780))
|
||||||
|
|
||||||
|
|
||||||
|
**Breaking changes:**
|
||||||
|
- `routeId` is now `route.id` ([#7450](https://github.com/sveltejs/kit/pull/7450))
|
||||||
|
- 'load' has been renamed to 'enter' and 'unload' to 'leave' in the `beforeNavigate` and `afterNavigate` methods. `beforeNavigate` is now called once with type 'unload' on external navigation and will no longer run during redirects ([#7502](https://github.com/sveltejs/kit/pull/7502), [#7529](https://github.com/sveltejs/kit/pull/7529), [#7588](https://github.com/sveltejs/kit/pull/7588))
|
||||||
|
- The `redirect` helper will now only allow status codes between 300-308 for redirects and only `error` status codes between 400-599 are allowed ([#7767](https://github.com/sveltejs/kit/pull/7767)) ([#7615](https://github.com/sveltejs/kit/pull/7615), [#7767](https://github.com/sveltejs/kit/pull/7767))
|
||||||
|
- Special characters will now be encoded with hex/unicode escape sequences in route directory names ([#7644](https://github.com/sveltejs/kit/pull/7644))
|
||||||
|
- devalue is now used to (de)serialize action data - this is only a breaking change for everyone who fetches the actions directly and doesn't go through `use:enhance` ([#7494](https://github.com/sveltejs/kit/pull/7494))
|
||||||
|
- `trailingSlash` is now a page option, rather than configuration ([#7719](https://github.com/sveltejs/kit/pull/7719))
|
||||||
|
- The client-side router now ignores links outside `%sveltekit.body%` ([#7766](https://github.com/sveltejs/kit/pull/7766))
|
||||||
|
- `prerendering` is now named `building`, and `config.kit.prerender.enabled` has been removed ([#7762](https://github.com/sveltejs/kit/pull/7762))
|
||||||
|
- `getStaticDirectory()` has been removed from the builder API ([#7809](https://github.com/sveltejs/kit/pull/7809))
|
||||||
|
- The `format` option has been removed from `generateManifest(...)` ([#7820](https://github.com/sveltejs/kit/pull/7820))
|
||||||
|
- `data-sveltekit-prefetch` has been replaced with `-preload-code` and `-preload-data`, `prefetch` is now `preloadData` and `prefetchRoutes` is now `preloadCode` ([#7776](https://github.com/sveltejs/kit/pull/7776), [#7776](https://github.com/sveltejs/kit/pull/7776))
|
||||||
|
- `SubmitFunction` has been moved from `$app/forms` into `@sveltejs/kit` ([#7003](https://github.com/sveltejs/kit/pull/7003))
|
||||||
|
|
||||||
|
## New in Svelte
|
||||||
|
- The css compiler options of `css: false` and `css: true` have been replaced with `'external' | 'injected' | 'none'` settings to speed up compilation for `ssr` builds and improve clarity (**3.53.0**)
|
||||||
|
|
||||||
|
For all the changes to the Svelte compiler, including unreleased changes, check out the [CHANGELOG](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites built with Svelte**
|
||||||
|
- [Appwrite's new console](https://github.com/appwrite/console) makes its secure backend server for web, mobile & Flutter developers avaiable in the browser
|
||||||
|
- [RepoMagic](https://www.repomagic.com/) is a search and analytics tool for GitHub
|
||||||
|
- [Podman Desktop](https://github.com/containers/podman-desktop) is a graphical tool for developing on containers and Kubernetes
|
||||||
|
- [Ballerine](https://github.com/ballerine-io/ballerine) is a Know Your Customer (KYC) UX for any vertical or geography using modular building blocks, components, and 3rd party integrations
|
||||||
|
- [Budget Pen](https://github.com/Nico-Mayer/budget_pen) is a Codepen-like browser code editor with Tailwind included
|
||||||
|
- [doTogether](https://github.com/SarcevicAntonio/doTogether) helps you keep track of stuff you have get done via a List of recurring Tasks
|
||||||
|
- [Webscraped College Results](https://www.redditcollegeresults.com/) is a collection of visualizations for data from r/collegeresults
|
||||||
|
- [Let's premortem](https://letspremortem.com/) helps avoid lengthy, frustrating post-mortems after a project fails
|
||||||
|
- [BLKMARKET.COM](https://beta.blkmarket.com/) is an illustration library for commercial and personal use
|
||||||
|
- [Sigil](https://sigilspace.com/) is a canvas for anything with spaces organized by the most-voted content
|
||||||
|
- [corpus-activity-streams](https://github.com/ryanatkn/corpus-activity-streams) is an unofficial ActivityStreams 2.0 vocabulary data set and alternative docs
|
||||||
|
- [nodeMyAdmin](https://github.com/Andrea055/nodeMyAdmin) is an alternative to phpMyAdmin written with SvelteKit
|
||||||
|
- [Image to Pattern Conversion](https://www.thread-bare.com/convert) is a cross-stitch pattern conversion tool with [a list of pre-made patterns](https://www.thread-bare.com/store) to start with
|
||||||
|
- [Verbums](https://verbums.vdoc.dev/) is an English vocabulary trainer to improve language comprehension
|
||||||
|
- [SVGPS](https://svgps.app/) removes the burden of working with a cluster of SVG files by converting your icons into a single JSON file
|
||||||
|
- [This 3D retro-themed asteroid shooter](https://photon-alexwarnes.vercel.app/showcase/asteroids) was made with threlte
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_To Hear_
|
||||||
|
- [Catching up after Svelte Summit](https://www.svelteradio.com/episodes/catching-up) and [3D, WebGL and AI](https://www.svelteradio.com/episodes/3d-webgl-and-ai) by Svelte Radio
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [Domenik Reitzner - The easy way, an introduction to Sveltekit](https://www.youtube.com/watch?v=t-LKRrNedps) from Svelte Society Vienna
|
||||||
|
- [Sirens: Form Actions](https://www.youtube.com/watch?v=2OISk5-EHek) - Kev joins the Sirens again to chat about Form actions in SvelteKit and create a new form for speaker submissions on SvelteSirens.dev
|
||||||
|
- [Introduction To 3D With Svelte (Threlte)](https://www.youtube.com/watch?v=89LYeHOncVk), [How To Use Global Styles In SvelteKit](https://www.youtube.com/watch?v=jHSwChkx3TQ) and [Progressive Form Enhancement With SvelteKit](https://www.youtube.com/watch?v=6pv70d7i-3Q) by Joy of Code
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Building tic-tac-toe with Svelte](https://geoffrich.net/posts/tic-tac-toe/) by Geoff Rich
|
||||||
|
- [Speed up SvelteKit Pages With a Redis Cache](https://www.captaincodeman.com/speed-up-sveltekit-pages-with-a-redis-cache) by Captain Codeman
|
||||||
|
- [Understanding environment variables in SvelteKit](https://www.okupter.com/blog/environment-variables-in-sveltekit), [Form validation with SvelteKit and Zod](https://www.okupter.com/blog/sveltekit-form-validation-with-zod) and [Build a SvelteKit application with Docker](https://www.okupter.com/blog/build-a-sveltekit-application-with-docker) by Justin Ahinon
|
||||||
|
- [Why I failed to create the "Solid.js's store" for Svelte, and announcing svelte-store-tree v0.3.1](https://dev.to/igrep/why-i-failed-to-create-the-solidjss-store-for-svelte-and-announcing-svelte-store-tree-v031-1am2) by YAMAMOTO Yuji
|
||||||
|
- [Create an offline-first and installable PWA with SvelteKit and workbox-precaching](https://www.sarcevic.dev/offline-first-installable-pwa-sveltekit-workbox-precaching) by Antonio Sarcevic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [Skeleton](https://www.skeleton.dev/) is a UI toolkit to build fast and reactive web interfaces using Svelte + Tailwind CSS
|
||||||
|
- [svelte-svg-spinners](https://github.com/luluvia/svelte-svg-spinners) is a collection of SVG Spinners components
|
||||||
|
- [Svelte Floating UI](https://github.com/fedorovvvv/svelte-floating-ui) enables floating UIs with actions - no wrapper components or component bindings required
|
||||||
|
- [at-html](https://github.com/micha-lmxt/at-html) lets you use `{@html }` tags with slots in Svelte apps
|
||||||
|
- [html-svelte-parser](https://github.com/PatrickG/html-svelte-parser) is a HTML to Svelte parser that works on both the server (Node.js) and the client (browser)
|
||||||
|
- [svelte-switcher](https://github.com/rohitpotato/svelte-switcher) is a fully customisable, touch-friendly, accessible and tiny toggle component
|
||||||
|
- [sveltkit-hook-html-minifier](https://www.npmjs.com/package/@svackages/sveltkit-hook-html-minifier) is a hook that wrapps `html-minifier`
|
||||||
|
- [sveltekit-hook-redirect](https://www.npmjs.com/package/@svackages/sveltekit-hook-redirect) is a hook that makes redirects easy
|
||||||
|
- [sveltekit-video-meet](https://github.com/harshmangalam/sveltekit-video-meet) is a video calling web app built with SvelteKit and SocketIO
|
||||||
|
- [svelte-colourpicker](https://www.npmjs.com/package/svelte-colourpicker) is a lightweight opinionated colour picker component for Svelte
|
||||||
|
- [Svelte-HeadlessUI](https://captaincodeman.github.io/svelte-headlessui/) is an unofficial implementation of Tailwind HeadlessUI for Svelte
|
||||||
|
- [svelte-lazyimage-cache](https://github.com/binsarjr/svelte-lazyimage-cache) is a Lazy Image component with IntersectionObserver and cache action
|
||||||
|
- [threlte v5.0](https://www.reddit.com/r/sveltejs/comments/ywit18/threlte_v50_is_here_a_completely_new_developer/) is a completely new developer experience that is faster, more powerful, and incredibly flexible
|
||||||
|
|
||||||
|
|
||||||
|
That's it for this month! Let us know if we missed anything on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.gg/svelte)
|
||||||
|
|
||||||
|
See ya next near 🎆
|
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./.svelte-kit/tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"allowJs": true,
|
|
||||||
"checkJs": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"strict": true
|
|
||||||
}
|
|
||||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files
|
|
||||||
//
|
|
||||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
|
||||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,25 +1,51 @@
|
|||||||
{
|
{
|
||||||
"name": "sites",
|
"name": "svelte.dev",
|
||||||
"version": "0.0.1",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"description": "Docs and examples for Svelte",
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "node scripts/update.js && vite dev",
|
||||||
"build": "vite build",
|
"build": "node scripts/update.js && vite build",
|
||||||
|
"update": "node scripts/update.js --force=true",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
|
"start": "node build",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
||||||
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
"format": "npm run check:format -- --write",
|
||||||
"format": "prettier --plugin-search-dir . --write ."
|
"check:format": "prettier --check . --ignore-path .gitignore --plugin-search-dir=.",
|
||||||
|
"test": "uvu -r ts-node/register src/lib/server/markdown"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@supabase/supabase-js": "^2.7.0",
|
||||||
|
"@sveltejs/repl": "0.0.3",
|
||||||
|
"cookie": "^0.5.0",
|
||||||
|
"devalue": "^4.2.3",
|
||||||
|
"do-not-zip": "^1.0.0",
|
||||||
|
"flru": "^1.0.2",
|
||||||
|
"sourcemap-codec": "^1.4.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@resvg/resvg-js": "^2.2.0",
|
||||||
"@sveltejs/adapter-auto": "^1.0.2",
|
"@sveltejs/adapter-auto": "^1.0.2",
|
||||||
"@sveltejs/kit": "^1.2.9",
|
"@sveltejs/kit": "^1.3.10",
|
||||||
|
"@sveltejs/site-kit": "^3.2.1",
|
||||||
|
"@sveltejs/vite-plugin-svelte": "^2.0.2",
|
||||||
|
"degit": "^2.8.4",
|
||||||
|
"dotenv": "^16.0.3",
|
||||||
|
"jimp": "^0.16.2",
|
||||||
|
"marked": "^4.2.12",
|
||||||
|
"node-fetch": "^3.3.0",
|
||||||
"prettier": "^2.8.3",
|
"prettier": "^2.8.3",
|
||||||
"prettier-plugin-svelte": "^2.9.0",
|
"prettier-plugin-svelte": "^2.9.0",
|
||||||
|
"prism-svelte": "^0.5.0",
|
||||||
|
"prismjs": "^1.29.0",
|
||||||
|
"satori": "^0.1.2",
|
||||||
|
"satori-html": "^0.3.2",
|
||||||
|
"shelljs": "^0.8.5",
|
||||||
"svelte": "^3.55.1",
|
"svelte": "^3.55.1",
|
||||||
"svelte-check": "^3.0.3",
|
"svelte-check": "^3.0.3",
|
||||||
"typescript": "^4.9.4",
|
"typescript": "^4.9.5",
|
||||||
"vite": "^4.0.4"
|
"vite": "^4.0.4",
|
||||||
},
|
"vite-imagetools": "^4.0.18"
|
||||||
"type": "module"
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
import 'dotenv/config';
|
||||||
|
import fs from 'fs';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
import Jimp from 'jimp';
|
||||||
|
import { dirname } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const force = process.env.FORCE_UPDATE === 'true';
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
process.chdir(__dirname);
|
||||||
|
|
||||||
|
const outputFile = `../src/routes/_components/Supporters/contributors.js`;
|
||||||
|
if (!force && fs.existsSync(outputFile)) {
|
||||||
|
console.info(`[update/contributors] ${outputFile} exists. Skipping`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const base = `https://api.github.com/repos/sveltejs/svelte/contributors`;
|
||||||
|
const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = process.env;
|
||||||
|
|
||||||
|
const MAX = 24;
|
||||||
|
const SIZE = 128;
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const contributors = [];
|
||||||
|
let page = 1;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const res = await fetch(
|
||||||
|
`${base}?client_id=${GITHUB_CLIENT_ID}&client_secret=${GITHUB_CLIENT_SECRET}&per_page=100&page=${page++}`
|
||||||
|
);
|
||||||
|
const list = await res.json();
|
||||||
|
|
||||||
|
if (list.length === 0) break;
|
||||||
|
|
||||||
|
contributors.push(...list);
|
||||||
|
}
|
||||||
|
|
||||||
|
const authors = contributors
|
||||||
|
.filter(({ login }) => !login.includes('[bot]'))
|
||||||
|
.sort((a, b) => b.contributions - a.contributions)
|
||||||
|
.slice(0, MAX);
|
||||||
|
|
||||||
|
const sprite = new Jimp(SIZE * authors.length, SIZE);
|
||||||
|
|
||||||
|
for (let i = 0; i < authors.length; i += 1) {
|
||||||
|
const author = authors[i];
|
||||||
|
console.log(`${i + 1} / ${authors.length}: ${author.login}`);
|
||||||
|
|
||||||
|
const image_data = await fetch(author.avatar_url);
|
||||||
|
const buffer = await image_data.arrayBuffer();
|
||||||
|
|
||||||
|
const image = await Jimp.read(buffer);
|
||||||
|
image.resize(SIZE, SIZE);
|
||||||
|
|
||||||
|
sprite.composite(image, i * SIZE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await sprite.quality(80).write(`../src/routes/_components/Supporters/contributors.jpg`);
|
||||||
|
// TODO: Optimizing the static/contributors.jpg image should probably get automated as well
|
||||||
|
console.log(
|
||||||
|
'remember to additionally optimize the resulting /static/contributors.jpg image file via e.g. https://squoosh.app '
|
||||||
|
);
|
||||||
|
|
||||||
|
const str = `[\n\t${authors.map((a) => `'${a.login}'`).join(',\n\t')}\n]`;
|
||||||
|
|
||||||
|
fs.writeFileSync(outputFile, `export default ${str};`);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
@ -0,0 +1,66 @@
|
|||||||
|
import 'dotenv/config';
|
||||||
|
import fs from 'fs';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
import Jimp from 'jimp';
|
||||||
|
import { dirname } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const force = process.env.FORCE_UPDATE === 'true';
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
process.chdir(__dirname);
|
||||||
|
|
||||||
|
const outputFile = `../src/routes/_components/Supporters/donors.js`;
|
||||||
|
if (!force && fs.existsSync(outputFile)) {
|
||||||
|
console.info(`[update/donors] ${outputFile} exists. Skipping`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MAX = 24;
|
||||||
|
const SIZE = 128;
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const res = await fetch('https://opencollective.com/svelte/members/all.json');
|
||||||
|
const donors = await res.json();
|
||||||
|
|
||||||
|
const unique = new Map();
|
||||||
|
donors.forEach((d) => unique.set(d.profile, d));
|
||||||
|
|
||||||
|
let backers = [...unique.values()]
|
||||||
|
.filter(({ role }) => role === 'BACKER')
|
||||||
|
.sort((a, b) => b.totalAmountDonated - a.totalAmountDonated)
|
||||||
|
.slice(0, 3 * MAX);
|
||||||
|
|
||||||
|
const included = [];
|
||||||
|
for (let i = 0; included.length < MAX; i += 1) {
|
||||||
|
const backer = backers[i];
|
||||||
|
console.log(`${included.length + 1} / ${MAX}: ${backer.name}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const image_data = await fetch(backer.image);
|
||||||
|
const buffer = await image_data.arrayBuffer();
|
||||||
|
const image = await Jimp.read(buffer);
|
||||||
|
image.resize(SIZE, SIZE);
|
||||||
|
included.push({ backer, image });
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`Skipping ${backer.name}: no image data`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sprite = new Jimp(SIZE * included.length, SIZE);
|
||||||
|
for (let i = 0; i < included.length; i += 1) {
|
||||||
|
sprite.composite(included[i].image, i * SIZE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await sprite.quality(80).write(`../src/routes/_components/Supporters/donors.jpg`);
|
||||||
|
// TODO: Optimizing the static/donors.jpg image should probably get automated as well
|
||||||
|
console.log(
|
||||||
|
'remember to additionally optimize the resulting /static/donors.jpg image file via e.g. https://squoosh.app '
|
||||||
|
);
|
||||||
|
|
||||||
|
const str = `[\n\t${included.map((a) => `${JSON.stringify(a.backer.name)}`).join(',\n\t')}\n]`;
|
||||||
|
|
||||||
|
fs.writeFileSync(outputFile, `export default ${str};`);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
@ -0,0 +1,9 @@
|
|||||||
|
import sh from 'shelljs';
|
||||||
|
|
||||||
|
sh.env['FORCE_UPDATE'] = process.argv.includes('--force=true');
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
|
sh.exec('node ./scripts/get_contributors.js'),
|
||||||
|
sh.exec('node ./scripts/get_donors.js'),
|
||||||
|
sh.exec('node ./scripts/update_template.js')
|
||||||
|
]);
|
@ -0,0 +1,36 @@
|
|||||||
|
import sh from 'shelljs';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path, { dirname } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const force = process.env.FORCE_UPDATE === 'true';
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
sh.cd(path.join(__dirname, '..'));
|
||||||
|
|
||||||
|
const outputFile = 'static/svelte-app.json';
|
||||||
|
if (!force && fs.existsSync(outputFile)) {
|
||||||
|
console.info(`[update/template] ${outputFile} exists. Skipping`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch svelte app
|
||||||
|
sh.rm('-rf', 'scripts/svelte-app');
|
||||||
|
sh.exec('npx degit sveltejs/template scripts/svelte-app');
|
||||||
|
|
||||||
|
// remove src (will be recreated client-side) and node_modules
|
||||||
|
sh.rm('-rf', 'scripts/svelte-app/src');
|
||||||
|
sh.rm('-rf', 'scripts/svelte-app/node_modules');
|
||||||
|
|
||||||
|
// build svelte-app.json
|
||||||
|
const appPath = 'scripts/svelte-app';
|
||||||
|
const files = [];
|
||||||
|
|
||||||
|
for (const path of sh.find(appPath).filter((p) => fs.lstatSync(p).isFile())) {
|
||||||
|
const bytes = fs.readFileSync(path);
|
||||||
|
const string = bytes.toString();
|
||||||
|
const data = bytes.compare(Buffer.from(string)) === 0 ? string : [...bytes];
|
||||||
|
files.push({ path: path.slice(appPath.length + 1), data });
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(outputFile, JSON.stringify(files));
|
@ -1,12 +0,0 @@
|
|||||||
// See https://kit.svelte.dev/docs/types#app
|
|
||||||
// for information about these interfaces
|
|
||||||
declare global {
|
|
||||||
namespace App {
|
|
||||||
// interface Error {}
|
|
||||||
// interface Locals {}
|
|
||||||
// interface PageData {}
|
|
||||||
// interface Platform {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {};
|
|
@ -1,12 +1,19 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="theme-default typo-default">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="theme-color" content="#ff3e00" />
|
||||||
|
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||||
|
|
||||||
|
<meta name="twitter:site" content="@sveltejs" />
|
||||||
|
<meta name="twitter:creator" content="@sveltejs" />
|
||||||
|
|
||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body data-sveltekit-preload-data="hover">
|
<body data-sveltekit-prefetch>
|
||||||
<div style="display: contents">%sveltekit.body%</div>
|
<div>%sveltekit.body%</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
// REPL props
|
||||||
|
|
||||||
|
export const svelteUrl = `https://unpkg.com/svelte@3`;
|
||||||
|
export const rollupUrl = `https://unpkg.com/rollup@1/dist/rollup.browser.js`;
|
||||||
|
export const mapbox_setup = `window.MAPBOX_ACCESS_TOKEN = '${
|
||||||
|
import.meta.env.VITE_MAPBOX_ACCESS_TOKEN
|
||||||
|
}';`;
|
@ -0,0 +1,59 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
export let once = false;
|
||||||
|
export let top = 0;
|
||||||
|
export let bottom = 0;
|
||||||
|
export let left = 0;
|
||||||
|
export let right = 0;
|
||||||
|
|
||||||
|
let intersecting = false;
|
||||||
|
let container;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (typeof IntersectionObserver !== 'undefined') {
|
||||||
|
const rootMargin = `${bottom}px ${left}px ${top}px ${right}px`;
|
||||||
|
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
intersecting = entries[0].isIntersecting;
|
||||||
|
if (intersecting && once) {
|
||||||
|
observer.unobserve(container);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ rootMargin }
|
||||||
|
);
|
||||||
|
|
||||||
|
observer.observe(container);
|
||||||
|
return () => observer.unobserve(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handler() {
|
||||||
|
const bcr = container.getBoundingClientRect();
|
||||||
|
|
||||||
|
intersecting =
|
||||||
|
bcr.bottom + bottom > 0 &&
|
||||||
|
bcr.right + right > 0 &&
|
||||||
|
bcr.top - top < window.innerHeight &&
|
||||||
|
bcr.left - left < window.innerWidth;
|
||||||
|
|
||||||
|
if (intersecting && once) {
|
||||||
|
window.removeEventListener('scroll', handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', handler);
|
||||||
|
return () => window.removeEventListener('scroll', handler);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={container}>
|
||||||
|
<slot {intersecting} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,11 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
let constructor;
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
constructor = await $$props.this();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:component this={constructor} {...$$props} />
|
@ -0,0 +1,67 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
let p = 0;
|
||||||
|
let visible = false;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
function next() {
|
||||||
|
visible = true;
|
||||||
|
p += 0.1;
|
||||||
|
|
||||||
|
const remaining = 1 - p;
|
||||||
|
if (remaining > 0.15) setTimeout(next, 500 / remaining);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(next, 250);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if visible}
|
||||||
|
<div class="progress-container">
|
||||||
|
<div class="progress" style="inline-size: {p * 100}%" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if p >= 0.4}
|
||||||
|
<div class="fade" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.progress-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 4px;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--prime);
|
||||||
|
transition: width 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(255, 255, 255, 0.3);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 998;
|
||||||
|
animation: fade 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,92 @@
|
|||||||
|
<script>
|
||||||
|
import Repl from '@sveltejs/repl';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { browser } from '$app/environment';
|
||||||
|
import { process_example } from '$lib/utils/examples';
|
||||||
|
import { PUBLIC_API_BASE } from '$env/static/public';
|
||||||
|
|
||||||
|
export let version = '3';
|
||||||
|
export let gist = null;
|
||||||
|
export let example = null;
|
||||||
|
export let embedded = false;
|
||||||
|
|
||||||
|
let repl;
|
||||||
|
let name = 'loading...';
|
||||||
|
|
||||||
|
let mounted = false;
|
||||||
|
|
||||||
|
function load(gist, example) {
|
||||||
|
if (version !== 'local') {
|
||||||
|
fetch(`https://unpkg.com/svelte@${version}/package.json`)
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((pkg) => {
|
||||||
|
version = pkg.version;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gist) {
|
||||||
|
fetch(`/repl/${gist}.json`)
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((data) => {
|
||||||
|
const { description, files } = data;
|
||||||
|
|
||||||
|
name = description;
|
||||||
|
|
||||||
|
const components = Object.keys(files)
|
||||||
|
.map((file) => {
|
||||||
|
const dot = file.lastIndexOf('.');
|
||||||
|
if (!~dot) return;
|
||||||
|
|
||||||
|
const source = files[file].content;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: file.slice(0, dot),
|
||||||
|
type: file.slice(dot + 1),
|
||||||
|
source
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter((x) => x.type === 'svelte' || x.type === 'js')
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (a.name === 'App' && a.type === 'svelte') return -1;
|
||||||
|
if (b.name === 'App' && b.type === 'svelte') return 1;
|
||||||
|
|
||||||
|
if (a.type !== b.type) return a.type === 'svelte' ? -1 : 1;
|
||||||
|
|
||||||
|
return a.name < b.name ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
repl.set({ components });
|
||||||
|
});
|
||||||
|
} else if (example) {
|
||||||
|
fetch(`${PUBLIC_API_BASE}/docs/svelte/examples/${example}`).then(async (response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
const components = process_example(data.files);
|
||||||
|
|
||||||
|
repl.set({
|
||||||
|
components
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
mounted = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
$: if (mounted) load(gist, example);
|
||||||
|
|
||||||
|
$: if (embedded) document.title = `${name} • Svelte REPL`;
|
||||||
|
|
||||||
|
$: svelteUrl =
|
||||||
|
browser && version === 'local'
|
||||||
|
? `${location.origin}/repl/local`
|
||||||
|
: `https://unpkg.com/svelte@${version}`;
|
||||||
|
|
||||||
|
const rollupUrl = `https://unpkg.com/rollup@1/dist/rollup.browser.js`;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if browser}
|
||||||
|
<Repl bind:this={repl} {svelteUrl} {rollupUrl} embedded relaxed />
|
||||||
|
{/if}
|
@ -0,0 +1,43 @@
|
|||||||
|
<script>
|
||||||
|
export let labels;
|
||||||
|
export let offset = 0;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="toggle">
|
||||||
|
{#each labels as label, index}
|
||||||
|
<button class:selected={offset === index} on:click={() => (offset = index)}>
|
||||||
|
{label}
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.toggle {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 4.6rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-top: 1px solid var(--second);
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0 0.15em;
|
||||||
|
width: 4em;
|
||||||
|
height: 1em;
|
||||||
|
padding: 0.3em 0.4em;
|
||||||
|
border-radius: var(--border-r);
|
||||||
|
line-height: 1em;
|
||||||
|
box-sizing: content-box;
|
||||||
|
color: #888;
|
||||||
|
border: 1px solid var(--back-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
background-color: var(--prime);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,6 @@
|
|||||||
|
import { dev } from '$app/environment';
|
||||||
|
import { SUPABASE_URL, SUPABASE_KEY } from '$env/static/private';
|
||||||
|
import { createClient } from '@supabase/supabase-js';
|
||||||
|
|
||||||
|
export const client =
|
||||||
|
(!dev || (SUPABASE_URL && SUPABASE_KEY)) && createClient(SUPABASE_URL, SUPABASE_KEY, { global: { fetch } });
|
@ -0,0 +1,97 @@
|
|||||||
|
import { client } from './client.js';
|
||||||
|
|
||||||
|
/** @typedef {import('./types').UserID} UserID */
|
||||||
|
/** @typedef {import('./types').Gist} Gist */
|
||||||
|
|
||||||
|
const PAGE_SIZE = 90;
|
||||||
|
|
||||||
|
export async function list(user, { offset, search }) {
|
||||||
|
const { data, error } = await client.rpc('gist_list', {
|
||||||
|
list_search: search || '',
|
||||||
|
list_userid: user.id,
|
||||||
|
list_count: PAGE_SIZE,
|
||||||
|
list_start: offset
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) throw new Error(error.message);
|
||||||
|
|
||||||
|
// normalize IDs
|
||||||
|
data.forEach((gist) => {
|
||||||
|
gist.id = gist.id.replace(/-/g, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
gists: data.slice(0, PAGE_SIZE),
|
||||||
|
next: data.length > PAGE_SIZE ? offset + PAGE_SIZE : null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {User} user
|
||||||
|
* @param {Pick<Gist, 'name'|'files'>} gist
|
||||||
|
* @returns {Promise<Gist>}
|
||||||
|
*/
|
||||||
|
export async function create(user, gist) {
|
||||||
|
const { data, error } = await client.rpc('gist_create', {
|
||||||
|
name: gist.name,
|
||||||
|
files: gist.files,
|
||||||
|
userid: user.id
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} id
|
||||||
|
* @returns {Promise<Gist>}
|
||||||
|
*/
|
||||||
|
export async function read(id) {
|
||||||
|
const { data, error } = await client
|
||||||
|
.from('gist')
|
||||||
|
.select('id,name,files,userid')
|
||||||
|
.eq('id', id)
|
||||||
|
.is('deleted_at', null);
|
||||||
|
|
||||||
|
if (error) throw new Error(error.message);
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {User} user
|
||||||
|
* @param {string} gistid
|
||||||
|
* @param {Pick<Gist, 'name'|'files'>} gist
|
||||||
|
* @returns {Promise<Gist>}
|
||||||
|
*/
|
||||||
|
export async function update(user, gistid, gist) {
|
||||||
|
const { data, error } = await client.rpc('gist_update', {
|
||||||
|
gist_id: gistid,
|
||||||
|
gist_name: gist.name,
|
||||||
|
gist_files: gist.files,
|
||||||
|
gist_userid: user.id
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} userid
|
||||||
|
* @param {string[]} ids
|
||||||
|
*/
|
||||||
|
export async function destroy(userid, ids) {
|
||||||
|
const { error } = await client.rpc('gist_destroy', {
|
||||||
|
gist_ids: ids,
|
||||||
|
gist_userid: userid
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
import * as cookie from 'cookie';
|
||||||
|
import flru from 'flru';
|
||||||
|
import { client } from './client.js';
|
||||||
|
|
||||||
|
const session_cache = flru(1000);
|
||||||
|
|
||||||
|
/** @typedef {import('./types').User} User */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {User} user
|
||||||
|
* @param {string} access_token
|
||||||
|
*/
|
||||||
|
export async function create(user, access_token) {
|
||||||
|
const { data, error } = await client.rpc('login', {
|
||||||
|
user_github_id: user.github_id,
|
||||||
|
user_github_name: user.github_name,
|
||||||
|
user_github_login: user.github_login,
|
||||||
|
user_github_avatar_url: user.github_avatar_url
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
session_cache.set(data.sessionid, {
|
||||||
|
id: data.userid,
|
||||||
|
github_name: user.github_name,
|
||||||
|
github_login: user.github_login,
|
||||||
|
github_avatar_url: user.github_avatar_url
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
sessionid: data.sessionid,
|
||||||
|
expires: new Date(data.expires)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} sessionid
|
||||||
|
* @returns {Promise<User>}
|
||||||
|
*/
|
||||||
|
export async function read(sessionid) {
|
||||||
|
if (!sessionid) return null;
|
||||||
|
|
||||||
|
if (!session_cache.get(sessionid)) {
|
||||||
|
session_cache.set(
|
||||||
|
sessionid,
|
||||||
|
client
|
||||||
|
.rpc('get_user', { sessionid })
|
||||||
|
.then(({ data, error }) => {
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.id && data;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
session_cache.set(sessionid, null);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await session_cache.get(sessionid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {string} sessionid */
|
||||||
|
export async function destroy(sessionid) {
|
||||||
|
const { error } = await client.rpc('logout', { sessionid });
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
session_cache.set(sessionid, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {string | null} str */
|
||||||
|
export function from_cookie(str) {
|
||||||
|
if (!str) return null;
|
||||||
|
return read(cookie.parse(str).sid);
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
export type UserID = number;
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
id: UserID;
|
||||||
|
name: string;
|
||||||
|
username: string;
|
||||||
|
avatar: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Gist {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
owner: UserID;
|
||||||
|
files: Array<{ name: string; type: string; source: string }>;
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import { transform } from './marked';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {import('./types').BlogPostSummary[]}
|
||||||
|
*/
|
||||||
|
export function get_index() {
|
||||||
|
return fs
|
||||||
|
.readdirSync('content/blog')
|
||||||
|
.reverse()
|
||||||
|
.map((file) => {
|
||||||
|
if (!file.endsWith('.md')) return;
|
||||||
|
|
||||||
|
const { date, slug } = get_date_and_slug(file);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(`content/blog/${file}`, 'utf-8');
|
||||||
|
const { metadata } = extract_frontmatter(content);
|
||||||
|
|
||||||
|
return {
|
||||||
|
slug,
|
||||||
|
date,
|
||||||
|
title: metadata.title,
|
||||||
|
description: metadata.description,
|
||||||
|
draft: !!metadata.draft
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} slug
|
||||||
|
* @returns {import('./types').BlogPost}
|
||||||
|
*/
|
||||||
|
export function get_post(slug) {
|
||||||
|
for (const file of fs.readdirSync('content/blog')) {
|
||||||
|
if (!file.endsWith('.md')) continue;
|
||||||
|
if (file.slice(11, -3) !== slug) continue;
|
||||||
|
|
||||||
|
const { date, date_formatted } = get_date_and_slug(file);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(`content/blog/${file}`, 'utf-8');
|
||||||
|
const { metadata, body } = extract_frontmatter(content);
|
||||||
|
|
||||||
|
return {
|
||||||
|
date,
|
||||||
|
date_formatted,
|
||||||
|
title: metadata.title,
|
||||||
|
description: metadata.description,
|
||||||
|
author: {
|
||||||
|
name: metadata.author,
|
||||||
|
url: metadata.authorURL
|
||||||
|
},
|
||||||
|
draft: !!metadata.draft,
|
||||||
|
content: transform(body)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {string} filename */
|
||||||
|
function get_date_and_slug(filename) {
|
||||||
|
const match = /^(\d{4}-\d{2}-\d{2})-(.+)\.md$/.exec(filename);
|
||||||
|
if (!match) throw new Error(`Invalid filename for blog: '${filename}'`);
|
||||||
|
|
||||||
|
const [, date, slug] = match;
|
||||||
|
const [y, m, d] = date.split('-');
|
||||||
|
const date_formatted = `${months[+m - 1]} ${+d} ${y}`;
|
||||||
|
|
||||||
|
return { date, date_formatted, slug };
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {string} markdown */
|
||||||
|
function extract_frontmatter(markdown) {
|
||||||
|
const match = /---\r?\n([\s\S]+?)\r?\n---/.exec(markdown);
|
||||||
|
const frontmatter = match[1];
|
||||||
|
const body = markdown.slice(match[0].length);
|
||||||
|
|
||||||
|
/** @type {Record<string, string>} */
|
||||||
|
const metadata = {};
|
||||||
|
frontmatter.split('\n').forEach((pair) => {
|
||||||
|
const i = pair.indexOf(':');
|
||||||
|
metadata[pair.slice(0, i).trim()] = strip_quotes(pair.slice(i + 1).trim());
|
||||||
|
});
|
||||||
|
|
||||||
|
return { metadata, body };
|
||||||
|
}
|
||||||
|
|
||||||
|
function strip_quotes(str) {
|
||||||
|
if (str[0] === '"' && str[str.length - 1] === '"') return str.slice(1, -1);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
const months = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');
|
||||||
|
|
||||||
|
function format_date(date) {}
|
@ -0,0 +1,187 @@
|
|||||||
|
import PrismJS from 'prismjs';
|
||||||
|
import 'prismjs/components/prism-bash.js';
|
||||||
|
import 'prismjs/components/prism-diff.js';
|
||||||
|
import 'prismjs/components/prism-typescript.js';
|
||||||
|
import 'prism-svelte';
|
||||||
|
import { marked } from 'marked';
|
||||||
|
|
||||||
|
const escape_test = /[&<>"']/;
|
||||||
|
const escape_replace = /[&<>"']/g;
|
||||||
|
const escape_test_no_encode = /[<>"']|&(?!#?\w+;)/;
|
||||||
|
const escape_replace_no_encode = /[<>"']|&(?!#?\w+;)/g;
|
||||||
|
const escape_replacements = {
|
||||||
|
'&': '&',
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'"': '"',
|
||||||
|
"'": '''
|
||||||
|
};
|
||||||
|
const get_escape_replacement = (ch) => escape_replacements[ch];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} html
|
||||||
|
* @param {boolean} encode
|
||||||
|
*/
|
||||||
|
export function escape(html, encode) {
|
||||||
|
if (encode) {
|
||||||
|
if (escape_test.test(html)) {
|
||||||
|
return html.replace(escape_replace, get_escape_replacement);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (escape_test_no_encode.test(html)) {
|
||||||
|
return html.replace(escape_replace_no_encode, get_escape_replacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
const prism_languages = {
|
||||||
|
bash: 'bash',
|
||||||
|
env: 'bash',
|
||||||
|
html: 'markup',
|
||||||
|
svelte: 'svelte',
|
||||||
|
js: 'javascript',
|
||||||
|
css: 'css',
|
||||||
|
diff: 'diff',
|
||||||
|
ts: 'typescript',
|
||||||
|
'': ''
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {Partial<import('marked').Renderer>} */
|
||||||
|
const default_renderer = {
|
||||||
|
code(code, infostring, escaped) {
|
||||||
|
const lang = (infostring || '').match(/\S*/)[0];
|
||||||
|
|
||||||
|
const prism_language = prism_languages[lang];
|
||||||
|
|
||||||
|
if (prism_language) {
|
||||||
|
const highlighted = PrismJS.highlight(code, PrismJS.languages[prism_language], lang);
|
||||||
|
return `<div class="code-block"><pre class="language-${prism_language}"><code>${highlighted}</code></pre></div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
'<div class="code-block"><pre><code>' +
|
||||||
|
(escaped ? code : escape(code, true)) +
|
||||||
|
'</code></pre></div>'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
blockquote(quote) {
|
||||||
|
return '<blockquote>\n' + quote + '</blockquote>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
html(html) {
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
|
||||||
|
heading(text, level) {
|
||||||
|
return '<h' + level + '>' + text + '</h' + level + '>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
hr() {
|
||||||
|
return '<hr>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
list(body, ordered, start) {
|
||||||
|
const type = ordered ? 'ol' : 'ul',
|
||||||
|
startatt = ordered && start !== 1 ? ' start="' + start + '"' : '';
|
||||||
|
return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
listitem(text) {
|
||||||
|
return '<li>' + text + '</li>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
checkbox(checked) {
|
||||||
|
return '<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox"' + '' + '> ';
|
||||||
|
},
|
||||||
|
|
||||||
|
paragraph(text) {
|
||||||
|
return '<p>' + text + '</p>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
table(header, body) {
|
||||||
|
if (body) body = '<tbody>' + body + '</tbody>';
|
||||||
|
|
||||||
|
return '<table>\n' + '<thead>\n' + header + '</thead>\n' + body + '</table>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
tablerow(content) {
|
||||||
|
return '<tr>\n' + content + '</tr>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
tablecell(content, flags) {
|
||||||
|
const type = flags.header ? 'th' : 'td';
|
||||||
|
const tag = flags.align ? '<' + type + ' align="' + flags.align + '">' : '<' + type + '>';
|
||||||
|
return tag + content + '</' + type + '>\n';
|
||||||
|
},
|
||||||
|
|
||||||
|
// span level renderer
|
||||||
|
strong(text) {
|
||||||
|
return '<strong>' + text + '</strong>';
|
||||||
|
},
|
||||||
|
|
||||||
|
em(text) {
|
||||||
|
return '<em>' + text + '</em>';
|
||||||
|
},
|
||||||
|
|
||||||
|
codespan(text) {
|
||||||
|
return '<code>' + text + '</code>';
|
||||||
|
},
|
||||||
|
|
||||||
|
br() {
|
||||||
|
return '<br>';
|
||||||
|
},
|
||||||
|
|
||||||
|
del(text) {
|
||||||
|
return '<del>' + text + '</del>';
|
||||||
|
},
|
||||||
|
|
||||||
|
link(href, title, text) {
|
||||||
|
if (href === null) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
let out = '<a href="' + escape(href) + '"';
|
||||||
|
if (title) {
|
||||||
|
out += ' title="' + title + '"';
|
||||||
|
}
|
||||||
|
out += '>' + text + '</a>';
|
||||||
|
return out;
|
||||||
|
},
|
||||||
|
|
||||||
|
image(href, title, text) {
|
||||||
|
if (href === null) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
let out = '<img src="' + href + '" alt="' + text + '"';
|
||||||
|
if (title) {
|
||||||
|
out += ' title="' + title + '"';
|
||||||
|
}
|
||||||
|
out += '>';
|
||||||
|
return out;
|
||||||
|
},
|
||||||
|
|
||||||
|
text(text) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} markdown
|
||||||
|
* @param {Partial<import('marked').Renderer>} renderer
|
||||||
|
*/
|
||||||
|
export function transform(markdown, renderer = {}) {
|
||||||
|
marked.use({
|
||||||
|
renderer: {
|
||||||
|
// we have to jump through these hoops because of marked's API design choices —
|
||||||
|
// options are global, and merged in confusing ways. You can't do e.g.
|
||||||
|
// `new Marked(options).parse(markdown)`
|
||||||
|
...default_renderer,
|
||||||
|
...renderer
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return marked(markdown);
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
export interface BlogPost {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
date: string;
|
||||||
|
date_formatted: string;
|
||||||
|
author: {
|
||||||
|
name: string;
|
||||||
|
url?: string;
|
||||||
|
};
|
||||||
|
draft: boolean;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BlogPostSummary {
|
||||||
|
slug: string;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
date: string;
|
||||||
|
draft: boolean;
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
// adapted from https://github.com/digplan/time-ago
|
||||||
|
// https://github.com/digplan/time-ago/blob/master/license.txt
|
||||||
|
const o = {
|
||||||
|
second: 1000,
|
||||||
|
minute: 60 * 1000,
|
||||||
|
hour: 60 * 1000 * 60,
|
||||||
|
day: 24 * 60 * 1000 * 60,
|
||||||
|
week: 7 * 24 * 60 * 1000 * 60,
|
||||||
|
month: 30 * 24 * 60 * 1000 * 60,
|
||||||
|
year: 365 * 24 * 60 * 1000 * 60
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ago = (nd, s) => {
|
||||||
|
var r = Math.round,
|
||||||
|
dir = ' ago',
|
||||||
|
pl = function (v, n) {
|
||||||
|
return s === undefined ? n + ' ' + v + (n > 1 ? 's' : '') + dir : n + v.substring(0, 1);
|
||||||
|
},
|
||||||
|
ts = Date.now() - new Date(nd).getTime(),
|
||||||
|
ii;
|
||||||
|
if (ts < 0) {
|
||||||
|
ts *= -1;
|
||||||
|
dir = ' from now';
|
||||||
|
}
|
||||||
|
for (var i in o) {
|
||||||
|
if (r(ts) < o[i]) return pl(ii || 'm', r(ts / (o[ii] || 1)));
|
||||||
|
ii = i;
|
||||||
|
}
|
||||||
|
return pl(i, r(ts / o[i]));
|
||||||
|
};
|
@ -0,0 +1 @@
|
|||||||
|
export const isMac = typeof navigator !== 'undefined' && navigator.platform === 'MacIntel';
|
@ -0,0 +1,19 @@
|
|||||||
|
export function keyEvent(code) {
|
||||||
|
return function (node, callback) {
|
||||||
|
node.addEventListener('keydown', handleKeydown);
|
||||||
|
|
||||||
|
function handleKeydown(event) {
|
||||||
|
if (event.keyCode === code) {
|
||||||
|
callback.call(this, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
destroy() {
|
||||||
|
node.removeEventListener('keydown', handleKeydown);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enter = keyEvent(13);
|
@ -0,0 +1,16 @@
|
|||||||
|
export function process_example(files) {
|
||||||
|
return files
|
||||||
|
.map((file) => {
|
||||||
|
const [name, type] = file.name.split('.');
|
||||||
|
return { name, type, source: file.source ?? file.content ?? '' };
|
||||||
|
})
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (a.name === 'App' && a.type === 'svelte') return -1;
|
||||||
|
if (b.name === 'App' && b.type === 'svelte') return 1;
|
||||||
|
|
||||||
|
if (a.type === b.type) return a.name < b.name ? -1 : 1;
|
||||||
|
|
||||||
|
if (a.type === 'svelte') return -1;
|
||||||
|
if (b.type === 'svelte') return 1;
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
import * as session from '$lib/db/session';
|
||||||
|
|
||||||
|
export async function load({ request }) {
|
||||||
|
return {
|
||||||
|
user: await session.from_cookie(request.headers.get('cookie'))
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<script>
|
||||||
|
import { setContext } from 'svelte';
|
||||||
|
import { invalidate } from '$app/navigation';
|
||||||
|
|
||||||
|
setContext('app', {
|
||||||
|
login: () => {
|
||||||
|
const login_window = window.open(
|
||||||
|
`${window.location.origin}/auth/login`,
|
||||||
|
'login',
|
||||||
|
'width=600,height=400'
|
||||||
|
);
|
||||||
|
|
||||||
|
window.addEventListener('message', function handler(event) {
|
||||||
|
login_window.close();
|
||||||
|
window.removeEventListener('message', handler);
|
||||||
|
invalidate();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
logout: async () => {
|
||||||
|
const r = await fetch(`/auth/logout`);
|
||||||
|
if (r.ok) invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<slot />
|
@ -0,0 +1,20 @@
|
|||||||
|
import * as gist from '$lib/db/gist';
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageServerLoad} */
|
||||||
|
export async function load({ url, parent }) {
|
||||||
|
let gists = [];
|
||||||
|
let next = null;
|
||||||
|
|
||||||
|
const search = url.searchParams.get('search');
|
||||||
|
|
||||||
|
const { user } = await parent();
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
const offset = url.searchParams.get('offset') ? parseInt(url.searchParams.get('offset')) : 0;
|
||||||
|
const search = url.searchParams.get('search');
|
||||||
|
|
||||||
|
({ gists, next } = await gist.list(user, { offset, search }));
|
||||||
|
}
|
||||||
|
|
||||||
|
return { user, gists, next, search };
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import * as session from '$lib/db/session';
|
||||||
|
import * as gist from '$lib/db/gist';
|
||||||
|
|
||||||
|
export async function POST({ request }) {
|
||||||
|
const user = await session.from_cookie(request.headers.get('cookie'));
|
||||||
|
if (!user) return new Response(undefined, { status: 401 });
|
||||||
|
|
||||||
|
const body = await request.json();
|
||||||
|
await gist.destroy(user.id, body.ids);
|
||||||
|
|
||||||
|
return new Response(undefined, { status: 204 });
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export function load({ url }) {
|
||||||
|
const query = url.searchParams;
|
||||||
|
const gist = query.get('gist');
|
||||||
|
const example = query.get('example');
|
||||||
|
const version = query.get('version');
|
||||||
|
|
||||||
|
// redirect to v2 REPL if appropriate
|
||||||
|
if (/^[^>]?[12]/.test(version)) {
|
||||||
|
throw redirect(302, `https://v2.svelte.dev/repl?${query}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = gist || example || 'hello-world';
|
||||||
|
const q = version ? `?version=${version}` : ``;
|
||||||
|
|
||||||
|
throw redirect(301, `/repl/${id}${q}`);
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
import { error, json } from '@sveltejs/kit';
|
||||||
|
import { dev } from '$app/environment';
|
||||||
|
import * as session from '$lib/db/session';
|
||||||
|
import { client } from '$lib/db/client';
|
||||||
|
import * as gist from '$lib/db/gist';
|
||||||
|
import { PUBLIC_API_BASE } from '$env/static/public';
|
||||||
|
|
||||||
|
const UUID_REGEX = /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/;
|
||||||
|
|
||||||
|
/** @type {Set<string>} */
|
||||||
|
let examples;
|
||||||
|
|
||||||
|
function munge(files) {
|
||||||
|
return files
|
||||||
|
.map((file) => {
|
||||||
|
const dot = file.name.lastIndexOf('.');
|
||||||
|
let name = file.name.slice(0, dot);
|
||||||
|
let type = file.name.slice(dot + 1);
|
||||||
|
|
||||||
|
if (type === 'html') type = 'svelte';
|
||||||
|
return { name, type, source: file.source ?? file.content ?? '' };
|
||||||
|
})
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (a.name === 'App' && a.type === 'svelte') return -1;
|
||||||
|
if (b.name === 'App' && b.type === 'svelte') return 1;
|
||||||
|
|
||||||
|
if (a.type !== b.type) return a.type === 'svelte' ? -1 : 1;
|
||||||
|
|
||||||
|
return a.name < b.name ? -1 : 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET({ params }) {
|
||||||
|
if (!examples) {
|
||||||
|
const res = await fetch(`${PUBLIC_API_BASE}/docs/svelte/examples`);
|
||||||
|
examples = new Set(
|
||||||
|
(await res.json())
|
||||||
|
.map((category) => category.examples)
|
||||||
|
.flat()
|
||||||
|
.map((example) => example.slug)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (examples.has(params.id)) {
|
||||||
|
const res = await fetch(`${PUBLIC_API_BASE}/docs/svelte/examples/${params.id}`);
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
return new Response(await res.json(), {
|
||||||
|
status: res.status,
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const example = await res.json();
|
||||||
|
|
||||||
|
return json({
|
||||||
|
id: params.id,
|
||||||
|
name: example.name,
|
||||||
|
owner: null,
|
||||||
|
relaxed: example.relaxed, // TODO is this right?
|
||||||
|
components: munge(example.files),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev && !client) {
|
||||||
|
// in dev with no local Supabase configured, proxy to production
|
||||||
|
// this lets us at least load saved REPLs
|
||||||
|
return await fetch(`https://svelte.dev/repl/${params.id}.json`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UUID_REGEX.test(params.id)) {
|
||||||
|
throw error(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = await gist.read(params.id);
|
||||||
|
|
||||||
|
if (!app) {
|
||||||
|
throw error(404, 'not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return json({
|
||||||
|
id: params.id,
|
||||||
|
name: app.name,
|
||||||
|
owner: app.userid,
|
||||||
|
relaxed: false,
|
||||||
|
components: munge(app.files),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO reimplement as an action
|
||||||
|
export async function PUT({ params, request }) {
|
||||||
|
const user = await session.from_cookie(request.headers.get('cookie'));
|
||||||
|
if (!user) throw error(401, 'Unauthorized');
|
||||||
|
|
||||||
|
const body = await request.json();
|
||||||
|
await gist.update(user, params.id, body);
|
||||||
|
|
||||||
|
return new Response(undefined, { status: 204 });
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
import { error } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export async function load({ fetch, params, url }) {
|
||||||
|
const res = await fetch(`/repl/${params.id}.json`);
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
throw error(res.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gist = await res.json();
|
||||||
|
|
||||||
|
return {
|
||||||
|
gist,
|
||||||
|
version: url.searchParams.get('version') || '3'
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
<script>
|
||||||
|
import Repl from '@sveltejs/repl';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { browser } from '$app/environment';
|
||||||
|
import { afterNavigate, goto } from '$app/navigation';
|
||||||
|
import { mapbox_setup } from '../../../../config.js';
|
||||||
|
import AppControls from './AppControls.svelte';
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageData} */
|
||||||
|
export let data;
|
||||||
|
|
||||||
|
let version = data.version;
|
||||||
|
|
||||||
|
let repl;
|
||||||
|
let name = data.gist.name;
|
||||||
|
let zen_mode = false;
|
||||||
|
let modified_count = 0;
|
||||||
|
|
||||||
|
function update_query_string(version) {
|
||||||
|
const params = [];
|
||||||
|
|
||||||
|
if (version !== 'latest') params.push(`version=${version}`);
|
||||||
|
|
||||||
|
const url =
|
||||||
|
params.length > 0 ? `/repl/${data.gist.id}?${params.join('&')}` : `/repl/${data.gist.id}`;
|
||||||
|
|
||||||
|
history.replaceState({}, 'x', url);
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if (typeof history !== 'undefined') update_query_string(version);
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (data.version !== 'local') {
|
||||||
|
fetch(`https://unpkg.com/svelte@${data.version || '3'}/package.json`)
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((pkg) => {
|
||||||
|
version = pkg.version;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
afterNavigate(() => {
|
||||||
|
repl.set({
|
||||||
|
components: data.gist.components
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function handle_fork(event) {
|
||||||
|
console.log('> handle_fork', event);
|
||||||
|
goto(`/repl/${event.detail.gist.id}?version=${version}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_change(event) {
|
||||||
|
modified_count = event.detail.components.filter((c) => c.modified).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
$: svelteUrl =
|
||||||
|
browser && version === 'local'
|
||||||
|
? `${location.origin}/repl/local`
|
||||||
|
: `https://unpkg.com/svelte@${version}`;
|
||||||
|
|
||||||
|
$: relaxed = data.gist.relaxed || (data.user && data.user.id === data.gist.owner);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{name} • REPL • Svelte</title>
|
||||||
|
|
||||||
|
<meta name="twitter:title" content="{data.gist.name} • REPL • Svelte" />
|
||||||
|
<meta name="twitter:description" content="Cybernetically enhanced web apps" />
|
||||||
|
<meta name="Description" content="Interactive Svelte playground" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<div class="repl-outer {zen_mode ? 'zen-mode' : ''}">
|
||||||
|
<AppControls
|
||||||
|
user={data.user}
|
||||||
|
gist={data.gist}
|
||||||
|
{repl}
|
||||||
|
bind:name
|
||||||
|
bind:zen_mode
|
||||||
|
bind:modified_count
|
||||||
|
on:forked={handle_fork}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{#if browser}
|
||||||
|
<Repl
|
||||||
|
bind:this={repl}
|
||||||
|
{svelteUrl}
|
||||||
|
{relaxed}
|
||||||
|
injectedJS={mapbox_setup}
|
||||||
|
showModified
|
||||||
|
showAst
|
||||||
|
on:change={handle_change}
|
||||||
|
on:add={handle_change}
|
||||||
|
on:remove={handle_change}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.repl-outer {
|
||||||
|
position: relative;
|
||||||
|
height: calc(100vh - var(--nav-h));
|
||||||
|
--app-controls-h: 5.6rem;
|
||||||
|
--pane-controls-h: 4.2rem;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: var(--back);
|
||||||
|
padding: var(--app-controls-h) 0 0 0;
|
||||||
|
/* margin: 0 calc(var(--side-nav) * -1); */
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* temp fix for #2499 and #2550 while waiting for a fix for https://github.com/sveltejs/svelte-repl/issues/8 */
|
||||||
|
|
||||||
|
.repl-outer :global(.tab-content),
|
||||||
|
.repl-outer :global(.tab-content.visible) {
|
||||||
|
pointer-events: all;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.repl-outer :global(.tab-content) {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.repl-outer :global(.tab-content.visible) {
|
||||||
|
visibility: visible;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-mode {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
z-index: 111;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,328 @@
|
|||||||
|
<script>
|
||||||
|
import { createEventDispatcher, getContext } from 'svelte';
|
||||||
|
import UserMenu from './UserMenu.svelte';
|
||||||
|
import Icon from '@sveltejs/site-kit/components/Icon.svelte';
|
||||||
|
import * as doNotZip from 'do-not-zip';
|
||||||
|
import downloadBlob from './downloadBlob.js';
|
||||||
|
import { enter } from '$lib/utils/events.js';
|
||||||
|
import { isMac } from '$lib/utils/compat.js';
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
const { login } = getContext('app');
|
||||||
|
|
||||||
|
export let user;
|
||||||
|
export let repl;
|
||||||
|
export let gist;
|
||||||
|
export let name;
|
||||||
|
export let zen_mode;
|
||||||
|
export let modified_count;
|
||||||
|
|
||||||
|
let saving = false;
|
||||||
|
let downloading = false;
|
||||||
|
let justSaved = false;
|
||||||
|
let justForked = false;
|
||||||
|
|
||||||
|
function wait(ms) {
|
||||||
|
return new Promise((f) => setTimeout(f, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
$: canSave = user && gist && gist.owner === user.id;
|
||||||
|
|
||||||
|
function handleKeydown(event) {
|
||||||
|
if (event.key === 's' && (isMac ? event.metaKey : event.ctrlKey)) {
|
||||||
|
event.preventDefault();
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fork(intentWasSave) {
|
||||||
|
saving = true;
|
||||||
|
|
||||||
|
const { components } = repl.toJSON();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const r = await fetch(`/repl/create.json`, {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name,
|
||||||
|
files: components.map((component) => ({
|
||||||
|
name: `${component.name}.${component.type}`,
|
||||||
|
source: component.source,
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (r.status < 200 || r.status >= 300) {
|
||||||
|
const { error } = await r.json();
|
||||||
|
throw new Error(`Received an HTTP ${r.status} response: ${error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gist = await r.json();
|
||||||
|
dispatch('forked', { gist });
|
||||||
|
|
||||||
|
modified_count = 0;
|
||||||
|
repl.markSaved();
|
||||||
|
|
||||||
|
if (intentWasSave) {
|
||||||
|
justSaved = true;
|
||||||
|
await wait(600);
|
||||||
|
justSaved = false;
|
||||||
|
} else {
|
||||||
|
justForked = true;
|
||||||
|
await wait(600);
|
||||||
|
justForked = false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (navigator.onLine) {
|
||||||
|
alert(err.message);
|
||||||
|
} else {
|
||||||
|
alert(`It looks like you're offline! Find the internet and try again`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saving = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
if (!user) {
|
||||||
|
alert('Please log in before saving your app');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (saving) return;
|
||||||
|
|
||||||
|
if (!canSave) {
|
||||||
|
fork(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saving = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send all files back to API
|
||||||
|
// ~> Any missing files are considered deleted!
|
||||||
|
const { components } = repl.toJSON();
|
||||||
|
|
||||||
|
const r = await fetch(`/repl/${gist.id}.json`, {
|
||||||
|
method: 'PUT',
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name,
|
||||||
|
files: components.map((component) => ({
|
||||||
|
name: `${component.name}.${component.type}`,
|
||||||
|
source: component.source,
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (r.status < 200 || r.status >= 300) {
|
||||||
|
const { error } = await r.json();
|
||||||
|
throw new Error(`Received an HTTP ${r.status} response: ${error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
modified_count = 0;
|
||||||
|
repl.markSaved();
|
||||||
|
justSaved = true;
|
||||||
|
await wait(600);
|
||||||
|
justSaved = false;
|
||||||
|
} catch (err) {
|
||||||
|
if (navigator.onLine) {
|
||||||
|
alert(err.message);
|
||||||
|
} else {
|
||||||
|
alert(`It looks like you're offline! Find the internet and try again`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saving = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function download() {
|
||||||
|
downloading = true;
|
||||||
|
|
||||||
|
const { components, imports } = repl.toJSON();
|
||||||
|
|
||||||
|
const files = await (await fetch('/svelte-app.json')).json();
|
||||||
|
|
||||||
|
if (imports.length > 0) {
|
||||||
|
const idx = files.findIndex(({ path }) => path === 'package.json');
|
||||||
|
const pkg = JSON.parse(files[idx].data);
|
||||||
|
const { devDependencies } = pkg;
|
||||||
|
imports.forEach((mod) => {
|
||||||
|
const match = /^(@[^/]+\/)?[^@/]+/.exec(mod);
|
||||||
|
devDependencies[match[0]] = 'latest';
|
||||||
|
});
|
||||||
|
pkg.devDependencies = devDependencies;
|
||||||
|
files[idx].data = JSON.stringify(pkg, null, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
files.push(
|
||||||
|
...components.map((component) => ({
|
||||||
|
path: `src/${component.name}.${component.type}`,
|
||||||
|
data: component.source,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
files.push({
|
||||||
|
path: `src/main.js`,
|
||||||
|
data: `import App from './App.svelte';
|
||||||
|
|
||||||
|
var app = new App({
|
||||||
|
target: document.body
|
||||||
|
});
|
||||||
|
|
||||||
|
export default app;`,
|
||||||
|
});
|
||||||
|
|
||||||
|
downloadBlob(doNotZip.toBlob(files), 'svelte-app.zip');
|
||||||
|
|
||||||
|
downloading = false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:window on:keydown={handleKeydown} />
|
||||||
|
|
||||||
|
<div class="app-controls">
|
||||||
|
<input bind:value={name} on:focus={(e) => e.target.select()} use:enter={(e) => e.target.blur()} />
|
||||||
|
|
||||||
|
<div style="text-align: right; margin-right:.4rem">
|
||||||
|
<button class="icon" on:click={() => (zen_mode = !zen_mode)} title="fullscreen editor">
|
||||||
|
{#if zen_mode}
|
||||||
|
<Icon name="close" />
|
||||||
|
{:else}
|
||||||
|
<Icon name="maximize" />
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="icon" disabled={downloading} on:click={download} title="download zip file">
|
||||||
|
<Icon name="download" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="icon" disabled={saving || !user} on:click={() => fork(false)} title="fork">
|
||||||
|
{#if justForked}
|
||||||
|
<Icon name="check" />
|
||||||
|
{:else}
|
||||||
|
<Icon name="git-branch" />
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="icon" disabled={saving || !user} on:click={save} title="save">
|
||||||
|
{#if justSaved}
|
||||||
|
<Icon name="check" />
|
||||||
|
{:else}
|
||||||
|
<Icon name="save" />
|
||||||
|
{#if modified_count}
|
||||||
|
<div class="badge">{modified_count}</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{#if user}
|
||||||
|
<UserMenu {user} />
|
||||||
|
{:else}
|
||||||
|
<button class="icon" on:click|preventDefault={login}>
|
||||||
|
<Icon name="log-in" />
|
||||||
|
<span> Log in to save</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.app-controls {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: var(--app-controls-h);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0.6rem var(--side-nav);
|
||||||
|
background-color: var(--second);
|
||||||
|
color: white;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
position: relative;
|
||||||
|
top: -0.1rem;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.2em;
|
||||||
|
opacity: 0.7;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
font-family: var(--font);
|
||||||
|
font-size: 1.6rem;
|
||||||
|
color: white;
|
||||||
|
/* width: 1.6em;
|
||||||
|
height: 1.6em; */
|
||||||
|
line-height: 1;
|
||||||
|
margin: 0 0 0 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.icon:disabled {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon[title^='fullscreen'] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: currentColor;
|
||||||
|
font-family: var(--font);
|
||||||
|
font-size: 1.6rem;
|
||||||
|
opacity: 0.7;
|
||||||
|
outline: none;
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 0.2em 0 0.4rem;
|
||||||
|
padding-top: 0.2em;
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:hover {
|
||||||
|
border-bottom: 1px solid currentColor;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
input:focus {
|
||||||
|
border-bottom: 1px solid currentColor;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background: #ff3e00;
|
||||||
|
border-radius: 100%;
|
||||||
|
font-size: 10px;
|
||||||
|
padding: 0;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
line-height: 15px;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
.icon[title^='fullscreen'] {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
button span {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,117 @@
|
|||||||
|
<script>
|
||||||
|
import { getContext } from 'svelte';
|
||||||
|
|
||||||
|
const { logout } = getContext('app');
|
||||||
|
|
||||||
|
export let user;
|
||||||
|
|
||||||
|
let showMenu = false;
|
||||||
|
let name;
|
||||||
|
|
||||||
|
$: name = user.github_name || user.github_login;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="user" on:mouseenter={() => (showMenu = true)} on:mouseleave={() => (showMenu = false)}>
|
||||||
|
<span>{name}</span>
|
||||||
|
<img alt="{name} avatar" src={user.github_avatar_url} />
|
||||||
|
|
||||||
|
{#if showMenu}
|
||||||
|
<div class="menu">
|
||||||
|
<a href="/apps">Your saved apps</a>
|
||||||
|
<button on:click={logout}>Log out</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.user {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0em 1.2rem 0 1.6rem;
|
||||||
|
height: 0.8em;
|
||||||
|
line-height: 1;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user::after {
|
||||||
|
/* embiggen hit zone, so log out menu doesn't disappear */
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
width: 100%;
|
||||||
|
height: 3.2rem;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
/* position: relative; padding: 0 2em 0 0; */
|
||||||
|
line-height: 1;
|
||||||
|
display: none;
|
||||||
|
font-family: var(--font);
|
||||||
|
font-size: 1.6rem;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user:hover span {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
position: absolute;
|
||||||
|
top: -0.05em;
|
||||||
|
right: 0;
|
||||||
|
width: 2.1rem;
|
||||||
|
height: 2.1rem;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
position: absolute;
|
||||||
|
width: calc(100% + 1.6rem);
|
||||||
|
min-width: 10em;
|
||||||
|
top: 3rem;
|
||||||
|
right: -1.6rem;
|
||||||
|
background-color: var(--second);
|
||||||
|
padding: 0.8rem 1.6rem;
|
||||||
|
z-index: 99;
|
||||||
|
text-align: left;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu button,
|
||||||
|
.menu a {
|
||||||
|
background-color: transparent;
|
||||||
|
font-family: var(--font);
|
||||||
|
font-size: 1.6rem;
|
||||||
|
opacity: 0.7;
|
||||||
|
padding: 0.4rem 0;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: left;
|
||||||
|
border: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu button:hover,
|
||||||
|
.menu a:hover {
|
||||||
|
opacity: 1;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
.user {
|
||||||
|
padding: 0em 3.2rem 0 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 2.4rem;
|
||||||
|
height: 2.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,11 @@
|
|||||||
|
export default (blob, filename) => {
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = filename;
|
||||||
|
link.style.display = 'none';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
link.remove();
|
||||||
|
};
|
@ -0,0 +1,19 @@
|
|||||||
|
import { json } from '@sveltejs/kit';
|
||||||
|
import * as session from '$lib/db/session';
|
||||||
|
import * as gist from '$lib/db/gist';
|
||||||
|
import { error } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export async function POST({ request }) {
|
||||||
|
const user = await session.from_cookie(request.headers.get('cookie'));
|
||||||
|
if (!user) throw error(401);
|
||||||
|
|
||||||
|
const body = await request.json();
|
||||||
|
const result = await gist.create(user, body);
|
||||||
|
|
||||||
|
// normalize id
|
||||||
|
result.id = result.id.replace(/-/g, '');
|
||||||
|
|
||||||
|
return json(result, {
|
||||||
|
status: 201
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
export function load({ url }) {
|
||||||
|
const query = url.searchParams;
|
||||||
|
return {
|
||||||
|
version: query.get('version') || '3',
|
||||||
|
gist: query.get('gist'),
|
||||||
|
example: query.get('example')
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
<script>
|
||||||
|
import { browser } from '$app/environment';
|
||||||
|
import ReplWidget from '$lib/components/ReplWidget.svelte';
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageData} */
|
||||||
|
export let data;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>REPL • Svelte</title>
|
||||||
|
|
||||||
|
<meta name="twitter:title" content="Svelte REPL" />
|
||||||
|
<meta name="twitter:description" content="Cybernetically enhanced web apps" />
|
||||||
|
<meta name="Description" content="Interactive Svelte playground" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<div class="repl-outer">
|
||||||
|
{#if browser}
|
||||||
|
<ReplWidget version={data.version} gist={data.gist} example={data.example} embedded={true} />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.repl-outer {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--back);
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
--pane-controls-h: 4.2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,14 @@
|
|||||||
|
import { readFileSync } from 'fs';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { LOCAL_SVELTE_PATH } from '$env/static/private';
|
||||||
|
|
||||||
|
const local_svelte_path = LOCAL_SVELTE_PATH || '../../../svelte';
|
||||||
|
|
||||||
|
export function GET({ params: { path } }) {
|
||||||
|
if (import.meta.env.PROD || ('/' + path).includes('/.')) {
|
||||||
|
return new Response(undefined, { status: 403 });
|
||||||
|
}
|
||||||
|
return new Response(readFileSync(join(local_svelte_path, path)), {
|
||||||
|
headers: { 'Content-Type': 'text/javascript' }
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
<script>
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
|
||||||
|
// we don't want to use <svelte:window bind:online> here,
|
||||||
|
// because we only care about the online state when
|
||||||
|
// the page first loads
|
||||||
|
const online = typeof navigator !== 'undefined' ? navigator.onLine : true;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{$page.status}</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{#if online}
|
||||||
|
{#if $page.status === 404}
|
||||||
|
<h1>Not found!</h1>
|
||||||
|
<p>
|
||||||
|
If you were expecting to find something here, please drop by the
|
||||||
|
<a href="/chat"> Discord chatroom </a>
|
||||||
|
and let us know, or raise an issue on
|
||||||
|
<a href="https://github.com/sveltejs/sites">GitHub</a>. Thanks!
|
||||||
|
</p>
|
||||||
|
{:else}
|
||||||
|
<h1>Yikes!</h1>
|
||||||
|
<p>Something went wrong when we tried to render this page.</p>
|
||||||
|
{#if $page.error.message}
|
||||||
|
<p class="error">{$page.status}: {$page.error.message}</p>
|
||||||
|
{:else}
|
||||||
|
<p class="error">Encountered a {$page.status} error.</p>
|
||||||
|
{/if}
|
||||||
|
<p>Please try reloading the page.</p>
|
||||||
|
<p>
|
||||||
|
If the error persists, please drop by the
|
||||||
|
<a href="/chat"> Discord chatroom </a>
|
||||||
|
and let us know, or raise an issue on
|
||||||
|
<a href="https://github.com/sveltejs/sites">GitHub</a>. Thanks!
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<h1>It looks like you're offline</h1>
|
||||||
|
<p>Reload the page once you've found the internet.</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
padding: var(--top-offset) var(--side-nav) 6rem var(--side-nav);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
p {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2.8em;
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0 0 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 1em auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
background-color: var(--second);
|
||||||
|
color: white;
|
||||||
|
padding: 12px 16px;
|
||||||
|
font: 600 16px/1.7 var(--font);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,161 @@
|
|||||||
|
<script>
|
||||||
|
import "@sveltejs/site-kit/styles/index.css";
|
||||||
|
import { page, navigating } from "$app/stores";
|
||||||
|
import { Icon, Icons, Nav, NavItem, SkipLink } from "@sveltejs/site-kit";
|
||||||
|
import PreloadingIndicator from "$lib/components/PreloadingIndicator.svelte";
|
||||||
|
import StopWar from "./stopwar.svg";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Icons />
|
||||||
|
|
||||||
|
{#if $navigating && $navigating.to}
|
||||||
|
<PreloadingIndicator />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if $page.url.pathname !== "/repl/embed"}
|
||||||
|
<SkipLink href="#main" />
|
||||||
|
<Nav {page} logo={StopWar}>
|
||||||
|
<svelte:fragment slot="nav-center">
|
||||||
|
<NavItem href="/tutorial">Tutorial</NavItem>
|
||||||
|
<NavItem href="/docs">Docs</NavItem>
|
||||||
|
<NavItem href="/examples">Examples</NavItem>
|
||||||
|
<NavItem href="/repl">REPL</NavItem>
|
||||||
|
<NavItem href="/blog">Blog</NavItem>
|
||||||
|
<NavItem href="/faq">FAQ</NavItem>
|
||||||
|
</svelte:fragment>
|
||||||
|
|
||||||
|
<svelte:fragment slot="nav-right">
|
||||||
|
<NavItem external="https://kit.svelte.dev">SvelteKit</NavItem>
|
||||||
|
|
||||||
|
<NavItem external="/chat" title="Discord Chat">
|
||||||
|
<span class="small">Discord</span>
|
||||||
|
<span class="large"><Icon name="message-square" /></span>
|
||||||
|
</NavItem>
|
||||||
|
|
||||||
|
<NavItem
|
||||||
|
external="https://github.com/sveltejs/svelte"
|
||||||
|
title="GitHub Repo"
|
||||||
|
>
|
||||||
|
<span class="small">GitHub</span>
|
||||||
|
<span class="large"><Icon name="github" /></span>
|
||||||
|
</NavItem>
|
||||||
|
</svelte:fragment>
|
||||||
|
</Nav>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
{#if $page.route.id !== "/blog/[slug]"}
|
||||||
|
<meta name="twitter:card" content="summary" />
|
||||||
|
<meta
|
||||||
|
name="twitter:image"
|
||||||
|
content="https://svelte.dev/images/twitter-thumbnail.jpg"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
name="og:image"
|
||||||
|
content="https://svelte.dev/images/twitter-thumbnail.jpg"
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<main id="main">
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<a target="_blank" rel="noopener noreferrer" href="https://www.stopputin.net/">
|
||||||
|
<div class="ukr">
|
||||||
|
<span class="small">
|
||||||
|
<strong>We stand with Ukraine.</strong> Donate →
|
||||||
|
</span>
|
||||||
|
<span class="large">
|
||||||
|
<strong>We stand with Ukraine.</strong> Petition your leaders. Show your support.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.ukr {
|
||||||
|
background-color: #0066cc;
|
||||||
|
color: white;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100vw;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.75em;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 830px) {
|
||||||
|
:global(aside) {
|
||||||
|
z-index: 9999 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
position: relative;
|
||||||
|
margin: 0 auto;
|
||||||
|
/* padding: var(--nav-h) var(--side-nav) 0 var(--side-nav); */
|
||||||
|
padding: var(--nav-h) 0 0 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
.small {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Ukraine banner */
|
||||||
|
:root {
|
||||||
|
--ukr-footer-height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding-bottom: var(--ukr-footer-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ukr {
|
||||||
|
background-color: #0066cc;
|
||||||
|
color: white;
|
||||||
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: var(--ukr-footer-height);
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.examples-container, .repl-outer, .tutorial-outer) {
|
||||||
|
height: calc(100vh - var(--nav-h) - var(--ukr-footer-height)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.toggle) {
|
||||||
|
bottom: var(--ukr-footer-height) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.zen-mode) {
|
||||||
|
height: calc(100vh - var(--ukr-footer-height)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 830px) {
|
||||||
|
:global(aside) {
|
||||||
|
z-index: 9999 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ukr strong {
|
||||||
|
color: #ffcc00;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1 @@
|
|||||||
|
export const prerender = true;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue