Redesign pages, remove layout nesting (#24)
* wip * new svelte-style prop declaration is working * got it working! * revert h changes * format * style lang update
This commit is contained in:
parent
3c24faa8ca
commit
a72ab10c62
28 changed files with 751 additions and 714 deletions
38
examples/snowpack/astro/components/BaseHead.astro
Normal file
38
examples/snowpack/astro/components/BaseHead.astro
Normal file
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
import Banner from './Banner.astro';
|
||||
import Nav from './Nav.astro';
|
||||
|
||||
export let title: string;
|
||||
export let description: string;
|
||||
export let permalink: string;
|
||||
---
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />
|
||||
<link rel="manifest" href="/favicon/site.webmanifest" />
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>{title}</title>
|
||||
<meta name="title" content={title} />
|
||||
<meta name="description" content="{description}" />
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={permalink} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content="https://www.snowpack.dev/img/social-2.jpg" />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={permalink} />
|
||||
<meta property="twitter:title" content={title} />
|
||||
<meta property="twitter:description" content={description} />
|
||||
<meta property="twitter:image" content="https://www.snowpack.dev/img/social-2.jpg" />
|
||||
|
||||
<!-- Global Stylesheets -->
|
||||
<link rel="stylesheet" href="/css/app.css" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Overpass:wght@400;700;900&display=swap" rel="stylesheet" />
|
20
examples/snowpack/astro/components/BaseLayout.astro
Normal file
20
examples/snowpack/astro/components/BaseLayout.astro
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
import Banner from './Banner.astro';
|
||||
import Nav from './Nav.astro';
|
||||
---
|
||||
|
||||
<Banner></Banner>
|
||||
<Nav />
|
||||
|
||||
<slot></slot>
|
||||
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-130280175-9"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-130280175-9', { page_path: location.pathname === '/' ? (location.pathname + location.hash) : (location.pathname) });
|
||||
</script>
|
23
examples/snowpack/astro/components/MainLayout.astro
Normal file
23
examples/snowpack/astro/components/MainLayout.astro
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
import BaseLayout from './BaseLayout.astro';
|
||||
import Menu from './Menu.astro';
|
||||
export function setup({ context }) {
|
||||
return {};
|
||||
}
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
<div class="container">
|
||||
<section class="snow-view__docs is-full">
|
||||
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu />
|
||||
</aside>
|
||||
|
||||
<article class="snow-view-main">
|
||||
<slot></slot>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</BaseLayout>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
export let props: { version: string };
|
||||
export let version: string = '3.1.2';
|
||||
---
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -257,7 +257,7 @@
|
|||
</div>
|
||||
<div style="flex-grow: 1"></div>
|
||||
<a href="https://github.com/snowpackjs/snowpack/releases" target="_blank" class="link version">
|
||||
{`v${props.version}`}
|
||||
{`v${version}`}
|
||||
</a>
|
||||
<a href="https://github.com/snowpackjs/snowpack" target="_blank" class="link link__desktop">
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="github" class="snow-icon" role="img"
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
---
|
||||
export let props: {
|
||||
title: string,
|
||||
inputPath: string,
|
||||
headers: { text: string, slug: string }[]
|
||||
};
|
||||
export let title: string;
|
||||
export let inputPath: string;
|
||||
export let headers: string;
|
||||
---
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -59,12 +57,12 @@
|
|||
|
||||
<script type="module" defer src="/js/index.js"></script>
|
||||
<aside class="subnav">
|
||||
{props.headers.length > 0 && (
|
||||
{headers.length > 0 && (
|
||||
<div>
|
||||
<h4 class="header">On this page</h4>
|
||||
<nav class="toc">
|
||||
<ol>
|
||||
{props.headers.map((heading) => {
|
||||
{headers.map((heading) => {
|
||||
return <li><a href={"#" + heading.slug}>{heading.text}</a></li>
|
||||
})}
|
||||
</ol>
|
||||
|
@ -74,5 +72,5 @@
|
|||
)}
|
||||
|
||||
<h4 class="header">Suggest a change</h4>
|
||||
<a href="https://github.com/snowpackjs/snowpack/blob/main/www/{props.inputPath}">Edit this page on GitHub</a>
|
||||
<a href="https://github.com/snowpackjs/snowpack/blob/main/www/{inputPath}">Edit this page on GitHub</a>
|
||||
</aside>
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
---
|
||||
import Banner from '../components/Banner.astro';
|
||||
import Nav from '../components/Nav.astro';
|
||||
export function setup({ context }) {
|
||||
return {
|
||||
context: {
|
||||
title: 'Snowpack',
|
||||
description: 'Snowpack is a lightning-fast frontend build tool, designed for the modern web.',
|
||||
currentSnowpackVersion: '3.0.13',
|
||||
}
|
||||
};
|
||||
}
|
||||
---
|
||||
|
||||
<astro:head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />
|
||||
<link rel="manifest" href="/favicon/site.webmanifest" />
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>{context.title}</title>
|
||||
<meta name="title" content={context.title} />
|
||||
<meta name="description" content="{context.description}" />
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={context.permalink} />
|
||||
<meta property="og:title" content={context.title} />
|
||||
<meta property="og:description" content={context.description} />
|
||||
<meta property="og:image" content="https://www.snowpack.dev/img/social-2.jpg" />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={context.permalink} />
|
||||
<meta property="twitter:title" content={context.title} />
|
||||
<meta property="twitter:description" content={context.description} />
|
||||
<meta property="twitter:image" content="https://www.snowpack.dev/img/social-2.jpg" />
|
||||
|
||||
<!-- Global Stylesheets -->
|
||||
<link rel="stylesheet" href="/css/app.css" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Overpass:wght@400;700;900&display=swap" rel="stylesheet" />
|
||||
</astro:head>
|
||||
|
||||
<Banner></Banner>
|
||||
<Nav version={context.currentSnowpackVersion} />
|
||||
|
||||
<!-- if no slot given, assume add to bottom -->
|
||||
<slot></slot>
|
||||
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-130280175-9"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-130280175-9', { page_path: location.pathname === '/' ? (location.pathname + location.hash) : (location.pathname) });
|
||||
</script>
|
|
@ -1,78 +1,88 @@
|
|||
---
|
||||
import Menu from '../components/Menu.astro';
|
||||
import Subnav from '../components/Subnav.astro';
|
||||
import Subnav from '../components/Subnav.astro';
|
||||
import Menu from '../components/Menu.astro';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import BaseLayout from '../components/BaseLayout.astro';
|
||||
|
||||
export const layout = 'layouts/base.astro';
|
||||
export function setup({ context }) {
|
||||
return {};
|
||||
}
|
||||
export let content: any;
|
||||
---
|
||||
|
||||
<html>
|
||||
|
||||
<style>
|
||||
.cover-wrapper {
|
||||
width: 100%;
|
||||
height: 44vh;
|
||||
min-height: 20rem;
|
||||
max-height: 30rem;
|
||||
position: relative;
|
||||
background: #2a85ca40;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cover,
|
||||
.cover-blur {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.cover-blur {
|
||||
object-fit: cover;
|
||||
filter: blur(3px) brightness(1.5);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.cover {
|
||||
object-fit: contain;
|
||||
filter: brightness(1.5);
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
<head>
|
||||
<style>
|
||||
.cover-wrapper {
|
||||
width: 100%;
|
||||
height: 44vh;
|
||||
min-height: 20rem;
|
||||
max-height: 30rem;
|
||||
position: relative;
|
||||
background: #2a85ca40;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cover,
|
||||
.cover-blur {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.cover-blur {
|
||||
object-fit: cover;
|
||||
filter: blur(3px) brightness(1.5);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.cover {
|
||||
object-fit: cover;
|
||||
object-fit: contain;
|
||||
filter: brightness(1.5);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@media (max-width: 1200px) {
|
||||
.cover-blur {
|
||||
object-fit: cover;
|
||||
}
|
||||
.cover {
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<BaseHead title={content.title} description={content.description} permalink="TODO" />
|
||||
</head>
|
||||
|
||||
<div class="cover-wrapper">
|
||||
<img class="cover-blur" src={context.cover} alt=""/>
|
||||
<img class="cover" src={context.cover} alt=""/>
|
||||
</div>
|
||||
<body>
|
||||
<BaseLayout>
|
||||
|
||||
<div class="container">
|
||||
<section class="snow-view__docs has-subnav">
|
||||
<div class="cover-wrapper">
|
||||
<img class="cover-blur" src={content.cover} alt=""/>
|
||||
<img class="cover" src={content.cover} alt=""/>
|
||||
</div>
|
||||
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu />
|
||||
</aside>
|
||||
<div class="container">
|
||||
<section class="snow-view__docs has-subnav">
|
||||
|
||||
<article class="snow-view-main">
|
||||
<div class="content">
|
||||
<h2 class="content-title">
|
||||
{context.title}
|
||||
</h2>
|
||||
<div class="content-layout">
|
||||
<div class="content-body">
|
||||
<slot></slot>
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu />
|
||||
</aside>
|
||||
|
||||
<article class="snow-view-main">
|
||||
<div class="content">
|
||||
<h2 class="content-title">
|
||||
{content.title}
|
||||
</h2>
|
||||
<div class="content-layout">
|
||||
<div class="content-body">
|
||||
{content.body}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</article>
|
||||
|
||||
<Subnav title={context.title} headers={context.content.headers} />
|
||||
</section>
|
||||
</div>
|
||||
<Subnav title={content.title} headers={content.headers} />
|
||||
</section>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,37 +1,45 @@
|
|||
---
|
||||
import Subnav from '../components/Subnav.astro';
|
||||
import Menu from '../components/Menu.astro';
|
||||
import Subnav from '../components/Subnav.astro';
|
||||
import Menu from '../components/Menu.astro';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import BaseLayout from '../components/BaseLayout.astro';
|
||||
|
||||
export const layout = 'layouts/base.astro';
|
||||
export function setup({ context }) {
|
||||
return {
|
||||
context: {
|
||||
}
|
||||
};
|
||||
}
|
||||
export let content: any;
|
||||
---
|
||||
|
||||
<div class="container">
|
||||
<section class="snow-view__docs has-subnav">
|
||||
<html>
|
||||
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu />
|
||||
</aside>
|
||||
<head>
|
||||
<BaseHead title={content.title} description={content.description} permalink="TODO" />
|
||||
</head>
|
||||
|
||||
<Subnav title={context.title} headers={context.content.headers} />
|
||||
<body>
|
||||
<BaseLayout>
|
||||
<div class="container">
|
||||
<section class="snow-view__docs has-subnav">
|
||||
|
||||
<article class="snow-view-main">
|
||||
<div class="content">
|
||||
<h2 class="content-title">
|
||||
{context.title}
|
||||
</h2>
|
||||
<div class="content-layout">
|
||||
<div class="content-body">
|
||||
<slot></slot>
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu />
|
||||
</aside>
|
||||
|
||||
<Subnav title={content.title} headers={content.headers} />
|
||||
|
||||
<article class="snow-view-main">
|
||||
<div class="content">
|
||||
<h2 class="content-title">
|
||||
{content.title}
|
||||
</h2>
|
||||
<div class="content-layout">
|
||||
<div class="content-body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
import Menu from '../components/Menu.astro';
|
||||
export const layout = 'layouts/base.astro';
|
||||
export function setup({ context }) {
|
||||
return {};
|
||||
}
|
||||
---
|
||||
|
||||
<div class="container">
|
||||
<section class="snow-view__docs is-full">
|
||||
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu />
|
||||
</aside>
|
||||
|
||||
<article class="snow-view-main">
|
||||
<slot></slot>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
</div>
|
|
@ -1,127 +1,136 @@
|
|||
---
|
||||
import { format as formatDate, parseISO } from 'date-fns';
|
||||
export const layout = 'layouts/base.astro';
|
||||
export function setup({ context }) {
|
||||
return {};
|
||||
}
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import BaseLayout from '../components/BaseLayout.astro';
|
||||
import { format as formatDate, parseISO } from 'date-fns';
|
||||
|
||||
export let content: any;
|
||||
---
|
||||
|
||||
<astro:head>
|
||||
<link rel="stylesheet" href="/css/legacy-post.css" />
|
||||
</astro:head>
|
||||
|
||||
<style>
|
||||
.markdown-body img,
|
||||
.markdown-body video,
|
||||
.markdown-body iframe {
|
||||
box-shadow: 0px 5px 12px 0 #CCC;
|
||||
border-radius: 3px;
|
||||
min-width: 130%;
|
||||
width: 130%;
|
||||
margin-left: -15%;
|
||||
margin-right: -15%;
|
||||
margin-top: 4rem;
|
||||
margin-bottom: -1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<style>
|
||||
.markdown-body img,
|
||||
.markdown-body video,
|
||||
.markdown-body iframe {
|
||||
min-width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: -2rem;
|
||||
box-shadow: 0px 5px 12px 0 #CCC;
|
||||
border-radius: 3px;
|
||||
min-width: 130%;
|
||||
width: 130%;
|
||||
margin-left: -15%;
|
||||
margin-right: -15%;
|
||||
margin-top: 4rem;
|
||||
margin-bottom: -1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-body table td:nth-child(1) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.markdown-body,
|
||||
.fbody-header {
|
||||
max-width: 840px;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
font-size: 18px;
|
||||
margin-bottom: 20vh;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
|
||||
@media (max-width: 860px) {
|
||||
|
||||
.markdown-body img,
|
||||
.markdown-body video,
|
||||
.markdown-body iframe {
|
||||
min-width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: -2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-body table td:nth-child(1) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.markdown-body,
|
||||
.toc {
|
||||
padding: 1em;
|
||||
.fbody-header {
|
||||
max-width: 840px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 740px) {
|
||||
.markdown-body img,
|
||||
.markdown-body iframe {
|
||||
max-width: 108%;
|
||||
margin-left: -4%;
|
||||
margin-right: -4%;
|
||||
|
||||
.markdown-body {
|
||||
font-size: 18px;
|
||||
margin-bottom: 20vh;
|
||||
}
|
||||
|
||||
.grid-body {
|
||||
padding: 20px 0 0 0;
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
.markdown-body,
|
||||
.toc {
|
||||
padding: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 740px) {
|
||||
.markdown-body img,
|
||||
.markdown-body iframe {
|
||||
max-width: 108%;
|
||||
margin-left: -4%;
|
||||
margin-right: -4%;
|
||||
}
|
||||
|
||||
.grid-body {
|
||||
padding: 20px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.header-snowpack {
|
||||
font-size: 3.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 3.5em;
|
||||
}
|
||||
|
||||
.markdown-body h3 .header-link {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
<BaseHead title={content.title} description={content.description} permalink="TODO" />
|
||||
<link rel="stylesheet" href="/css/legacy-post.css" />
|
||||
</head>
|
||||
|
||||
.header-snowpack {
|
||||
font-size: 3.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
<body>
|
||||
<BaseLayout>
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 3.5em;
|
||||
}
|
||||
|
||||
.markdown-body h3 .header-link {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="grid-extra-space">
|
||||
<div class="grid-body-header">
|
||||
<svg height="80px" style="padding-left: 8px;" viewBox="0 0 640 512" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd">
|
||||
<g id="mountain-solid" transform="translate(-1.000000, 0.000000)" fill-rule="nonzero">
|
||||
<path
|
||||
d="M635.92,462.7 L347.92,14.7 C342.03,5.54 331.89,0 321,0 C310.11,0 299.97,5.54 294.08,14.7 L6.08,462.7 C-0.250773249,472.547007 -0.699487627,485.064987 4.91,495.34 C10.522069,505.612419 21.2945349,512 33,512 L609,512 C620.71,512 631.48,505.61 637.09,495.33 C642.699457,485.058495 642.250708,472.543372 635.92,462.7 Z M321,91.18 L406.39,224 L321,224 L257,288 L218.94,249.94 L321,91.18 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<h1 class="header-snowpack">{context.title}</h1>
|
||||
<div class="grid-extra-space">
|
||||
<div class="grid-body-header">
|
||||
<svg height="80px" style="padding-left: 8px;" viewBox="0 0 640 512" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd">
|
||||
<g id="mountain-solid" transform="translate(-1.000000, 0.000000)" fill-rule="nonzero">
|
||||
<path
|
||||
d="M635.92,462.7 L347.92,14.7 C342.03,5.54 331.89,0 321,0 C310.11,0 299.97,5.54 294.08,14.7 L6.08,462.7 C-0.250773249,472.547007 -0.699487627,485.064987 4.91,495.34 C10.522069,505.612419 21.2945349,512 33,512 L609,512 C620.71,512 631.48,505.61 637.09,495.33 C642.699457,485.058495 642.250708,472.543372 635.92,462.7 Z M321,91.18 L406.39,224 L321,224 L257,288 L218.94,249.94 L321,91.18 Z"
|
||||
id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<h1 class="header-snowpack">{content.title}</h1>
|
||||
|
||||
|
||||
<div>
|
||||
{context.tagline && <div style="margin-bottom: 1rem;">{context.tagline}</div>}
|
||||
<div>
|
||||
Published <a href='#published-at'>{formatDate(parseISO(context.date), 'MMMM d, yyyy')}</a>
|
||||
by <a href="https://twitter.com/FredKSchott">Fred K. Schott</a>
|
||||
<div>
|
||||
{content.tagline && <div style="margin-bottom: 1rem;">{content.tagline}</div>}
|
||||
<div>
|
||||
Published <a href='#published-at'>{formatDate(parseISO(content.date), 'MMMM d, yyyy')}</a>
|
||||
by <a href="https://twitter.com/FredKSchott">Fred K. Schott</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Place this tag where you want the button to render. -->
|
||||
<div class="hidden-mobile" style="text-align: center; margin-top: 0.5rem; filter: scale(2);">
|
||||
<a class="github-button" href="https://github.com/snowpackjs/snowpack" data-icon="octicon-star" data-size="large"
|
||||
data-show-count="true" aria-label="Star snowpackjs/snowpack on GitHub">Star</a>
|
||||
</div>
|
||||
<!-- Place this tag in your head or just before your close body tag. -->
|
||||
<script defer src="https://buttons.github.io/buttons.js"></script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Place this tag where you want the button to render. -->
|
||||
<div class="hidden-mobile" style="text-align: center; margin-top: 0.5rem; filter: scale(2);">
|
||||
<a class="github-button" href="https://github.com/snowpackjs/snowpack" data-icon="octicon-star" data-size="large"
|
||||
data-show-count="true" aria-label="Star snowpackjs/snowpack on GitHub">Star</a>
|
||||
<div class="grid-body">
|
||||
<article class="markdown-body">
|
||||
<slot></slot>
|
||||
</article>
|
||||
</div>
|
||||
<!-- Place this tag in your head or just before your close body tag. -->
|
||||
<script defer src="https://buttons.github.io/buttons.js"></script>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-body">
|
||||
<article class="markdown-body">
|
||||
<slot></slot>
|
||||
</article>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,19 +1,26 @@
|
|||
---
|
||||
export const layout = 'layouts/main.astro';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import MainLayout from '../components/MainLayout.astro';
|
||||
|
||||
export function setup({ context }) {
|
||||
return {
|
||||
context: {
|
||||
title: '404 - Not Found',
|
||||
}
|
||||
};
|
||||
}
|
||||
let title = 'Not Found';
|
||||
let description = 'Snowpack is a lightning-fast frontend build tool, designed for the modern web.';
|
||||
---
|
||||
|
||||
<h2 class="content-title">
|
||||
{context.title}
|
||||
</h2>
|
||||
<html>
|
||||
|
||||
<div class="content">
|
||||
<a href="/">Go Home</a>
|
||||
</div>
|
||||
<head>
|
||||
<BaseHead title={title} description={description} permalink="TODO" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<MainLayout>
|
||||
<h2 class="content-title">
|
||||
{title}
|
||||
</h2>
|
||||
<div class="content">
|
||||
<a href="/">Go Home</a>
|
||||
</div>
|
||||
</MainLayout>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,73 +1,86 @@
|
|||
---
|
||||
import Card from '../components/Card.jsx';
|
||||
import Card from '../components/Card.jsx';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import MainLayout from '../components/MainLayout.astro';
|
||||
|
||||
export const layout = 'layouts/main.astro';
|
||||
|
||||
// mocked for now, to be added later
|
||||
// 1. import {paginate} from 'magicthing';
|
||||
// 2. export default function ({paginate}) {
|
||||
function paginate(options) {
|
||||
if (options.tag === 'guide') {
|
||||
return [
|
||||
{ title: 'Test guide 1', href: "#" },
|
||||
{ title: 'Test guide 2', href: "#" },
|
||||
];
|
||||
}
|
||||
if (options.tag === 'communityGuides') {
|
||||
return [{ title: 'Test communityGuides', href: "#" }];
|
||||
}
|
||||
return [];
|
||||
// mocked for now, to be added later
|
||||
// 1. import {paginate} from 'magicthing';
|
||||
// 2. export default function ({paginate}) {
|
||||
function paginate(options) {
|
||||
if (options.tag === 'guide') {
|
||||
return [
|
||||
{ title: 'Test guide 1', href: "#" },
|
||||
{ title: 'Test guide 2', href: "#" },
|
||||
];
|
||||
}
|
||||
|
||||
export function setup({ context, /* paginate */ }) {
|
||||
return {
|
||||
context: {
|
||||
title: 'Guides',
|
||||
description: "Snowpack's usage and integration guides.",
|
||||
guides: paginate({
|
||||
files: '/posts/guides/*.md',
|
||||
// sort: ((a, b) => new Date(b) - new Date(a)),
|
||||
tag: 'guide',
|
||||
limit: 10,
|
||||
// page: query.page,
|
||||
}),
|
||||
communityGuides: paginate({
|
||||
files: '/posts/guides/*.md',
|
||||
// sort: ((a, b) => new Date(b) - new Date(a)),
|
||||
tag: 'communityGuides',
|
||||
limit: 10,
|
||||
}),
|
||||
}
|
||||
};
|
||||
if (options.tag === 'communityGuides') {
|
||||
return [{ title: 'Test communityGuides', href: "#" }];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
let title = 'Guides';
|
||||
let description = 'Snowpack\'s usage and integration guides.';
|
||||
let guides;
|
||||
let communityGuides;
|
||||
|
||||
|
||||
export function setup({ /* paginate */ }) {
|
||||
guides = paginate({
|
||||
files: '/posts/guides/*.md',
|
||||
// sort: ((a, b) => new Date(b) - new Date(a)),
|
||||
tag: 'guide',
|
||||
limit: 10,
|
||||
// page: query.page,
|
||||
});
|
||||
communityGuides = paginate({
|
||||
files: '/posts/guides/*.md',
|
||||
// sort: ((a, b) => new Date(b) - new Date(a)),
|
||||
tag: 'communityGuides',
|
||||
limit: 10,
|
||||
});
|
||||
return {};
|
||||
}
|
||||
---
|
||||
|
||||
<h2 class="content-title">
|
||||
{context.title}
|
||||
</h2>
|
||||
<html>
|
||||
|
||||
<h3 class="content-title">
|
||||
Using Snowpack
|
||||
</h3>
|
||||
<head>
|
||||
<BaseHead title={title} description={description} permalink="TODO" />
|
||||
</head>
|
||||
|
||||
<div class="content">
|
||||
<ul>
|
||||
{context.guides.map((post) => {
|
||||
return <li><a href={post.href}>{post.title}</a></li>;
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
<body>
|
||||
<MainLayout>
|
||||
<h2 class="content-title">
|
||||
{title}
|
||||
</h2>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<h3 class="content-title">
|
||||
Using Snowpack
|
||||
</h3>
|
||||
|
||||
<h3 class="content-title">
|
||||
Popular Integration Guides
|
||||
</h3>
|
||||
<div class="content">
|
||||
<ul>
|
||||
{guides.map((post) => {
|
||||
return <li><a href={post.href}>{post.title}</a></li>;
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-grid card-grid-4">
|
||||
{context.communityGuides.map((post) => {
|
||||
return
|
||||
<Card item={post} />;
|
||||
})}
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<h3 class="content-title">
|
||||
Popular Integration Guides
|
||||
</h3>
|
||||
|
||||
<div class="card-grid card-grid-4">
|
||||
{communityGuides.map((post) => {
|
||||
return
|
||||
<Card item={post} />;
|
||||
})}
|
||||
</div>
|
||||
</MainLayout>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,18 +1,19 @@
|
|||
---
|
||||
import Menu from '../components/Menu.astro';
|
||||
import Hero from '../components/Hero.astro';
|
||||
import Menu from '../components/Menu.astro';
|
||||
import Hero from '../components/Hero.astro';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import BaseLayout from '../components/BaseLayout.astro';
|
||||
|
||||
export const layout = 'layouts/base.astro';
|
||||
export function setup({ context }) {
|
||||
return {};
|
||||
}
|
||||
let title = 'Snowpack';
|
||||
let description = 'Snowpack is a lightning-fast frontend build tool, designed for the modern web.';
|
||||
---
|
||||
|
||||
<astro:head>
|
||||
<meta charset="AAA" />
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<style lang="scss">
|
||||
@use '../../public/css/var' as *;
|
||||
|
||||
|
||||
.top {
|
||||
text-align: left;
|
||||
}
|
||||
|
@ -56,113 +57,96 @@
|
|||
margin: 0.5em;
|
||||
}
|
||||
</style>
|
||||
</astro:head>
|
||||
<Hero bar="{context.title}"></Hero>
|
||||
<BaseHead title={title} description={description} permalink="TODO" />
|
||||
</head>
|
||||
|
||||
<div foo="{context.title}" class="container" style="margin: 0 auto">
|
||||
<section class="snow-view__docs is-full is-home">
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu></Menu>
|
||||
</aside>
|
||||
<body>
|
||||
<BaseLayout>
|
||||
<Hero bar="{title}" />
|
||||
<div foo="{title}" class="container" style="margin: 0 auto">
|
||||
<section class="snow-view__docs is-full is-home">
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu></Menu>
|
||||
</aside>
|
||||
|
||||
<article class="snow-view-main">
|
||||
<div class="content">
|
||||
<article class="grid-body">
|
||||
<a
|
||||
class="img-banner"
|
||||
href="https://osawards.com/javascript/2020"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<img
|
||||
src="/img/JSAwardWinner.png"
|
||||
alt="2020 JavaScript Open Source Award Winner banner"
|
||||
/>
|
||||
</a>
|
||||
<article class="snow-view-main">
|
||||
<div class="content">
|
||||
<article class="grid-body">
|
||||
<a class="img-banner" href="https://osawards.com/javascript/2020" target="_blank"
|
||||
rel="noopener noreferrer">
|
||||
<img src="/img/JSAwardWinner.png" alt="2020 JavaScript Open Source Award Winner banner" />
|
||||
</a>
|
||||
|
||||
<div class="content markdown-body feature-list">
|
||||
<div class="feature-list-top">
|
||||
<p>
|
||||
<strong
|
||||
>Snowpack is a lightning-fast frontend build tool, designed
|
||||
for the modern web.</strong
|
||||
>
|
||||
It is an alternative to heavier, more complex bundlers like
|
||||
webpack or Parcel in your development workflow. Snowpack
|
||||
leverages JavaScript's native module system (<a
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import"
|
||||
>known as ESM</a
|
||||
>) to avoid unnecessary work and stay fast no matter how big
|
||||
your project grows.
|
||||
</p>
|
||||
<p>
|
||||
Once you try it, it's impossible to go back to anything else.
|
||||
</p>
|
||||
</div>
|
||||
<div class="content markdown-body feature-list">
|
||||
<div class="feature-list-top">
|
||||
<p>
|
||||
<strong>Snowpack is a lightning-fast frontend build tool, designed
|
||||
for the modern web.</strong>
|
||||
It is an alternative to heavier, more complex bundlers like
|
||||
webpack or Parcel in your development workflow. Snowpack
|
||||
leverages JavaScript's native module system (<a
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import">known
|
||||
as
|
||||
ESM</a>) to avoid unnecessary work and stay fast no matter how big
|
||||
your project grows.
|
||||
</p>
|
||||
<p>
|
||||
Once you try it, it's impossible to go back to anything else.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ul class="feature-list-bullets">
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Instant startup</h3>
|
||||
Snowpack's unbundled web development server
|
||||
<strong>starts up in 50ms or less</strong>
|
||||
and stays fast in large projects.
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Build once, cache forever</h3>
|
||||
Snowpack never builds the same file twice. Powered by
|
||||
JavaScript’s native module system (ESM) in the browser.
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>HMR feat. Fast Refresh</h3>
|
||||
No refresh required. See changes reflected instantly in the
|
||||
browser with
|
||||
<a href="/concepts/hot-module-replacement"
|
||||
>HMR + Fast Refresh</a
|
||||
>
|
||||
for React, Preact & Svelte.
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Out-of-the-box support</h3>
|
||||
Enjoy Snowpack's built-in support for JSX, TypeScript, React,
|
||||
Preact, CSS Modules
|
||||
<a href="/reference/supported-files">and more.</a>
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Optimize for production</h3>
|
||||
Build for production with built-in optimizations and plugin
|
||||
support for your favorite bundlers.
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Plugins? Plugins!</h3>
|
||||
Babel? Sass? MDX? Browse the entire
|
||||
<a href="/plugins">Snowpack Plugin Catalog</a>
|
||||
to connect your favorite build tool (or
|
||||
<a href="/reference/plugins">create your own!</a>)
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="feature-list-bullets">
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Instant startup</h3>
|
||||
Snowpack's unbundled web development server
|
||||
<strong>starts up in 50ms or less</strong>
|
||||
and stays fast in large projects.
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Build once, cache forever</h3>
|
||||
Snowpack never builds the same file twice. Powered by
|
||||
JavaScript’s native module system (ESM) in the browser.
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>HMR feat. Fast Refresh</h3>
|
||||
No refresh required. See changes reflected instantly in the
|
||||
browser with
|
||||
<a href="/concepts/hot-module-replacement">HMR + Fast Refresh</a>
|
||||
for React, Preact & Svelte.
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Out-of-the-box support</h3>
|
||||
Enjoy Snowpack's built-in support for JSX, TypeScript, React,
|
||||
Preact, CSS Modules
|
||||
<a href="/reference/supported-files">and more.</a>
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Optimize for production</h3>
|
||||
Build for production with built-in optimizations and plugin
|
||||
support for your favorite bundlers.
|
||||
</li>
|
||||
<li class="feature-list-bullet">
|
||||
<h3>Plugins? Plugins!</h3>
|
||||
Babel? Sass? MDX? Browse the entire
|
||||
<a href="/plugins">Snowpack Plugin Catalog</a>
|
||||
to connect your favorite build tool (or
|
||||
<a href="/reference/plugins">create your own!</a>)
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="feature-list-buttons">
|
||||
<a
|
||||
href="/tutorials/quick-start"
|
||||
class="button button-primary feature-list-button"
|
||||
>Get started</a
|
||||
>
|
||||
<a
|
||||
href="/concepts/how-snowpack-works"
|
||||
class="button feature-list-button"
|
||||
>Learn more</a
|
||||
>
|
||||
</div>
|
||||
<div class="feature-list-buttons">
|
||||
<a href="/tutorials/quick-start" class="button button-primary feature-list-button">Get started</a>
|
||||
<a href="/concepts/how-snowpack-works" class="button feature-list-button">Learn more</a>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
<!-- Place this tag in your head or just before your close body tag. -->
|
||||
<script async="async" defer="defer" src="https://buttons.github.io/buttons.js"></script>
|
||||
</body>
|
||||
|
||||
<!-- Place this tag in your head or just before your close body tag. -->
|
||||
<script
|
||||
async="async"
|
||||
defer="defer"
|
||||
src="https://buttons.github.io/buttons.js"
|
||||
></script>
|
||||
</html>
|
|
@ -1,78 +1,86 @@
|
|||
---
|
||||
import Card from '../components/Card.jsx';
|
||||
import CompanyLogo from '../components/CompanyLogo.jsx';
|
||||
import NewsAssets from '../components/NewsAssets.svelte';
|
||||
import NewsTitle from '../components/NewsTitle.vue';
|
||||
import Card from '../components/Card.jsx';
|
||||
import CompanyLogo from '../components/CompanyLogo.jsx';
|
||||
import NewsAssets from '../components/NewsAssets.svelte';
|
||||
import NewsTitle from '../components/NewsTitle.vue';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import MainLayout from '../components/MainLayout.astro';
|
||||
|
||||
export const layout = 'layouts/main.astro';
|
||||
// Using Snowpack? Want to be featured on snowpack.dev?
|
||||
// Add your project, organization, or company to the end of this list!
|
||||
import news from '../data/news.json';
|
||||
import users from '../data/users.json';
|
||||
|
||||
import news from '../data/news.json';
|
||||
import users from '../data/users.json';
|
||||
let title = 'Community & News';
|
||||
let description = 'Snowpack community news and companies that use Snowpack.';
|
||||
let pokemonData;
|
||||
|
||||
export async function setup({ context, request, fetch }) {
|
||||
const pokemonData = await fetch(`https://pokeapi.co/api/v2/pokemon/ditto`);
|
||||
return {
|
||||
context: {
|
||||
title: 'Community & News',
|
||||
description: "Snowpack community news and companies that use Snowpack.",
|
||||
// Using Snowpack? Want to be featured on snowpack.dev?
|
||||
// Add your project, organization, or company to the end of this list!
|
||||
news,
|
||||
users,
|
||||
pokemonData: await pokemonData.json(),
|
||||
}
|
||||
}
|
||||
}
|
||||
export async function setup({ context, request, fetch }) {
|
||||
const pokemonDataReq = await fetch(`https://pokeapi.co/api/v2/pokemon/ditto`);
|
||||
pokemonData = await pokemonDataReq.json();
|
||||
return {};
|
||||
}
|
||||
---
|
||||
|
||||
<NewsTitle title={context.title} />
|
||||
<html>
|
||||
|
||||
<p>
|
||||
Get the latest news, blog posts, and tutorials on Snowpack. <a href="/feed.xml">Also available via RSS.</a>
|
||||
</p>
|
||||
<head>
|
||||
<BaseHead title={title} description={description} permalink="TODO" />
|
||||
</head>
|
||||
|
||||
<p>
|
||||
Got something that you think we should feature?
|
||||
<a href="https://github.com/snowpackjs/snowpack/edit/main/www/_data/news.js">Submit it!</a>
|
||||
</p>
|
||||
<body>
|
||||
<MainLayout>
|
||||
<NewsTitle title={title} />
|
||||
<p>
|
||||
Get the latest news, blog posts, and tutorials on Snowpack. <a href="/feed.xml">Also available via RSS.</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In case you're curious, the best pokemon is <strong>{context.pokemonData.name}.</strong>
|
||||
</p>
|
||||
<p>
|
||||
Got something that you think we should feature?
|
||||
<a href="https://github.com/snowpackjs/snowpack/edit/main/www/_data/news.js">Submit it!</a>
|
||||
</p>
|
||||
|
||||
<div class="card-grid card-grid-3">
|
||||
<article class="discord-banner">
|
||||
<a href="https://discord.gg/snowpack" style="flex-shrink: 0; height: 48px;"><img alt="Join us on Discord!"
|
||||
src="https://img.shields.io/discord/712696926406967308.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2"
|
||||
style="height: 48px; border: none; margin-right: 1rem; filter: brightness(1.2) contrast(1.5);" /></a>
|
||||
<div>Join us on Discord to discuss Snowpack, meet other developers in our community, and show off what you’re
|
||||
working on!</div>
|
||||
</article>
|
||||
<p>
|
||||
In case you're curious, the best pokemon is <strong>{pokemonData.name}.</strong>
|
||||
</p>
|
||||
|
||||
{context.news.reverse().map((item: any) =>
|
||||
<Card:dynamic item={item} />)}
|
||||
</div>
|
||||
<div class="card-grid card-grid-3">
|
||||
<article class="discord-banner">
|
||||
<a href="https://discord.gg/snowpack" style="flex-shrink: 0; height: 48px;"><img alt="Join us on Discord!"
|
||||
src="https://img.shields.io/discord/712696926406967308.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2"
|
||||
style="height: 48px; border: none; margin-right: 1rem; filter: brightness(1.2) contrast(1.5);" /></a>
|
||||
<div>Join us on Discord to discuss Snowpack, meet other developers in our community, and show off what you’re
|
||||
working on!</div>
|
||||
</article>
|
||||
|
||||
<div class="content">
|
||||
{news.reverse().map((item: any) =>
|
||||
<Card:dynamic item={item} />)}
|
||||
</div>
|
||||
|
||||
<h3>Who's Using Snowpack?</h3>
|
||||
<div class="content">
|
||||
|
||||
<div class="company-logos">
|
||||
<h3>Who's Using Snowpack?</h3>
|
||||
|
||||
{context.users.map((user) =>
|
||||
<CompanyLogo user={user} />)}
|
||||
<div class="company-logos">
|
||||
|
||||
<a href="https://github.com/snowpackjs/snowpack/edit/main/www/_template/news.md" target="_blank"
|
||||
title="Add Your Project/Company!" class="add-company-button">
|
||||
<svg style="height: 22px; margin-right: 8px;" aria-hidden="true" focusable="false" data-prefix="fas"
|
||||
data-icon="plus" class="company-logo" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<path fill="currentColor"
|
||||
d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z">
|
||||
</path>
|
||||
</svg>
|
||||
Add your logo
|
||||
</a>
|
||||
</div>
|
||||
{users.map((user) =>
|
||||
<CompanyLogo user={user} />)}
|
||||
|
||||
<NewsAssets />
|
||||
</div>
|
||||
<a href="https://github.com/snowpackjs/snowpack/edit/main/www/_template/news.md" target="_blank"
|
||||
title="Add Your Project/Company!" class="add-company-button">
|
||||
<svg style="height: 22px; margin-right: 8px;" aria-hidden="true" focusable="false" data-prefix="fas"
|
||||
data-icon="plus" class="company-logo" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<path fill="currentColor"
|
||||
d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z">
|
||||
</path>
|
||||
</svg>
|
||||
Add your logo
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<NewsAssets />
|
||||
</div>
|
||||
</MainLayout>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,70 +1,72 @@
|
|||
---
|
||||
import news from '../data/news.json';
|
||||
import users from '../data/users.json';
|
||||
import PluginSearchPage from '../components/PluginSearchPage.jsx';
|
||||
import PluginSearchPage from '../components/PluginSearchPage.jsx';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import MainLayout from '../components/MainLayout.astro';
|
||||
|
||||
export const layout = 'layouts/main.astro';
|
||||
|
||||
export function setup({ context }) {
|
||||
return {
|
||||
context: {
|
||||
title: 'The Snowpack Plugin Catalog',
|
||||
description:
|
||||
'Snowpack plugins allow for configuration-minimal tooling integration.',
|
||||
},
|
||||
};
|
||||
}
|
||||
let title = 'The Snowpack Plugin Catalog';
|
||||
let description = 'Snowpack plugins allow for configuration-minimal tooling integration.';
|
||||
---
|
||||
|
||||
<style lang="scss">
|
||||
.intro {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
<html>
|
||||
|
||||
a {
|
||||
<head>
|
||||
<BaseHead title={title} description={description} permalink="TODO" />
|
||||
<style lang="scss">
|
||||
.intro {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
|
||||
a {
|
||||
color: #2e5e82;
|
||||
}
|
||||
}
|
||||
|
||||
.subheading {
|
||||
margin-top: -2.5rem;
|
||||
margin-bottom: 0;
|
||||
color: #2e5e82;
|
||||
font-weight: 500;
|
||||
font-size: 1em;
|
||||
font-family: 'Overpass', sans-serif;
|
||||
letter-spacing: -0.02em;
|
||||
text-align: left;
|
||||
|
||||
@media (min-width: 600px) {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subheading {
|
||||
margin-top: -2.5rem;
|
||||
margin-bottom: 0;
|
||||
color: #2e5e82;
|
||||
font-weight: 500;
|
||||
font-size: 1em;
|
||||
font-family: 'Overpass', sans-serif;
|
||||
letter-spacing: -0.02em;
|
||||
text-align: left;
|
||||
.zero-heading {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
font-weight: 700;
|
||||
font-size: 1.4em;
|
||||
text-align: left;
|
||||
|
||||
@media (min-width: 600px) {
|
||||
font-size: 1.5em;
|
||||
@media (min-width: 600px) {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
.zero-heading {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
font-weight: 700;
|
||||
font-size: 1.4em;
|
||||
text-align: left;
|
||||
<body>
|
||||
<MainLayout>
|
||||
<h2 class="content-title">{ title }</h2>
|
||||
|
||||
@media (min-width: 600px) {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<h3 class="pluginPage-subheading">
|
||||
Customize Snowpack with optimized build plugins.
|
||||
</h3>
|
||||
<p class="pluginPage-intro">
|
||||
To learn more about our plugin system, check out the
|
||||
<a href="/reference/plugins">Plugin API.</a><br />Can't find what you need?
|
||||
<a href="/reference/plugins">Creating your own plugin is easy!</a>
|
||||
</p>
|
||||
|
||||
<h2 class="content-title">{ context.title }</h2>
|
||||
<PluginSearchPage:dynamic />
|
||||
</MainLayout>
|
||||
</body>
|
||||
|
||||
<h3 class="pluginPage-subheading">
|
||||
Customize Snowpack with optimized build plugins.
|
||||
</h3>
|
||||
<p class="pluginPage-intro">
|
||||
To learn more about our plugin system, check out the
|
||||
<a href="/reference/plugins">Plugin API.</a><br />Can't find what you need?
|
||||
<a href="/reference/plugins">Creating your own plugin is easy!</a>
|
||||
</p>
|
||||
|
||||
<PluginSearchPage:dynamic />
|
||||
</html>
|
||||
|
|
|
@ -1,23 +1,34 @@
|
|||
---
|
||||
import Subnav from '../components/Subnav.astro';
|
||||
import { content as Menu } from '../components/Menu.astro';
|
||||
// import contentful from 'skypack:contentful';
|
||||
import Subnav from '../components/Subnav.astro';
|
||||
import Menu from '../components/Menu.astro';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import BaseLayout from '../components/BaseLayout.astro';
|
||||
// import contentful from 'skypack:contentful';
|
||||
|
||||
export default async function ({ params }) {
|
||||
const entry = await contentful.getEntry(params.slug);
|
||||
return { title: entry.fields.title, description: entry.fields.description, layout: 'layouts/base.astro', props: { entry } };
|
||||
}
|
||||
let title = 'Community & News';
|
||||
let description = 'Snowpack community news and companies that use Snowpack.';
|
||||
let entry;
|
||||
|
||||
export default async function ({ params }) {
|
||||
entry = await contentful.getEntry(params.slug);
|
||||
return { title: entry.fields.title, description: entry.fields.description, layout: 'layouts/base.astro', props: { entry } };
|
||||
}
|
||||
---
|
||||
|
||||
<div class="container">
|
||||
<section class="snow-view__docs has-subnav">
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<BaseHead title={title} description={description} permalink="TODO" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<MainLayout>
|
||||
<div class="container">
|
||||
<section class="snow-view__docs has-subnav">
|
||||
<aside id="nav-primary" class="snow-view-nav">
|
||||
<Menu />
|
||||
</aside>
|
||||
|
||||
<Subnav title={context.title} headers={context.content.headers} />
|
||||
|
||||
<Subnav title={context.title} headers={context.content.headers} />
|
||||
<article class="snow-view-main">
|
||||
<div class="content">
|
||||
<h2 class="content-title">
|
||||
|
@ -30,6 +41,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
</MainLayout>
|
||||
</body>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</html>
|
|
@ -11,7 +11,7 @@ export interface AstroConfig {
|
|||
dist: string;
|
||||
projectRoot: URL;
|
||||
astroRoot: URL;
|
||||
extensions?: Record<string, ValidExtensionPlugins>
|
||||
extensions?: Record<string, ValidExtensionPlugins>;
|
||||
}
|
||||
|
||||
export interface JsxItem {
|
||||
|
@ -21,7 +21,7 @@ export interface JsxItem {
|
|||
|
||||
export interface TransformResult {
|
||||
script: string;
|
||||
head: JsxItem | undefined;
|
||||
props: string[];
|
||||
items: JsxItem[];
|
||||
}
|
||||
|
||||
|
|
|
@ -99,20 +99,17 @@ const defaultExtensions: Readonly<Record<string, ValidExtensionPlugins>> = {
|
|||
'.astro': 'astro',
|
||||
'.jsx': 'react',
|
||||
'.vue': 'vue',
|
||||
'.svelte': 'svelte'
|
||||
'.svelte': 'svelte',
|
||||
};
|
||||
|
||||
function getComponentWrapper(_name: string, { type, url }: ComponentInfo, compileOptions: CompileOptions) {
|
||||
const {
|
||||
resolve,
|
||||
extensions = defaultExtensions
|
||||
} = compileOptions;
|
||||
const { resolve, extensions = defaultExtensions } = compileOptions;
|
||||
|
||||
const [name, kind] = _name.split(':');
|
||||
|
||||
const plugin = extensions[type] || defaultExtensions[type];
|
||||
|
||||
if(!plugin) {
|
||||
if (!plugin) {
|
||||
throw new Error(`No supported plugin found for extension ${type}`);
|
||||
}
|
||||
|
||||
|
@ -142,7 +139,9 @@ function getComponentWrapper(_name: string, { type, url }: ComponentInfo, compil
|
|||
case 'react': {
|
||||
if (kind === 'dynamic') {
|
||||
return {
|
||||
wrapper: `__react_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('react')}', '${resolve('react-dom')}')`,
|
||||
wrapper: `__react_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve(
|
||||
'react'
|
||||
)}', '${resolve('react-dom')}')`,
|
||||
wrapperImport: `import {__react_dynamic} from '${internalImport('render/react.js')}';`,
|
||||
};
|
||||
} else {
|
||||
|
@ -215,6 +214,9 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
|
|||
// Compile scripts as TypeScript, always
|
||||
const script = compileScriptSafe(ast.module ? ast.module.content : '');
|
||||
|
||||
// Collect all exported variables for props
|
||||
const scannedExports = eslexer.parse(script)[1].filter((n) => n !== 'setup' && n !== 'layout');
|
||||
|
||||
// Todo: Validate that `h` and `Fragment` aren't defined in the script
|
||||
const [scriptImports] = eslexer.parse(script, 'optional-sourcename');
|
||||
const components = Object.fromEntries(
|
||||
|
@ -380,7 +382,7 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
|
|||
|
||||
return {
|
||||
script: script + '\n' + Array.from(additionalImports).join('\n'),
|
||||
head: headItem,
|
||||
items,
|
||||
props: scannedExports,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -72,4 +72,4 @@ export default async function (astroConfig: AstroConfig) {
|
|||
function formatErrorForBrowser(error: Error) {
|
||||
// TODO make this pretty.
|
||||
return error.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,7 @@ import ReactDOMServer from 'react-dom/server';
|
|||
|
||||
export function __react_static(ReactComponent: any) {
|
||||
return (attrs: Record<string, any>, ...children: any): string => {
|
||||
let html = ReactDOMServer.renderToString(
|
||||
React.createElement(
|
||||
ReactComponent,
|
||||
attrs,
|
||||
children
|
||||
)
|
||||
);
|
||||
let html = ReactDOMServer.renderToString(React.createElement(ReactComponent, attrs, children));
|
||||
return html;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -32,4 +32,4 @@ const plugin: HtmlExtension = {
|
|||
},
|
||||
};
|
||||
|
||||
export { plugin as encodeMarkdown };
|
||||
export { plugin as encodeMarkdown };
|
||||
|
|
|
@ -69,6 +69,7 @@ async function load(config: RuntimeConfig, rawPathname: string | undefined): Pro
|
|||
href: fullurl.toString(),
|
||||
},
|
||||
children: [],
|
||||
props: {},
|
||||
})) as string;
|
||||
|
||||
return {
|
||||
|
@ -103,7 +104,7 @@ export async function createRuntime(astroConfig: AstroConfig, logging: LogOption
|
|||
// Workaround for SKY-251
|
||||
const astroPlugOptions: {
|
||||
resolve?: (s: string) => string;
|
||||
extensions?: Record<string, string>
|
||||
extensions?: Record<string, string>;
|
||||
} = { extensions };
|
||||
if (existsSync(new URL('./package-lock.json', projectRoot))) {
|
||||
const pkgLockStr = await readFile(new URL('./package-lock.json', projectRoot), 'utf-8');
|
||||
|
@ -128,10 +129,7 @@ export async function createRuntime(astroConfig: AstroConfig, logging: LogOption
|
|||
},
|
||||
packageOptions: {
|
||||
knownEntrypoints: ['preact-render-to-string'],
|
||||
external: [
|
||||
'@vue/server-renderer',
|
||||
'node-fetch'
|
||||
],
|
||||
external: ['@vue/server-renderer', 'node-fetch'],
|
||||
},
|
||||
});
|
||||
const snowpack = await startSnowpackServer({
|
||||
|
|
|
@ -52,7 +52,7 @@ async function convertMdToJsx(
|
|||
contents: string,
|
||||
{ compileOptions, filename, fileID }: { compileOptions: CompileOptions; filename: string; fileID: string }
|
||||
): Promise<TransformResult> {
|
||||
const { data: _frontmatterData, content } = matter(contents);
|
||||
const { data: frontmatterData, content } = matter(contents);
|
||||
const { headers, headersExtension } = createMarkdownHeadersCollector();
|
||||
const mdHtml = micromark(content, {
|
||||
allowDangerousHtml: true,
|
||||
|
@ -60,31 +60,27 @@ async function convertMdToJsx(
|
|||
htmlExtensions: [gfmHtml, encodeMarkdown, headersExtension],
|
||||
});
|
||||
|
||||
const setupContext = {
|
||||
..._frontmatterData,
|
||||
content: {
|
||||
frontmatter: _frontmatterData,
|
||||
headers,
|
||||
source: content,
|
||||
html: mdHtml,
|
||||
},
|
||||
// TODO: Warn if reserved word is used in "frontmatterData"
|
||||
const contentData: any = {
|
||||
...frontmatterData,
|
||||
headers,
|
||||
source: content,
|
||||
html: mdHtml,
|
||||
};
|
||||
|
||||
let imports = '';
|
||||
for(let [ComponentName, specifier] of Object.entries(_frontmatterData.import || {})) {
|
||||
for (let [ComponentName, specifier] of Object.entries(frontmatterData.import || {})) {
|
||||
imports += `import ${ComponentName} from '${specifier}';\n`;
|
||||
}
|
||||
|
||||
// </script> can't be anywhere inside of a JS string, otherwise the HTML parser fails.
|
||||
// Break it up here so that the HTML parser won't detect it.
|
||||
const stringifiedSetupContext = JSON.stringify(setupContext).replace(/\<\/script\>/g, `</scrip" + "t>`);
|
||||
const stringifiedSetupContext = JSON.stringify(contentData).replace(/\<\/script\>/g, `</scrip" + "t>`);
|
||||
|
||||
const raw = `---
|
||||
const raw = `---
|
||||
${imports}
|
||||
${_frontmatterData.layout ? `export const layout = ${JSON.stringify(_frontmatterData.layout)};` : ''}
|
||||
export function setup({context}) {
|
||||
return {context: ${stringifiedSetupContext} };
|
||||
}
|
||||
${frontmatterData.layout ? `const __layout = ${JSON.stringify(frontmatterData.layout)};` : ''}
|
||||
const __content = ${stringifiedSetupContext};
|
||||
---
|
||||
<section>${mdHtml}</section>`;
|
||||
|
||||
|
@ -115,11 +111,10 @@ export async function compileComponent(
|
|||
{ compileOptions = defaultCompileOptions, filename, projectRoot }: { compileOptions: CompileOptions; filename: string; projectRoot: string }
|
||||
): Promise<CompileResult> {
|
||||
const sourceJsx = await transformFromSource(source, { compileOptions, filename, projectRoot });
|
||||
const headItem = sourceJsx.head;
|
||||
const headItemJsx = !headItem ? 'null' : headItem.jsx;
|
||||
|
||||
// sort <style> tags first
|
||||
// TODO: remove these and inject in <head>
|
||||
const isPage = path.extname(filename) === '.md' || sourceJsx.items.some((item) => item.name === 'html');
|
||||
sourceJsx.items.sort((a, b) => (a.name === 'style' && b.name !== 'style' ? -1 : 0));
|
||||
|
||||
// return template
|
||||
|
@ -127,61 +122,47 @@ export async function compileComponent(
|
|||
// <script astro></script>
|
||||
${sourceJsx.script}
|
||||
|
||||
// \`__render()\`: Render the contents of the Astro module. "<slot:*>" elements are not
|
||||
// included (see below).
|
||||
// \`__render()\`: Render the contents of the Astro module.
|
||||
import { h, Fragment } from '${internalImport('h.js')}';
|
||||
export function __slothead(children, context) { return h(Fragment, null, ${headItemJsx}); }
|
||||
function __render(props, children, context) { return h(Fragment, null, ${sourceJsx.items.map(({ jsx }) => jsx).join(',')}); }
|
||||
function __render(props, ...children) {
|
||||
${sourceJsx.props.map((p) => `${p} = props.${p} ?? ${p};`).join('\n')}
|
||||
return h(Fragment, null, ${sourceJsx.items.map(({ jsx }) => jsx).join(',')});
|
||||
}
|
||||
export default __render;
|
||||
`;
|
||||
|
||||
if (headItemJsx) {
|
||||
if (isPage) {
|
||||
modJsx += `
|
||||
// \`__renderPage()\`: Render the contents of the Astro module as a page. This is a special flow,
|
||||
// triggered by loading a component directly by URL.
|
||||
// If the page exports a defined "layout", then load + render those first. "context", "astro:head",
|
||||
// and "slot:body" should all inherit from parent layouts, merging together in the correct order.
|
||||
export async function __renderPage({request, children}) {
|
||||
export async function __renderPage({request, children, props}) {
|
||||
|
||||
const currentChild = {
|
||||
__slothead,
|
||||
__render,
|
||||
setup: typeof setup === 'undefined' ? (passthrough) => passthrough : setup,
|
||||
layout: typeof layout === 'undefined' ? undefined : layout,
|
||||
layout: typeof __layout === 'undefined' ? undefined : __layout,
|
||||
content: typeof __content === 'undefined' ? undefined : __content,
|
||||
__render,
|
||||
};
|
||||
|
||||
// find all layouts, going up the layout chain.
|
||||
const fetch = (await import('node-fetch')).default;
|
||||
await currentChild.setup({request, fetch});
|
||||
const childBodyResult = await currentChild.__render(props, children);
|
||||
|
||||
// find layout, if one was given.
|
||||
if (currentChild.layout) {
|
||||
const layoutComponent = (await import('/_astro/layouts/' + layout.replace(/.*layouts\\//, "").replace(/\.astro$/, '.js')));
|
||||
const layoutComponent = (await import('/_astro/layouts/' + currentChild.layout.replace(/.*layouts\\//, "").replace(/\.astro$/, '.js')));
|
||||
return layoutComponent.__renderPage({
|
||||
request,
|
||||
children: [currentChild, ...children],
|
||||
props: {content: currentChild.content},
|
||||
children: [childBodyResult],
|
||||
});
|
||||
}
|
||||
|
||||
const isRoot = true;
|
||||
const merge = (await import('deepmerge')).default;
|
||||
const fetch = (await import('node-fetch')).default;
|
||||
|
||||
// call all children setup scripts, in order, and return.
|
||||
let mergedContext = {};
|
||||
for (const child of [currentChild, ...children]) {
|
||||
const childSetupResult = await child.setup({request, fetch, context: mergedContext});
|
||||
mergedContext = childSetupResult.context ? merge(mergedContext, childSetupResult.context) : mergedContext;
|
||||
}
|
||||
|
||||
Object.freeze(mergedContext);
|
||||
|
||||
let headResult;
|
||||
let bodyResult;
|
||||
for (const child of children.reverse()) {
|
||||
headResult = await child.__slothead([headResult], mergedContext);
|
||||
bodyResult = await child.__render(undefined, [bodyResult], mergedContext);
|
||||
}
|
||||
return h(Fragment, null, [
|
||||
h("head", null, currentChild.__slothead([headResult], mergedContext)),
|
||||
h("body", null, currentChild.__render(undefined, [bodyResult], mergedContext)),
|
||||
]);
|
||||
return childBodyResult;
|
||||
};\n`;
|
||||
} else {
|
||||
modJsx += `
|
||||
export async function __renderPage() { throw new Error("No <html> page element found!"); }\n`;
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
---
|
||||
export function setup() {
|
||||
return {
|
||||
props: {}
|
||||
}
|
||||
return {props: {}}
|
||||
}
|
||||
---
|
||||
|
||||
<astro:head>
|
||||
<!-- Head Stuff -->
|
||||
</astro:head>
|
||||
|
||||
<h1>Hello world!</h1>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
---
|
||||
export function setup() {
|
||||
return {
|
||||
props: {}
|
||||
}
|
||||
return {props: {}}
|
||||
}
|
||||
---
|
||||
|
||||
<astro:head>
|
||||
<!-- Head Stuff -->
|
||||
</astro:head>
|
||||
|
||||
<h1>Hello world!</h1>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
import Hello from '../components/Hello.jsx';
|
||||
---
|
||||
|
||||
<astro:head>
|
||||
<!-- Head Stuff -->
|
||||
</astro:head>
|
||||
|
||||
<h1>My page</h1>
|
||||
<Hello name="world" />
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<Hello name="world" />
|
||||
</body>
|
||||
</html>
|
|
@ -72,7 +72,7 @@ SnowpackDev('Can load every page', async () => {
|
|||
}
|
||||
const result = await runtime.load(pathname);
|
||||
if (result.statusCode === 500) {
|
||||
failed.push(result);
|
||||
failed.push({...result, pathname});
|
||||
continue;
|
||||
}
|
||||
assert.equal(result.statusCode, 200, `Loading ${pathname}`);
|
||||
|
|
Loading…
Reference in a new issue