First commit

This commit is contained in:
Melon 2023-08-20 22:02:06 +01:00
commit 88a66f6763
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
22 changed files with 1504 additions and 0 deletions

4
create.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
git clone https://github.com/1f349/svelte-ssr-template svelte-ssr-template
cp -r svelte-ssr-template/template/* .
rm -r svelte-ssr-template

36
template/.editorconfig Normal file
View File

@ -0,0 +1,36 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Defaults
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
# CSS
[*.css]
indent_size = 2
indent_style = space
trim_trailing_whitespace = true
# HTML
[*.{htm,html}]
indent_size = 2
indent_style = space
trim_trailing_whitespace = true
# GNU make
[Makefile]
indent_style = tab
# Svelte
[*.svelte]
indent_size = 2
indent_style = space
# YAML
[*.{yaml,yml}]
indent_size = 2
indent_style = space

25
template/.gitignore vendored Normal file
View File

@ -0,0 +1,25 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
*.development
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

13
template/.prettierrc Normal file
View File

@ -0,0 +1,13 @@
{
"printWidth": 150,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"trailingComma": "all",
"bracketSpacing": false,
"bracketSameLine": false,
"arrowParens": "avoid",
"requirePragma": false,
"insertPragma": false
}

3
template/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"recommendations": ["svelte.svelte-vscode"]
}

15
template/README.md Normal file
View File

@ -0,0 +1,15 @@
# Svelte SSR Template
## Building
```bash
yarn
yarn run build
```
## Development
```bash
yarn
yarn run dev
```

38
template/package.json Normal file
View File

@ -0,0 +1,38 @@
{
"name": "svelte-ssr-template",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"prettier:check:ci": "./node_modules/.bin/prettier --check .",
"format": "./node_modules/.bin/prettier --write .",
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@svelte-parts/markdown": "^0.0.23",
"@sveltejs/vite-plugin-svelte": "^1.1.0",
"@tsconfig/svelte": "^3.0.0",
"@types/dompurify": "^2.4.0",
"@types/highlight.js": "^10.1.0",
"dompurify": "^2.4.1",
"highlight.js": "^11.7.0",
"prettier": "^2.7.1",
"prettier-plugin-svelte": "^2.8.0",
"sass": "^1.56.0",
"svelte": "^3.52.0",
"svelte-check": "^2.9.2",
"svelte-markdown": "^0.2.3",
"svelte-navigator": "^3.2.2",
"svelte-preprocess": "^4.10.7",
"tslib": "^2.4.0",
"typescript": "^4.6.4",
"vite": "^3.2.0",
"vite-plugin-ssr": "^0.4.90"
},
"dependencies": {
"semver": "^7.5.3"
}
}

Binary file not shown.

36
template/server.ts Normal file
View File

@ -0,0 +1,36 @@
const express = require("express");
const {renderPage} = require("vite-plugin-ssr");
const isProduction = process.env.NODE_ENV === "production";
const root = `${__dirname}/..`;
startServer();
async function startServer() {
const app = express();
if (isProduction) {
app.use(express.static(`${root}/client`));
} else {
const vite = require("vite");
const viteDevServer = await vite.createServer({
root,
server: {
middlewareMode: true,
},
});
app.use(viteDevServer.middlewares);
}
app.get("*", async (req, res, next) => {
const pageContextInit = {urlOriginal: req.originalUrl};
const pageContext = await renderPage(pageContextInit);
if (pageContext.httpResponse === null) return next();
const {body, statusCode, contentType} = pageContext.httpResponse;
res.status(statusCode).type(contentType).send(body);
});
const port = 5173;
app.listen(port);
console.log(`Server running at http://localhost:${port}`);
}

View File

@ -0,0 +1,27 @@
<script lang="ts">
export let url: string;
export let title: string;
export let description: string;
export let keywords: string;
</script>
<svelte:head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<title>{title}</title>
<meta name="theme-color" content="#0000" />
<meta name="default-theme" content="auto" />
<meta name="author" content="Svelte SSR Template" />
<meta name="description" content={description} />
<meta name="keywords" content="svelte-ssr-template,{keywords}" />
<meta name="referrer" content="no-referrer" />
<meta property="og:title" content={title} />
<meta property="og:url" content={url.indexOf("https://") == 0 ? url : "https://example.com" + (url[0] == "/" ? url : "/" + url)} />
<meta property="og:type" content="object" />
<meta property="og:image" content="https://example.com/logo.png" />
<meta property="og:site_name" content="Svelte SSR Template" />
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
<link rel="icon" type="image/png" href="/logo.png" />
</svelte:head>

View File

@ -0,0 +1,9 @@
<script lang="ts">
import "~/styles/app.scss";
</script>
<div>
<main>
<slot />
</main>
</div>

View File

@ -0,0 +1,30 @@
export const clientRouting = true;
export const prefetchStaticAssets = {when: "HOVER"};
export async function render(pageContext) {
const app_el = document.getElementById("app");
new pageContext.Page({
target: app_el,
hydrate: true,
props: {
__: pageContext.__,
pageProps: pageContext.pageProps,
},
});
}
export function onPageTransitionStart(pageContext) {
console.log("Page transition start");
// `pageContext.isBackwardNavigation` is also set at `render(pageContext)`
// and `onPageTransitionEnd(pageContext)`.
console.log("Is backwards navigation?", pageContext.isBackwardNavigation);
// For example:
document.body.classList.add("page-transition");
}
export function onPageTransitionEnd(pageContext) {
console.log("Page transition end");
// For example:
document.body.classList.remove("page-transition");
}

View File

@ -0,0 +1,44 @@
import {escapeInject, dangerouslySkipEscape} from "vite-plugin-ssr";
const base = import.meta.env.BASE_URL;
// See https://vite-plugin-ssr.com/data-fetching
export const passToClient = ["__", "pageProps", "routeParams", "urlOriginal"];
export async function onBeforeRender(pageContext) {
const {routeParams, urlOriginal} = pageContext;
return {
pageContext: {
__: {
routeParams,
urlOriginal,
},
},
};
}
export async function render(pageContext) {
const app = pageContext.Page.render(pageContext);
const appHtml = app.html;
const appCss = app.css.code;
const appHead = app.head;
// We are using Svelte's app.head variable rather than the Vite Plugin SSR
// technique described here: https://vite-plugin-ssr.com/html-head This seems
// easier for using data fetched from APIs and also allows us to input the
// data using our custom MetaTags Svelte component.
return escapeInject`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="${base}logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
${dangerouslySkipEscape(appHead)}
<style>${appCss}</style>
</head>
<body>
<div id="app">${dangerouslySkipEscape(appHtml)}</div>
</body>
</html>`;
}

View File

@ -0,0 +1,24 @@
<script lang="ts">
import {navigate} from "vite-plugin-ssr/client/router";
import MetaTags from "~/components/MetaTags.svelte";
import Layout from "./__layout.svelte";
export let __;
export let pageProps;
</script>
<MetaTags url={__.urlOriginal} title="Error" description="" keywords="error,error page" />
<Layout>
<div>
{#if pageProps.is404}
<h1 class="title-text">404 Not Found</h1>
<p class="coming-soon">You have lost your way, please return to valid paths.</p>
<p><button on:click={() => navigate("/")} class="refresh-btn">Back to homepage</button></p>
{:else}
<h1 class="title-text">500 Internal Server Error</h1>
<p class="coming-soon">The server had an issue with this page.</p>
<p><button on:click={() => navigate("/")} class="refresh-btn">Back to homepage</button></p>
{/if}
</div>
</Layout>

View File

@ -0,0 +1,21 @@
<script lang="ts">
import MetaTags from "~/components/MetaTags.svelte";
import Layout from "./__layout.svelte";
export let __;
export let pageProps;
</script>
<MetaTags url={__.urlOriginal} title="Svelte SSR Template" description="Svelte SSR Template Home Page" keywords="" />
<Layout isHome={true}>
<h1 class="title-text">Svelte SSR Template</h1>
</Layout>
<style lang="scss">
.title-text {
margin: 0 0 24px 0;
font-size: 3.2em;
line-height: 1.1;
}
</style>

View File

@ -0,0 +1,39 @@
@font-face {
font-family: 'Ubuntu';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/Ubuntu.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
:root {
font-family: Ubuntu, Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color-scheme: light dark;
color: #e2e2e2;
background-color: #000000;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
a {
font-weight: 500;
color: tomato;
text-decoration: inherit;
&:hover {
color: tomato;
}
}

9
template/src/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
/// <reference types="svelte" />
/// <reference types="vite/client" />
interface ImportMetaEnv {
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

View File

@ -0,0 +1,7 @@
import sveltePreprocess from "svelte-preprocess";
export default {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: sveltePreprocess(),
};

22
template/tsconfig.json Normal file
View File

@ -0,0 +1,22 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"resolveJsonModule": true,
"baseUrl": "./src",
"paths": {"~/*": ["./*"]},
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable checkJs if you'd like to use dynamic types in JS.
* Note that setting allowJs false does not prevent the use
* of JS in `.svelte` files.
*/
"allowJs": true,
"checkJs": true,
"isolatedModules": true
},
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte", "src/**/*.mjs"],
"references": [{"path": "./tsconfig.node.json"}]
}

View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node"
},
"include": ["vite.config.ts"]
}

38
template/vite.config.ts Normal file
View File

@ -0,0 +1,38 @@
import {defineConfig} from "vite";
import {svelte} from "@sveltejs/vite-plugin-svelte";
import sveltePreprocess from "svelte-preprocess";
import {resolve as pathResolve} from "path";
import ssr from "vite-plugin-ssr/plugin";
// https://vitejs.dev/config/
export default defineConfig({
build: {
emptyOutDir: true,
},
server: {
port: 5173,
},
plugins: [
svelte({
preprocess: sveltePreprocess({
preserve: ["ld+json"],
scss: {
includePaths: ["src/"],
quietDeps: true,
},
}),
compilerOptions: {
hydratable: true,
},
}),
ssr({
prerender: true,
}),
],
optimizeDeps: {exclude: ["svelte-navigator"]},
resolve: {
alias: {
"~": pathResolve(__dirname, "src"),
},
},
});

1056
template/yarn.lock Normal file

File diff suppressed because it is too large Load Diff