diff --git a/site/content/faq/100-im-new-to-svelte.md b/site/content/faq/100-im-new-to-svelte.md
new file mode 100644
index 0000000000..18e4b6742f
--- /dev/null
+++ b/site/content/faq/100-im-new-to-svelte.md
@@ -0,0 +1,7 @@
+---
+question: I'm new to Svelte. Where should I start?
+---
+
+We think the best way to get started is playing through the interactive [Tutorial](https://svelte.dev/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.
+
+Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial.
\ No newline at end of file
diff --git a/site/content/faq/1000-how-can-i-update-my-v2-components.md b/site/content/faq/1000-how-can-i-update-my-v2-components.md
new file mode 100644
index 0000000000..0800dff89b
--- /dev/null
+++ b/site/content/faq/1000-how-can-i-update-my-v2-components.md
@@ -0,0 +1,5 @@
+---
+question: How can I update my components written in Svelte v2?
+---
+
+svelte-upgrade isn't fully working for v2->v3 yet, [but it's close](https://github.com/sveltejs/svelte-upgrade/pull/12).
\ No newline at end of file
diff --git a/site/content/faq/1100-is-svelte-v2-still-availabile.md b/site/content/faq/1100-is-svelte-v2-still-availabile.md
new file mode 100644
index 0000000000..0fbc4c039c
--- /dev/null
+++ b/site/content/faq/1100-is-svelte-v2-still-availabile.md
@@ -0,0 +1,7 @@
+---
+question: Is Svelte v2 still available?
+---
+
+New features aren't being added to it, and bugs will probably only be fixed if they are extremely nasty or present some sort of security vulnerability.
+
+The documentation is still available [here](https://v2.svelte.dev/guide).
\ No newline at end of file
diff --git a/site/content/faq/1200-how-do-i-do-hmr.md b/site/content/faq/1200-how-do-i-do-hmr.md
new file mode 100644
index 0000000000..88d08b252f
--- /dev/null
+++ b/site/content/faq/1200-how-do-i-do-hmr.md
@@ -0,0 +1,5 @@
+---
+question: How do I do hot module reloading?
+---
+
+Use the community plugins for [rollup](https://github.com/rixo/rollup-plugin-svelte-hot) and [webpack](https://github.com/rixo/svelte-loader-hot).
diff --git a/site/content/faq/200-are-there-any-video-courses.md b/site/content/faq/200-are-there-any-video-courses.md
new file mode 100644
index 0000000000..0c2c1f680e
--- /dev/null
+++ b/site/content/faq/200-are-there-any-video-courses.md
@@ -0,0 +1,10 @@
+---
+question: Are there any video courses?
+---
+
+There are no official ones, but here are a couple of third-part ones that we know of.
+
+- [Egghead](https://egghead.io/playlists/getting-started-with-svelte-3-05a8541a)
+- [Udemy](https://www.udemy.com/sveltejs-the-complete-guide/)
+
+Note that Udemy very frequently has discounts over 90%.
diff --git a/site/content/faq/300-is-svelte-dev-down.md b/site/content/faq/300-is-svelte-dev-down.md
new file mode 100644
index 0000000000..a7ce9984b7
--- /dev/null
+++ b/site/content/faq/300-is-svelte-dev-down.md
@@ -0,0 +1,5 @@
+---
+question: Is svelte.dev down?
+---
+
+Probably not, but it's possible. If you can't seem to access any `.dev` sites, check out [this SuperUser question and answer](https://superuser.com/q/1413402).
\ No newline at end of file
diff --git a/site/content/faq/400-how-can-i-get-syntax-highlighting.md b/site/content/faq/400-how-can-i-get-syntax-highlighting.md
new file mode 100644
index 0000000000..90f10b254f
--- /dev/null
+++ b/site/content/faq/400-how-can-i-get-syntax-highlighting.md
@@ -0,0 +1,5 @@
+---
+question: How can I get VSCode to syntax-highlight my .svelte files?
+---
+
+There is an [official VSCode extension for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), however it is still in the **beta** testing stage, and not all issues have been ironed out.
\ No newline at end of file
diff --git a/site/content/faq/500-what-about-typescript-support.md b/site/content/faq/500-what-about-typescript-support.md
new file mode 100644
index 0000000000..dae27143ed
--- /dev/null
+++ b/site/content/faq/500-what-about-typescript-support.md
@@ -0,0 +1,5 @@
+---
+question: What about Typescript support?
+---
+
+You need to install a [community supported preprocessor](https://github.com/sveltejs/integrations#preprocessors) such as [svelte-preprocess](https://github.com/kaisermann/svelte-preprocess). Work is ongoing to improve [IDE support](https://github.com/sveltejs/language-tools/issues/83) and build [additional CLI tooling](https://github.com/sveltejs/language-tools/issues/68)
\ No newline at end of file
diff --git a/site/content/faq/600-does-svelte-scale.md b/site/content/faq/600-does-svelte-scale.md
new file mode 100644
index 0000000000..06c9b58a97
--- /dev/null
+++ b/site/content/faq/600-does-svelte-scale.md
@@ -0,0 +1,5 @@
+---
+question: Does Svelte scale?
+---
+
+There will be a blog post about this eventually, but in the meantime, check out [this issue](https://github.com/sveltejs/svelte/issues/2546).
diff --git a/site/content/faq/700-is-there-a-component-library.md b/site/content/faq/700-is-there-a-component-library.md
new file mode 100644
index 0000000000..fd771eabda
--- /dev/null
+++ b/site/content/faq/700-is-there-a-component-library.md
@@ -0,0 +1,5 @@
+---
+question: Is there a UI component library?
+---
+
+There are several UI component libraries. Find them under the [code section](https://svelte-community.netlify.com/code) of the Svelte Community website.
diff --git a/site/content/faq/800-how-do-i-test-svelte-apps.md b/site/content/faq/800-how-do-i-test-svelte-apps.md
new file mode 100644
index 0000000000..af67bebf3f
--- /dev/null
+++ b/site/content/faq/800-how-do-i-test-svelte-apps.md
@@ -0,0 +1,6 @@
+---
+question: How do I test Svelte apps?
+---
+
+We don't have a good answer to this yet, but it is a priority. There are a few approaches that people take when testing, but it generally involves compiling the component and mounting it to something and then performing the tests.
+You essentially need to create a bundle for each component you're testing (since svelte is a compiler and not a normal library) and then mount them. You can mount to a JSDOM instance, or you can use Puppeteer if you need a real browser, or you can use a tool like Cypress. There is an example of this in the Sapper starter template.
diff --git a/site/content/faq/900-is-there-a-router.md b/site/content/faq/900-is-there-a-router.md
new file mode 100644
index 0000000000..a78c478943
--- /dev/null
+++ b/site/content/faq/900-is-there-a-router.md
@@ -0,0 +1,13 @@
+---
+question: Is there a router?
+---
+
+You can use any router lib you want. A lot of people use [page.js](https://github.com/visionmedia/page.js). There's also [navaid](https://github.com/lukeed/navaid), which is very similar.
+
+If you prefer a declarative HTML approach, there's [svelte-routing](https://github.com/EmilTholin/svelte-routing).
+
+If you need hash-based routing on the client side, check out [svelte-spa-router](https://github.com/ItalyPaleAle/svelte-spa-router), or [abstract-state-router](https://github.com/TehShrike/abstract-state-router/), a mature router for business software.
+
+For filesystem-based routing, you can take a look at [Routify](https://routify.dev).
+
+For an official solution, there's nothing that's simply a routing library. There is, however, the official [Sapper](https://sapper.svelte.dev/) framework, a Next.js-style application framework built on Svelte, which includes its own filesystem-based routing.
\ No newline at end of file
diff --git a/site/src/routes/blog/[slug].svelte b/site/src/routes/blog/[slug].svelte
index 610fb6506b..d5fd6c0676 100644
--- a/site/src/routes/blog/[slug].svelte
+++ b/site/src/routes/blog/[slug].svelte
@@ -133,44 +133,14 @@
border: 0.8rem solid var(--second);
}
- /* headers anchors */
-
- .post :global(.offset-anchor) {
- position: relative;
- display: block;
- top: calc(-1 * (var(--nav-h) + var(--top-offset) - 1rem));
- width: 0;
- height: 0;
- }
-
.post :global(.anchor) {
- position: absolute;
- display: block;
- background: url(/icons/link.svg) 0 50% no-repeat;
- background-size: 1em 1em;
- width: 1.4em;
- height: 1em;
top: calc((var(--h3) - 24px) / 2);
- left: -1.4em;
- opacity: 0;
- transition: opacity 0.2s;
- border: none !important; /* TODO get rid of linkify */
}
- .post :global(h2):hover :global(.anchor),
- .post :global(h3):hover :global(.anchor),
- .post :global(h4):hover :global(.anchor),
- .post :global(h5):hover :global(.anchor),
- .post :global(h6):hover :global(.anchor) {
- opacity: 1;
- }
-
-
@media (max-width: 768px) {
.post :global(.anchor) {
transform: scale(0.6);
opacity: 1;
- top: calc((1em - 0.6 * 24px) / 2);
left: -1.0em;
}
}
diff --git a/site/src/routes/faq.js b/site/src/routes/faq.js
deleted file mode 100644
index 6263494a4c..0000000000
--- a/site/src/routes/faq.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export function get(req, res) {
- res.writeHead(302, { Location: 'https://github.com/sveltejs/svelte/wiki/FAQ' });
- res.end();
-}
\ No newline at end of file
diff --git a/site/src/routes/faq/_faqs.js b/site/src/routes/faq/_faqs.js
new file mode 100644
index 0000000000..fa48e02282
--- /dev/null
+++ b/site/src/routes/faq/_faqs.js
@@ -0,0 +1,58 @@
+import fs from 'fs';
+import path from 'path';
+import { extract_frontmatter, link_renderer } from '@sveltejs/site-kit/utils/markdown.js';
+import marked from 'marked';
+import { makeSlugProcessor } from '../../utils/slug';
+import { highlight } from '../../utils/highlight';
+import { SLUG_PRESERVE_UNICODE } from '../../../config';
+
+const makeSlug = makeSlugProcessor(SLUG_PRESERVE_UNICODE);
+
+export default function get_faqs() {
+ return fs
+ .readdirSync('content/faq')
+ .map(file => {
+ if (path.extname(file) !== '.md') return;
+
+ const match = /^([0-9]+)-(.+)\.md$/.exec(file);
+ if (!match) throw new Error(`Invalid filename '${file}'`);
+
+ const [, order, slug] = match;
+
+ const markdown = fs.readFileSync(`content/faq/${file}`, 'utf-8');
+
+ const { content, metadata } = extract_frontmatter(markdown);
+
+ const renderer = new marked.Renderer();
+
+ renderer.link = link_renderer;
+
+ renderer.code = highlight;
+
+ renderer.heading = (text, level, rawtext) => {
+ const fragment = makeSlug(rawtext);
+
+ return `
+
+
+
+ ${text}
+ `;
+ };
+
+ const answer = marked(
+ content.replace(/^\t+/gm, match => match.split('\t').join(' ')),
+ { renderer }
+ );
+
+ const fragment = makeSlug(slug);
+
+ return {
+ fragment,
+ order,
+ answer,
+ metadata
+ };
+ })
+ .sort((a, b) => a.order - b.order);
+}
diff --git a/site/src/routes/faq/index.json.js b/site/src/routes/faq/index.json.js
new file mode 100644
index 0000000000..b6810a984e
--- /dev/null
+++ b/site/src/routes/faq/index.json.js
@@ -0,0 +1,24 @@
+import send from '@polka/send';
+import get_faqs from './_faqs.js';
+
+let json;
+
+export function get(req, res) {
+ if (!json || process.env.NODE_ENV !== 'production') {
+ const faqs = get_faqs()
+ .map(faq => {
+ return {
+ fragment: faq.fragment,
+ answer: faq.answer,
+ metadata: faq.metadata
+ };
+ });
+
+ json = JSON.stringify(faqs);
+ }
+
+ send(res, 200, json, {
+ 'Content-Type': 'application/json',
+ 'Cache-Control': `max-age=${5 * 60 * 1e3}` // 5 minutes
+ });
+}
diff --git a/site/src/routes/faq/index.svelte b/site/src/routes/faq/index.svelte
new file mode 100644
index 0000000000..c426f5bf3d
--- /dev/null
+++ b/site/src/routes/faq/index.svelte
@@ -0,0 +1,89 @@
+
+
+
+
+
+ Frequently Asked Questions • Svelte
+
+
+
+
+
+
+