feat: engine

This commit is contained in:
Thomas Allmer
2022-03-03 00:01:43 +01:00
parent c009801164
commit e17671c448
1027 changed files with 24036 additions and 11601 deletions

View File

@@ -1,4 +0,0 @@
node_modules/**
/docs/_assets
/docs/_includes
/docs/_data

View File

@@ -12,3 +12,7 @@ __output
__output-dev
docs/_merged*
*-mdjs-generated.js
/packages/engine/test-node/fixtures/06-error-handling/01-page-error/docs/index.rocket.js
/packages/engine/test-node/fixtures/03b-format-markdown/c01-md-in-js-to-md-html/md-in-js.js

6
.gitignore vendored
View File

@@ -1,6 +1,5 @@
## editors
/.idea
/.vscode
## system files
.DS_Store
@@ -28,9 +27,7 @@ stats.html
*.tsbuildinfo
## Rocket ignore files (need to be the full relative path to the folders)
docs/_merged_data/
docs/_merged_assets/
docs/_merged_includes/
*-mdjs-generated.js
_site
_site-dev
@@ -40,3 +37,4 @@ _merged_assets
_merged_includes
__output
__output-dev
docs_backup

2
.nvmrc
View File

@@ -1 +1 @@
v14
v16

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"dbaeumer.vscode-eslint"
]
}

34
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,34 @@
// A launch configuration that compiles the extension and then opens it inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Web Dev Server Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/packages/vscode-rocket"
],
"outFiles": [
"${workspaceFolder}/packages/vscode-rocket/out/**/*.js"
],
"preLaunchTask": "Compile vscode-rocket"
},
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
],
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
}
]
}

11
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"gitdoc.enabled": false,
"typescript.tsdk": "node_modules/typescript/lib",
"files.exclude": {
"**/*-mdjs-generated.js": false,
},
"search.exclude": {
"**/*-mdjs-generated.js": true,
"**/dist-types": true,
}
}

29
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,29 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Compile vscode-rocket",
"type": "npm",
"script": "compile",
"path": "packages/vscode-rocket/",
"group": "build",
"problemMatcher": [],
"detail": "tsc -p ./"
}
]
}

View File

@@ -38,7 +38,7 @@
**The modern web setup for static sites with a sprinkle of JavaScript!**
- **Meta Framework:** Build on top of giants like <a href="https://www.11ty.dev/">Eleventy</a>, <a href="https://rollupjs.org/">Rollup</a>, and <a href="https://www.modern-web.dev/">Modern Web</a>.
- **Meta Framework:** Build on top of giants like <a href="https://lit.dev/">Lit</a>, <a href="https://rollupjs.org/">Rollup</a> and <a href="https://www.modern-web.dev/">Modern Web</a>.
- **Powerful Default Template:** Provide content and you are ready to go.
- **Small:** No overblown tools or frontend frameworks, add JavaScript and/or Web Components only on pages where needed..
@@ -55,6 +55,16 @@ You can still tweak every detail of every underlying tool that gets used.
Rocket is part of the [Modern Web Family](https://twitter.com/modern_web_dev).
## Quick Start
```
mkdir test-rocket
cd test-rocket
npm init -y
npm i @rocket/cli@alpha @rocket/launch@alpha @11ty/eleventy-cache-assets typescript
npx rocket init
```
## 🤝 Contributing
We are always looking for contributors of all skill levels! If you're looking to ease your way into the project, try out a [good first issue](https://github.com/modernweb-dev/rocket/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).

39
TODO.md Normal file
View File

@@ -0,0 +1,39 @@
## Features
- ssr render can just be a string concat
- recursive rendering of lit / html / and markdown
- "import" markdown with frontmatter
- mdjs update to unified v10 AND go esm only (only cjs pkg we have now)
## Nice to have
- Add "menuExclude" => to actually exclude the menu item
## Bugs
- write to `_site-dev` instead of `_site` while using `rocket start`
- nested `recursive.data.js` do not overwrite the parent data
- support <!-- asdf --> in markdown
## Error Handling
- make error nice for parent page not found in index => auto generate page? 🤔
## Examples
- docs site, blog (simple), blog (complex), minimal
- add stackblitz/codesandbox examples => does not work because of `@parcel/watcher` https://github.com/parcel-bundler/watcher/issues/99
- Example: export variable and use it in rendering
- Example: fetch data from an api and display it
- Example: usage of image
## later
- support `@change` in markdown
- support "hey ${foo.map(f => `${f} + 1`)}"
- ENGINE: Rename "options.docsDir" to "options.inputDir"
## consider
- Replace magic "resolve:pkg/foo.css" with a directive `${resolve()}`?

44
config/rocket.config.js Normal file
View File

@@ -0,0 +1,44 @@
import { rocketLaunch } from '@rocket/launch';
// import { rocketBlog } from '@rocket/blog';
// import { rocketSearch } from '@rocket/search';
// import { absoluteBaseUrlNetlify } from '@rocket/core/helpers';
// import { adjustPluginOptions } from 'plugins-manager';
// import { mdjsSetupCode } from '@mdjs/core';
// TODO: preset needs to be updated to use the new plugin manager
// import { codeTabs } from 'rocket-preset-code-tabs';
// import { customElementsManifest } from 'rocket-preset-custom-elements-manifest';
/** @type {import('@rocket/cli/types/main').RocketCliOptions} */
export default {
absoluteBaseUrl: 'http://localhost:8080',
presets: [
rocketLaunch(),
// rocketBlog(),
// rocketSearch(),
// codeTabs({
// collections: {
// packageManagers: {
// npm: { label: 'NPM', iconHref: '/_merged_assets/_static/logos/npm.svg' },
// yarn: { label: 'Yarn', iconHref: '/_merged_assets/_static/logos/yarn.svg' },
// pnpm: { label: 'PNPM', iconHref: '/_merged_assets/_static/logos/pnpm.svg' },
// },
// },
// }),
// customElementsManifest(),
],
// eleventy(eleventyConfig) {
// eleventyConfig.addTransform('fix-noscript', content =>
// content
// .replace(/&#x26;#x3C;(link|style)/g, '<$1')
// .replace(/&#x26;(link|style)/g, '<$1')
// .replace(/&#x3C;(link|style)/g, '<$1'),
// );
// },
// serviceWorkerName: 'sw.js',
// pathPrefix: '/_site/',
// emptyOutputDir: false,
};

View File

@@ -1 +0,0 @@
*.docs.md

View File

@@ -1,4 +0,0 @@
---
layout: layout-404
permalink: 404.html
---

View File

@@ -1 +0,0 @@
<svg id="n" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#c12127;}.cls-2{fill:#fff;}</style></defs><title>n</title><path class="cls-1" d="M0,16V0H16V16ZM3,3V13H8V5h3v8h2V3Z"/><path class="cls-2" d="M3,3H13V13H11V5H8v8H3Z"/></svg>

Before

Width:  |  Height:  |  Size: 287 B

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="76.58987244897958 44 164.00775510204068 164" width="160.01" height="160"><defs><path d="M237.6 95L187.6 95L187.6 45L237.6 45L237.6 95Z" id="arNRoK435"></path><path d="M182.59 95L132.59 95L132.59 45L182.59 45L182.59 95Z" id="a3H2WU7Px"></path><path d="M127.59 95L77.59 95L77.59 45L127.59 45L127.59 95Z" id="b1DInM56vl"></path><path d="M237.6 150L187.6 150L187.6 100L237.6 100L237.6 150Z" id="a7LFlgQIwu"></path><path d="M182.59 150L132.59 150L132.59 100L182.59 100L182.59 150Z" id="amwLiZcuo"></path><path d="M182.59 205L132.59 205L132.59 155L182.59 155L182.59 205Z" id="f3Peu5RWan"></path><path d="M237.6 205L187.6 205L187.6 155L237.6 155L237.6 205Z" id="a6DXBfqPa"></path><path d="M127.59 205L77.59 205L77.59 155L127.59 155L127.59 205Z" id="c1GWSTH1z7"></path></defs><g><g><use xlink:href="#arNRoK435" opacity="1" fill="#f9ad00" fill-opacity="1"></use></g><g><use xlink:href="#a3H2WU7Px" opacity="1" fill="#f9ad00" fill-opacity="1"></use></g><g><use xlink:href="#b1DInM56vl" opacity="1" fill="#f9ad00" fill-opacity="1"></use></g><g><use xlink:href="#a7LFlgQIwu" opacity="1" fill="#f9ad00" fill-opacity="1"></use></g><g><use xlink:href="#amwLiZcuo" opacity="1" fill="#4e4e4e" fill-opacity="1"></use></g><g><use xlink:href="#f3Peu5RWan" opacity="1" fill="#4e4e4e" fill-opacity="1"></use></g><g><use xlink:href="#a6DXBfqPa" opacity="1" fill="#4e4e4e" fill-opacity="1"></use></g><g><use xlink:href="#c1GWSTH1z7" opacity="1" fill="#4e4e4e" fill-opacity="1"></use></g></g></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1 +0,0 @@
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 518 518"><style>.st0{fill:#2c8ebb}.st1{fill:#fff}</style><path class="st0" d="M259 0c143 0 259 116 259 259S402 518 259 518 0 402 0 259 116 0 259 0z"/><path class="st1" d="M435.2 337.5c-1.8-14.2-13.8-24-29.2-23.8-23 .3-42.3 12.2-55.1 20.1-5 3.1-9.3 5.4-13 7.1.8-11.6.1-26.8-5.9-43.5-7.3-20-17.1-32.3-24.1-39.4 8.1-11.8 19.2-29 24.4-55.6 4.5-22.7 3.1-58-7.2-77.8-2.1-4-5.6-6.9-10-8.1-1.8-.5-5.2-1.5-11.9.4C293.1 96 289.6 93.8 286.9 92c-5.6-3.6-12.2-4.4-18.4-2.1-8.3 3-15.4 11-22.1 25.2-1 2.1-1.9 4.1-2.7 6.1-12.7.9-32.7 5.5-49.6 23.8-2.1 2.3-6.2 4-10.5 5.6h.1c-8.8 3.1-12.8 10.3-17.7 23.3-6.8 18.2.2 36.1 7.1 47.7-9.4 8.4-21.9 21.8-28.5 37.5-8.2 19.4-9.1 38.4-8.8 48.7-7 7.4-17.8 21.3-19 36.9-1.6 21.8 6.3 36.6 9.8 42 1 1.6 2.1 2.9 3.3 4.2-.4 2.7-.5 5.6.1 8.6 1.3 7 5.7 12.7 12.4 16.3 13.2 7 31.6 10 45.8 2.9 5.1 5.4 14.4 10.6 31.3 10.6h1c4.3 0 58.9-2.9 74.8-6.8 7.1-1.7 12-4.7 15.2-7.4 10.2-3.2 38.4-12.8 65-30 18.8-12.2 25.3-14.8 39.3-18.2 13.6-3.3 22.1-15.7 20.4-29.4zm-23.8 14.7c-16 3.8-24.1 7.3-43.9 20.2-30.9 20-64.7 29.3-64.7 29.3s-2.8 4.2-10.9 6.1c-14 3.4-66.7 6.3-71.5 6.4-12.9.1-20.8-3.3-23-8.6-6.7-16 9.6-23 9.6-23s-3.6-2.2-5.7-4.2c-1.9-1.9-3.9-5.7-4.5-4.3-2.5 6.1-3.8 21-10.5 27.7-9.2 9.3-26.6 6.2-36.9.8-11.3-6 .8-20.1.8-20.1s-6.1 3.6-11-3.8c-4.4-6.8-8.5-18.4-7.4-32.7 1.2-16.3 19.4-32.1 19.4-32.1s-3.2-24.1 7.3-48.8c9.5-22.5 35.1-40.6 35.1-40.6s-21.5-23.8-13.5-45.2c5.2-14 7.3-13.9 9-14.5 6-2.3 11.8-4.8 16.1-9.5 21.5-23.2 48.9-18.8 48.9-18.8s13-39.5 25-31.8c3.7 2.4 17 32 17 32s14.2-8.3 15.8-5.2c8.6 16.7 9.6 48.6 5.8 68-6.4 32-22.4 49.2-28.8 60-1.5 2.5 17.2 10.4 29 43.1 10.9 29.9 1.2 55 2.9 57.8.3.5.4.7.4.7s12.5 1 37.6-14.5c13.4-8.3 29.3-17.6 47.4-17.8 17.5-.3 18.4 20.2 5.2 23.4z"/></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,10 +0,0 @@
html {
--demo-background-color: #eee;
--demo-color: #222;
}
html[theme="dark"] body {
background: #333;
--demo-background-color: #888;
--demo-color: #eee;
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,33 +0,0 @@
<svg fill="#e63946" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 511.998 511.998" xml:space="preserve">
<g>
<path d="M98.649,430.256c-46.365,28.67-71.17,30.939-78.916,23.51c-7.75-7.433-6.519-32.307,20.182-79.832
c24.953-44.412,65.374-96.693,113.818-147.211l-11.279-10.817C93.124,267.348,51.871,320.751,26.291,366.279
c-19.228,34.22-37.848,79.134-17.375,98.766c5.84,5.6,13.599,7.935,22.484,7.935c22.269,0,51.606-14.677,75.469-29.432
c44.416-27.464,96.044-70.919,145.373-122.362l-11.279-10.817C192.517,360.888,141.976,403.464,98.649,430.256z"/>
<rect x="238.112" y="272.64" transform="matrix(-0.7218 -0.6921 0.6921 -0.7218 237.9094 656.5383)" width="25.589" height="15.628"/>
<rect x="268.895" y="302.163" transform="matrix(-0.7218 -0.6921 0.6921 -0.7218 270.4774 728.6761)" width="25.589" height="15.628"/>
<rect x="232.827" y="268.929" transform="matrix(-0.7218 -0.6921 0.6921 -0.7218 297.4719 673.0591)" width="102.364" height="15.628"/>
<path d="M500.916,41.287c-7.769,1.59-76.412,16.062-93.897,34.294l-50.728,52.899l-114.703-3.629l-39.198,40.876l79.28,40.569
l-21.755,22.687l72.848,69.858l21.755-22.687l43.857,77.51l39.197-40.876l-8.433-114.451l50.727-52.899
c17.485-18.234,29.067-87.422,30.331-95.251l1.801-11.169L500.916,41.287z M228.209,161.383l19.842-20.692l93.688,2.964
l-48.775,50.864L228.209,161.383z M401.632,327.686l-35.822-63.308l48.776-50.865l6.886,93.482L401.632,327.686z
M332.298,276.743l-50.287-48.223L412.89,92.037l50.288,48.223L332.298,276.743z M473.009,128.036l-48.316-46.334
c14.54-8.427,44.787-17.217,68.076-22.632C488.336,82.567,480.82,113.155,473.009,128.036z"/>
<rect x="302.369" y="231.988" transform="matrix(-0.7218 -0.6921 0.6921 -0.7218 384.0262 633.9694)" width="34.12" height="15.628"/>
<rect x="411.311" y="127.35" transform="matrix(-0.6921 0.7218 -0.7218 -0.6921 807.9747 -74.331)" width="17.061" height="15.628"/>
<rect x="394.288" y="145.087" transform="matrix(-0.7218 -0.6921 0.6921 -0.7218 586.0206 542.7934)" width="15.628" height="17.06"/>
<rect x="376.571" y="163.565" transform="matrix(-0.7218 -0.6921 0.6921 -0.7218 542.7271 562.3462)" width="15.628" height="17.06"/>
<rect x="161.111" y="185.158" transform="matrix(0.7071 0.7071 -0.7071 0.7071 192.1943 -60.3323)" width="15.628" height="33.35"/>
<rect x="184.683" y="172.695" transform="matrix(0.707 0.7072 -0.7072 0.707 182.4625 -83.9076)" width="15.628" height="11.118"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -1,51 +0,0 @@
:not(rocket-navigation):not(:defined) {
opacity: 0;
}
rocket-navigation,
header {
font-family: 'Montserrat', sans-serif;
}
code-tabs[collection="package-managers"] {
--code-tabs-icon-height: 18px;
}
.call-to-action {
background: var(--button-one) !important;
text-shadow: none !important;
border-radius: 5px !important;
padding-top: 15px !important;
padding-bottom: 15px !important;
border: none !important;
}
.call-to-action:hover,
.call-to-action:focus,
.call-to-action:active {
background: var(--button-one-hover) !important;
}
.call-to-action:nth-child(2) {
background: var(--button-two) !important;
}
.call-to-action:nth-child(2):hover,
.call-to-action:nth-child(2):focus,
.call-to-action:nth-child(2):active {
background: var(--button-two-hover) !important;
}
body[layout^='layout-home'] .markdown-body .call-to-action:nth-of-type(2) {
--primary-color: #222;
--primary-color-lighter: #333;
--primary-color-darker: #000;
}
@media screen and (min-width: 1024px) {
body[layout='layout-home-background'] .page-background {
top: -210px;
right: -463px;
transform: rotate(45deg);
}
}

View File

@@ -1,141 +0,0 @@
html {
--button-one-hover: #436eff;
--button-one: #2758ff;
--button-two-hover: #444;
--button-two: black;
--contrast-color-dark: #1d3557;
--contrast-color-light: #fff;
--footer-background: rgba(0, 0, 0, 0.02);
--header-color: white;
--markdown-link-color: #2758ff;
--markdown-syntax-background-color: #f9f9f9;
--markdown-table-row-odd-background-color: #efefef;
--owc-active-color: #2758ff;
--owc-hover-color: #436eff;
--page-background: white;
--primary-color-accent: #cee5f6;
--primary-color-darker: #1a5285;
--primary-color-lighter: #449ad7;
--primary-color: rgb(44, 62, 80);
--primary-lines-color: #ccc;
--primary-text-color: #2c3e50;
--primary-text-inverse-color: #eee;
--switch-unselected-color: #808080;
--switch-selected-color: #42b983;
}
@media (prefers-color-scheme: dark) {
html {
--header-color: #2f3136;
--footer-background: rgba(255, 255, 255, 0.1);
--page-background: #36393e;
--text-color: #eee;
--primary-text-color: #eee;
--primary-color: white;
--primary-color-lighter: #449ad7;
--primary-color-darker: #1a5285;
--primary-color-accent: #cee5f6;
--contrast-color-light: #fff;
--contrast-color-dark: #1d3557;
--primary-lines-color: #333;
--owc-active-color: #41ffb0;
--owc-hover-color: #6dffc2;
--button-one: #9b03fe;
--button-one-hover: #a724ff;
--button-two: black;
--button-two-hover: rgb(36, 36, 36);
--rocket-search-background-color: #4a4d52;
--rocket-search-highlight-color: #41ffb0;
--rocket-search-hover-background-color: #6b717a;
--rocket-search-fill-color: #fff;
--primary-text-inverse-color: #2c3e50;
--switch-unselected-color: #808080;
--switch-selected-color: #42b983;
/* Markdown */
--markdown-octicon-link: var(--primary-text-color);
--markdown-link-color: #41ffb0;
--markdown-divider-color: #e1e4e8;
--markdown-blockquote-border-color: #dfe2e5;
--markdown-blockquote-color: #90aac7;
--markdown-kbd-background-color: #fafbfc;
--markdown-kbd-border-color: #c6cbd1;
--markdown-kbd-border-bottom-color: #959da5;
--markdown-kbd-color: #444d56;
--markdown-heading-color-6: #6a737d;
--markdown-table-background-color: var(--markdown-syntax-background-color);
--markdown-table-row-odd-background-color: var(--markdown-kbd-color);
--markdown-table-border-color: transparent;
--markdown-code-background-color: rgba(27, 31, 35, 0.05);
--markdown-pre-background-color: rgb(49, 49, 49);
/* syntax */
--markdown-syntax-color: #f8f8f2;
--markdown-syntax-background-color: #2e3440;
--markdown-syntax-atrule-color: #88c0d0;
--markdown-syntax-attr-name-color: #a3be8c;
--markdown-syntax-attr-value-color: #88c0d0;
--markdown-syntax-builtin-color: #a3be8c;
--markdown-syntax-boolean-color: #81a1c1;
--markdown-syntax-class-name-color: #88c0d0;
--markdown-syntax-constant-color: #81a1c1;
--markdown-syntax-char-color: #a3be8c;
--markdown-syntax-deleted-color: #81a1c1;
--markdown-syntax-entity-color: #81a1c1;
--markdown-syntax-function-color: #88c0d0;
--markdown-syntax-inserted-color: #a3be8c;
--markdown-syntax-keyword-color: #81a1c1;
--markdown-syntax-number-color: #b48ead;
--markdown-syntax-operator-color: #81a1c1;
--markdown-syntax-property-color: #81a1c1;
--markdown-syntax-punctuation-color: #81a1c1;
--markdown-syntax-regex-color: #81a1c1;
--markdown-syntax-important-color: #81a1c1;
--markdown-syntax-selector-color: #a3be8c;
--markdown-syntax-symbol-color: #81a1c1;
--markdown-syntax-string-color: #a3be8c;
--markdown-syntax-tag-color: #81a1c1;
--markdown-syntax-url-color: #81a1c1;
--markdown-syntax-variable-color: #81a1c1;
--markdown-syntax-hotkey-selector-color: #d73a49;
--markdown-syntax-keyword-color: #22863a;
--markdown-syntax-background-color: rgb(27, 29, 35);
--markdown-syntax-atrule-color: rgb(198, 120, 221);
--markdown-syntax-attr-name-color: rgb(198, 120, 221);
--markdown-syntax-boolean-color: rgb(209, 154, 102);
--markdown-syntax-class-name-color: rgb(97, 175, 239);
--markdown-syntax-constant-color: rgb(220, 220, 170);
--markdown-syntax-entity-color: rgb(220, 220, 170);
--markdown-syntax-function-color: rgb(97, 175, 239);
--markdown-syntax-inserted-color: rgb(220, 220, 170);
--markdown-syntax-keyword-color: rgb(198, 120, 221);
--markdown-syntax-number-color: rgb(220, 220, 170);
--markdown-syntax-operator-color: rgb(220, 220, 170);
--markdown-syntax-property-color: rgb(220, 220, 170);
--markdown-syntax-punctuation-color: white;
--markdown-syntax-regex-color: rgb(209, 154, 102);
--markdown-syntax-selector-color: rgb(86, 156, 214);
--markdown-syntax-symbol-color: rgb(220, 220, 170);
--markdown-syntax-tag-color: rgb(86, 156, 214);
--markdown-syntax-url-color: rgb(220, 220, 170);
--markdown-syntax-variable-color: rgb(220, 220, 170);
}
.string {
color: rgb(152, 195, 121);
}
.comment {
color: #7d7d7d;
}
.language-css {
--markdown-syntax-string-color: #81a1c1;
}
}
body[layout='home'] .markdown-body .call-to-action:nth-of-type(2) {
--primary-color: #222;
--primary-color-lighter: #333;
--primary-color-darker: #000;
}

View File

@@ -1,29 +0,0 @@
{
"name": "Rocket",
"short_name": "rocket",
"theme_color": "#e63946",
"background_color": "#1d3557",
"display": "standalone",
"orientation": "portrait",
"Scope": "/",
"start_url": "/",
"icons": [
{
"src": "../_merged_assets/_static/icons/android-chrome-192x192.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "../_merged_assets/_static/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "../_merged_assets/_static/icons/maskable-icon.jpg",
"sizes": "1024x1024",
"type": "image/jpg",
"purpose": "any maskable"
}
],
"splash_pages": null
}

View File

@@ -1,45 +0,0 @@
[
{
"name": "Discover",
"children": [
{
"text": "Blog",
"href": "/blog/"
},
{
"text": "Help and Feedback",
"href": "https://github.com/modernweb-dev/rocket/issues"
}
]
},
{
"name": "Follow",
"children": [
{
"text": "GitHub",
"href": "https://github.com/modernweb-dev/rocket"
},
{
"text": "Twitter",
"href": "https://twitter.com/modern_web_dev"
},
{
"text": "Slack",
"href": "/about/slack/"
}
]
},
{
"name": "Support",
"children": [
{
"text": "Sponsor",
"href": "/about/sponsor/"
},
{
"text": "Contribute",
"href": "https://github.com/modernweb-dev/rocket/blob/main/CONTRIBUTING.md"
}
]
}
]

View File

@@ -1,4 +0,0 @@
{
"homeLayout": "background",
"newsletter": false
}

View File

@@ -1,28 +0,0 @@
module.exports = async function () {
return {
dir: 'ltr',
lang: 'en',
name: 'Rocket',
description: 'Rocket is the way to build fast static websites with a sprinkle of JavaScript',
socialLinks: [
{
name: 'GitHub',
url: 'https://github.com/modernweb-dev/rocket',
},
{
name: 'Slack',
url:
'https://join.slack.com/t/lit-and-friends/shared_invite/zt-llwznvsy-LZwT13R66gOgnrg12PUGqw',
},
],
gitSiteUrl: 'https://github.com/modernweb-dev/rocket',
gitBranch: 'main',
helpUrl: 'https://github.com/modernweb-dev/rocket/issues',
logoAlt: 'Rocket Logo',
iconColorMaskIcon: '#3f93ce',
iconColorMsapplicationTileColor: '#1d3557',
iconColorThemeColor: '#1d3557',
socialMediaImage: '/_assets/social-media-image.jpg',
// analytics: 'UA-131782693-2', // modern web key
};
};

View File

@@ -1 +0,0 @@
<link rel="stylesheet" href="{{ '/_assets/theme.css' | asset | url }}">

View File

@@ -1,3 +0,0 @@
<meta name="twitter:creator" content="@modern_web_dev" />
<link rel="stylesheet" href="{{ '/_assets/body.css' | asset | url }}" mdjs-use>

View File

@@ -1,5 +0,0 @@
# Slack
You can also find us on the Polymer Slack in the [#open-wc](https://polymer.slack.com/archives/CE6D9DN05) channel.
You can join the Polymer Slack by visiting [https://www.polymer-project.org/slack-invite](https://www.polymer-project.org/slack-invite).

View File

@@ -1,9 +0,0 @@
---
title: Sponsor
eleventyNavigation:
key: Sponsor
---
We currently can only accept sponsoring in the form of services or contributions.
If you are interested in monetary sponsoring please [let us know](mailto:hello@modern-web.dev).

View File

@@ -1,15 +0,0 @@
---
layout: layout-blog-overview
eleventyNavigation:
key: Blog
order: 30
pagination:
data: collections.blog
size: 10
reverse: true
alias: posts
---
# Rocket Blog
Discover articles from the core team and contributors about Rocket, tips and tricks included!

View File

@@ -1,12 +0,0 @@
const { createSocialImage } = require('@rocket/cli');
module.exports = async function () {
const socialMediaImage = await createSocialImage({
title: 'Introducing',
subTitle: 'check-html-links',
footer: 'Rocket Blog',
});
return {
socialMediaImage,
};
};

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#1d3557</TileColor>
</tile>
</msapplication>
</browserconfig>

View File

@@ -1,40 +0,0 @@
# Configuration >> Computed Config || 20
If you want to add data that depends on other data then you can do it via [Eleventy's computed data](https://www.11ty.dev/docs/data-computed/).
Rocket exposes it via `setupEleventyComputedConfig`.
## Set Your Own Data
Let's say you want to add a `Welcome to the contact page` everywhere. (A filter might be a better choice, but it's a good example of the concept.)
👉 `rocket.config.js` (or your theme config file)
<!-- prettier-ignore-start -->
```js copy
import { addPlugin } from 'plugins-manager';
/** @type {import('@rocket/cli').RocketCliOptions} */
export default ({
setupEleventyComputedConfig: [
addPlugin({ name: 'greeting', plugin: data => `Welcome to the ${data.title} page.` }),
],
});
```
<!-- prettier-ignore-end -->
Now you can use {% raw %}{{ greeting }}{% endraw %} everywhere,
and it will be correctly replaced with a Welcome and the page title.
## Default Available Configs
```js
[
{ name: 'titleMeta', plugin: titleMetaPlugin },
{ name: 'title', plugin: titlePlugin },
{ name: 'eleventyNavigation', plugin: eleventyNavigationPlugin },
{ name: 'section', plugin: sectionPlugin },
{ name: 'socialMediaImage', plugin: socialMediaImagePlugin },
{ name: 'templateBlocks', plugin: templateBlocksPlugin, options: rocketConfig },
];
```

View File

@@ -1 +0,0 @@
# Configuration ||10

View File

@@ -1,166 +0,0 @@
# Configuration >> Overview || 10
The configuration file is `rocket.config.js` or `rocket.config.mjs`.
The config files consist of the following parts:
<!-- prettier-ignore-start -->
```js
import { rocketLaunch } from '@rocket/launch';
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
presets: [rocketLaunch()],
emptyOutputDir: true,
pathPrefix: 'subfolder-only-for-build',
});
```
<!-- prettier-ignore-end -->
Rocket is primarily build around plugins for each of its systems.
New plugins can be added and all default plugins can be adjusted or even removed by using the following functions.
<!-- prettier-ignore-start -->
```js
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
// add remark/unified plugin to the Markdown processing (e.g. enable special code blocks)
setupUnifiedPlugins: [],
// add a rollup plugins to the web dev server (will be wrapped with @web/dev-server-rollup) AND the rollup build (e.g. enable json importing)
setupDevAndBuildPlugins: [],
// add a plugin to the web dev server (will not be wrapped) (e.g. esbuild for TypeScript)
setupDevPlugins: [],
// add a plugin to the rollup build (e.g. optimization steps)
setupBuildPlugins: [],
// add a plugin to Eleventy (e.g. a filter packs)
setupEleventyPlugins: [],
// add a computedConfig to Eleventy (e.g. site wide default variables like socialMediaImage)
setupEleventyComputedConfig: [],
// add a plugin to the cli (e.g. a new command like "rocket my-command")
setupCliPlugins: [],
});
```
<!-- prettier-ignore-end -->
## Adding Rollup Plugins
For some projects you might want to enable non-standard behaviors like importing JSON files as JavaScript.
```js
import data from './data.json';
```
You can accomplish this with Rollup and dev server plugins. Make sure to add both the dev-server plugin as well as the Rollup plugin, so that the behaviors is the same during development as it is in the production build.
For these cases you can use `setupDevAndBuildPlugins`, which will automatically add the plugin for you to both Rollup and dev-server:
<!-- prettier-ignore-start -->
```js
import json from '@rollup/plugin-json';
import { addPlugin } from 'plugins-manager';
/** @type {import('@rocket/cli').RocketCliOptions} */
export default ({
setupDevAndBuildPlugins: [
addPlugin({ name: 'json', plugin: json, location: 'top', options: { my: 'settings' } }),
],
});
```
<!-- prettier-ignore-end -->
This will add the Rollup plugin `json` with the id `json` at the top of the plugin list of Rollup and the dev server. It needs to be at the top so further plugins down the line can work with JSON imports.
For the Dev Server the plugins are automatically wrapped by `@web/dev-server-rollup`. Note that [not all Rollup plugins](https://modern-web.dev/docs/dev-server/plugins/rollup/#compatibility-with-rollup-plugins) will work with the dev-server.
## Modifying Options of Plugins
All plugins which are either default or are added via a preset can still be adjusted by using `adjustPluginOptions`.
<!-- prettier-ignore-start -->
```js
import { adjustPluginOptions } from 'plugins-manager';
/** @type {import('@rocket/cli').RocketCliOptions} */
export default ({
setupDevAndBuildPlugins: [adjustPluginOptions('json', { my: 'overwrite settings' })],
});
```
<!-- prettier-ignore-end -->
## Lifecycle
You can hook into the rocket lifecycle by specifying a function for `before11ty`. This function runs before 11ty calls it's write method. If it is an async function, Rocket will await it's promise.
<!-- prettier-ignore-start -->
```js
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
async before11ty() {
await copyDataFiles();
},
});
```
<!-- prettier-ignore-end -->
## Advanced
Sometimes you need even more control over specific settings.
### Rollup
For example if you wanna add an `acron` plugin to rollup
<!-- prettier-ignore-start -->
```js
import { importAssertions } from 'acorn-import-assertions';
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
rollup: config => ({
...config,
acornInjectPlugins: [importAssertions],
}),
});
```
<!-- prettier-ignore-end -->
### Eleventy
For example to add custom filter you can access the eleventy config directly
<!-- prettier-ignore-start -->
```js
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
eleventy: eleventyConfig => {
eleventyConfig.addFilter('value', value => `prefix${value}`);
},
});
```
<!-- prettier-ignore-end -->
You even have access to the full rocketConfig if you for example want to create filters that behave differently during start/build.
<!-- prettier-ignore-start -->
```js
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
eleventy: (config, rocketConfig) => {
config.addFilter('conditional-resolve', value => {
if (rocketConfig.command === 'build') {
return `build:${value}`;
}
if (rocketConfig.command === 'start') {
return `start:${value}`;
}
});
},
});
```
<!-- prettier-ignore-end -->

View File

@@ -1 +0,0 @@
# Eleventy Plugins ||40

View File

@@ -1,94 +0,0 @@
# Eleventy Plugins >> Markdown JavaScript (mdjs)
Use mdjs in your Eleventy site.
## Setup
```shell
npm install @rocket/eleventy-plugin-mdjs
```
Create an Eleventy config file `.eleventy.js`
```js
const pluginMdjs = require('@rocket/eleventy-plugin-mdjs');
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(pluginMdjs);
};
```
## Configure a unified or remark Plugin with mdjs
By providing a `setupUnifiedPlugins` function as an option to `eleventy-plugin-mdjs` you can set options for all unified/remark plugins.
We do use [plugins-manager](../tools/plugins-manager.md).
This example adds a CSS class to the `htmlHeading` plugin so heading links can be selected in CSS.
```js
const pluginMdjs = require('@rocket/eleventy-plugin-mdjs');
const { adjustPluginOptions } = require('plugins-manager');
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(pluginMdjs, {
setupUnifiedPlugins: [
adjustPluginOptions('htmlHeading', {
properties: {
className: ['anchor'],
},
}),
],
});
};
```
## Add a unified or remark Plugin
The order of plugins is important in unified as each plugin processes the content and passes on its result.
Some plugins do work with the Markdown AST and some with the rehype (e.g. HTML) AST. In order to get access to the correct AST the plugin needs to be in a specific location in the processing order.
Examples on how to insert a plugin right after creating the Markdown AST.
```js
const pluginMdjs = require('@rocket/eleventy-plugin-mdjs');
const { addPlugin } = require('plugins-manager');
const { myRemarkPlugin } = require('./my-remark-plugin.js');
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(pluginMdjs, {
setupUnifiedPlugins: [
addPlugin({ name: 'my-remark-plugin', plugin: myRemarkPlugin, location: 'markdown' }),
],
});
};
```
Examples on how to insert a plugin right after creating the rehype AST.
```js
const pluginMdjs = require('@rocket/eleventy-plugin-mdjs');
const { addPlugin } = require('plugins-manager');
const { myRehypePlugin } = require('./my-rehype-plugin.js');
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(pluginMdjs, {
setupUnifiedPlugins: [
addPlugin({ name: 'my-rehype-plugin', plugin: myRehypePlugin, location: 'remark2rehype' }),
],
});
};
```
You can also add both
```js
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(pluginMdjs, {
setupUnifiedPlugins: [
addPlugin({ name: 'my-remark-plugin', plugin: myRemarkPlugin, location: 'markdown' }),
addPlugin({ name: 'my-rehype-plugin', plugin: myRehypePlugin, location: 'remark2rehype' }),
],
});
};
```

View File

@@ -1 +0,0 @@
# Markdown JavaScript ||30

View File

@@ -1,36 +0,0 @@
# Presets >> Blog || 40
Enable writing blog posts within your Rocket site.
## Installation
<code-tabs collection="package-managers" default-tab="npm" align="end">
```bash tab npm
npm i @rocket/blog
```
```bash tab yarn
yarn add @rocket/blog
```
```bash tab pnpm
pnpm add @rocket/blog
```
</code-tabs>
## Usage
👉 `rocket.config.js`
<!-- prettier-ignore-start -->
```js
import { rocketBlog } from '@rocket/blog';
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
presets: [rocketBlog()],
});
```
<!-- prettier-ignore-end -->

View File

@@ -1,5 +0,0 @@
---
excludeFromSearch: true
---
# Presets ||20

View File

@@ -1,102 +0,0 @@
# Presets >> Joining Blocks || 10
The template system allows for a very granular control of how individual parts will be merged, overwritten or reorderd.
As a preset you may want to add this to your layout.
{% raw %}
```jinja2
<footer id="main-footer">
{% for blockName, blockPath in _joiningBlocks.footer %}
{% include blockPath %}
{% endfor %}
</footer>
```
{% endraw %}
This will now render all templates within `_includes/_joiningBlocks/footer/*`.
## Adding content without overriding
Let's assume we have a preset with the following files
👉 `_includes/_joiningBlocks/footer/10-first.njk`
```html
<p>first</p>
```
👉 `_includes/_joiningBlocks/footer/20-second.njk`
```html
<p>second</p>
```
And it produces this in your website
```html
<footer>
<p>first</p>
<p>second</p>
</footer>
```
Now we can add a file which will insert content without needing to overwrite any of the preset file.
👉 `docs/_includes/_joiningBlocks/footer/15-in-between.njk`
```html
<p>in-between</p>
```
the final output will be
```html
<footer>
<p>first</p>
<p>in-between</p>
<p>second</p>
</footer>
```
## Overriding Content
Now if you want to overwrite you can use the same filename.
👉 `docs/_includes/_joiningBlocks/footer/10-first.njk`
```html
<p>updated first</p>
```
the final output will be
```html
<footer>
<p>updated first</p>
<p>second</p>
</footer>
```
## Reordering and Overriding
Sometimes you wanna reorder when you overwrite as well
👉 `docs/_includes/_joiningBlocks/footer/30-first.njk`
```html
<p>first</p>
```
the final output will be
```html
<footer>
<p>second</p>
<p>first</p>
</footer>
```
Note: Reordering always requires you to overwrite as well.

View File

@@ -1,7 +0,0 @@
---
layout: layout-api
package: '@rocket/launch'
module: inline-notification/index.js
---
# Presets >> Launch >> Custom Elements || 20

View File

@@ -1,3 +0,0 @@
# Presets >> Launch || 20
- [Preset](./preset/)

View File

@@ -1,9 +0,0 @@
---
layout: layout-api
package: '@rocket/search'
modules:
- src/RocketSearch.js
- src/RocketSearchCombobox.js
---
# Presets >> Search >> Custom Elements || 20

View File

@@ -1,3 +0,0 @@
# Presets >> Search || 10
- [Preset](./preset/)

View File

@@ -1,36 +0,0 @@
# Presets >> Search >> Preset || 10
Add a search for all your static content.
## Installation
<code-tabs collection="package-managers" default-tab="npm" align="end">
```bash tab npm
npm i @rocket/search
```
```bash tab yarn
yarn add @rocket/search
```
```bash tab pnpm
pnpm add @rocket/search
```
</code-tabs>
## Usage
👉 `rocket.config.js`
<!-- prettier-ignore-start -->
```js
import { rocketSearch } from '@rocket/search';
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
presets: [rocketSearch()],
});
```
<!-- prettier-ignore-end -->

View File

@@ -1 +0,0 @@
# Tools ||50

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,38 +0,0 @@
# Configuration >> Getting Started ||10
The main config file is `rocket.config.js` or `rocket.config.mjs`.
It typically looks something like this
```js
import { rocketLaunch } from '@rocket/launch';
import { rocketBlog } from '@rocket/blog';
import { rocketSearch } from '@rocket/search';
import { absoluteBaseUrlNetlify } from '@rocket/core/helpers';
export default /** @type {Partial<import('@rocket/cli').RocketCliOptions>} */ ({
presets: [rocketLaunch(), rocketBlog(), rocketSearch()],
absoluteBaseUrl: absoluteBaseUrlNetlify('http://localhost:8080'),
});
```
The Plugins Manager helps you register and execute your plugins across the various Rocket components - Rollup, Web Dev Server, Eleventy, and Markdown. It replaces the specific registration/execution call in a given plugin system by an intent to use that plugin.
## Adding Remark/Unified Plugins
If you want to add a plugin to the Markdown processing you can use `setupUnifiedPlugins`.
<!-- prettier-ignore-start -->
```js
import emoji from 'remark-emoji';
import { addPlugin } from 'plugins-manager';
/** @type {Partial<import('@rocket/cli').RocketCliOptions>} */
export default ({
setupUnifiedPlugins: [addPlugin({ location: 'markdown', name: 'emoji', plugin: emoji })],
});
```
<!-- prettier-ignore-end -->
For plugins that should handle the Markdown <abbr title="Abstract Syntax Tree">AST</abbr> you should use `addPlugin({ location: 'markdown', name: 'my-plugin', plugin: MyPlugin})`. <br>
While for the rehype AST you should use `addPlugin({ location: 'remark2rehype', name: 'my-plugin', plugin: MyPlugin})`.

View File

@@ -1 +0,0 @@
# Configuration ||30

View File

@@ -1,85 +0,0 @@
# First Pages >> Adding Pages ||12
<inline-notification type="warning">
You can do this whole part of the tutorial in a couple minutes. It's almost _**too**_ fast.
It can help to examine each new page and menu carefully, to come to terms with the implicit navigation created by your addition of new content, at least the first couple of times.
</inline-notification>
## Add a Section
In most cases you will have multiple sections in your website and each of those sections will come with its own sidebar navigation.
To create a section you need to create a folder with an `index.md`.
```bash
mkdir docs/guides
```
👉 `docs/guides/index.md`
```md
# Guides
You can read all about...
```
Observe that this creates a section named "Guides" at the top menu bar, and a page with the same title.
<inline-notification type="tip">
Don't worry if this isn't how you would have styled or placed your menu bar or sidebar navigation, we'll get to customization of the default preset later in the tutorials.
</inline-notification>
> How many sections should I add?
It might be more practical to stay below 5 sections.
## Adding a Category
Often each section will have multiple categories.
To create a category you need to create a folder with an `index.md`.
```bash
mkdir docs/guides/first-pages/
```
👉 `docs/guides/first-pages/index.md`
```md
# First Pages
```
## Adding a Page to a Category
👉 `docs/guides/first-pages/getting-started.md`
```md
# First Pages >> Getting Started
This is how you get started.
```
## Headings as Anchor and Menu Items
_**Within**_ any page, you can still add links to your navigation!
Note that Markdown text prefixed with one or two # signs also becomes an anchor in the page and a link in the sidebar navigation when the page is open.
```md
## Headings as Anchor and Menu Items
_**Within**_ any page, you can still add links to your navigation!
```
```js script
import '@rocket/launch/inline-notification/inline-notification.js';
```
## Example as a Reference
If implicit navigation, derived from content, is a bit too much to grasp in one sitting, feel free to examine the **docs** folder in [the rocket codebase behind the pages you are reading](https://github.com/modernweb-dev/rocket) for more examples.

View File

@@ -1,188 +0,0 @@
# First Pages >> Getting Started ||10
Rocket has the following prerequisites:
- [Node 14+](https://nodejs.org/en/)
Make sure they are installed before proceeding.
## Setup
The fastest way to get started is by using an existing preset like the launch preset.
### Step 1. Initialize the Project Package
Start by creating an empty folder for your project
```bash copy
mkdir my-project
cd my-project
```
Then initialize a package.json file
<code-tabs collection="package-managers" default-tab="npm" align="end">
```bash tab npm
npm init -y
```
```bash tab yarn
yarn init -y
```
```bash tab pnpm
pnpm init -y
```
</code-tabs>
### Step 2. Install dependencies
<code-tabs collection="package-managers" default-tab="npm" align="end">
```bash tab npm
npm install --save-dev @rocket/cli @rocket/launch
```
```bash tab yarn
yarn add -D @rocket/cli @rocket/launch
```
```bash tab pnpm
pnpm add -D @rocket/cli @rocket/launch
```
</code-tabs>
### Step 3. Bootstrap the project
<code-tabs collection="package-managers" default-tab="npm" align="end">
```bash tab npm
npx rocket bootstrap
```
```bash tab yarn
yarn rocket bootstrap
```
```bash tab pnpm
pnpx rocket bootstrap
```
</code-tabs>
The `bootstrap` command creates four files in your repo:
- `.gitignore` containing rocket's build artifacts
- `rocket.config.js` containing a minimal rocket config
- `docs/.eleventyignore` required to allow you to [override templates](/guides/presets/overriding/)
- `docs/index.md` your first page
It also set the package `type` to `"module"` and adds a `start` and `docs` package scripts.
<inline-notification type="warning">
If you don't want to use the `module` package type, make sure to rename the generated config file to `rocket.config.mjs`.
</inline-notification>
<details><summary>Default Files Contents</summary>
<code-tabs default-tab="rocket.config.js">
<!-- prettier-ignore-start -->
```js tab rocket.config.js
import { rocketLaunch } from '@rocket/launch';
/** @type {import('rocket/cli').RocketCliConfig} */
export default ({
presets: [rocketLaunch()],
});
```
<!-- prettier-ignore-end -->
```md tab docs/index.md
# Welcome to Your Rocket Site
Add your markdown content here.
```
<!-- prettier-ignore-start -->
```html tab docs/.eleventyignore
_assets
_includes
_data
```
```html tab .gitignore
## Rocket ignore files (need to be the full relative path to the folders)
docs/_merged_data/
docs/_merged_assets/
docs/_merged_includes/
```
<!-- prettier-ignore-end -->
</code-tabs>
</details>
## Add your First Page
Bootstrap created the file `docs/index.md`. Open it in your editor and change it to suit your needs.
<small>NOTE: This tutorial assumes you are familiar with Markdown, for page authoring.</small>
```md
# Welcome to Your Rocket Site
Add your markdown content here.
```
Please note that the heading - text prefixed with `#` or `##` - is not optional for each page in this tutorial. Everything below that first line is optional Markdown text.
## Startup
Now you can launch your site locally with
<code-tabs collection="package-managers" default-tab="npm" align="end">
```bash tab npm
npm start
```
```bash tab yarn
yarn start
```
```bash tab pnpm
pnpx start
```
</code-tabs>
## Taking Inventory Before Adding Pages:
We're about to add both content and navigation at the same time.
It can be helpful to take an inventory, before we start, to separate basic setup from the creation of content and navigation.
- We built the project with basic npm commands
- Added a couple required files manually
- Adjusted package.json
- **docs/index.md** to seed the content
- Launches with `npm start`
That's all it takes to get a new super-fast and powerful site, complete with a service worker, default styling, navigation, and ready to deploy as a plain old static files.
## Next Steps
- [Adding Pages](../adding-pages/)
- [Using Presets](../../presets/getting-started/)
```js script
import '@rocket/launch/inline-notification/inline-notification.js';
```

View File

@@ -1 +0,0 @@
# First Pages ||10

View File

@@ -1,29 +0,0 @@
# First Pages >> Layouts ||60
The following templates are always available:
- `layout-raw` No html or any wrapping (use it for xml, json, ... outputs)
- `layout-default` For content
- `layout-index` Extends content and adds an "Open Navigation" button for mobile
Layout Default has the following Joining Blocks:
- `head` For the html `<head>`
- `header` Within the top `<header>`
- `content` Html within the main content section
- `footer` Within to bottom `<footer>`
- `bottom` Add the end of the body
## Launch Preset
On top of the above it adds the following templates
- `layout-404` A space not found page
- `layout-home` Frontpage with center logo below text
- `layout-home-background` Frontpage with left text and background image on the right
- `layout-sidebar` Left sidebar, right content
- `layout-index` Extends layout-sidebar
And the following changes
- Sets `layout-sidebar` as the default layout

View File

@@ -1,7 +0,0 @@
# First Pages >> Linking ||20
Standard Markdown applies. You can link like this:
```md
[visible label](./path/to/other-file.md)
```

View File

@@ -1,57 +0,0 @@
# First Pages >> Managing sidebar || 30
The sidebar will show all the content of the current section.
## Nesting Pages
You nest by adding `>>` between parent and child.
## Sorting Pages
You can sort by adding `||xx` at the end.
e.g.
```
# Second || 20
# First || 10
```
Will be ordered as `First`, `Second`,
## How it works
Internally `# Foo >> Bar >> Baz ||20` gets converted to.
```yml
---
title: Bar: Baz
eleventyNavigation:
key: Foo >> Bar >> Baz
parent: Foo >> Bar
order: 20
---
```
<!--
You can also look at this live playground:
```js story
import { html } from '@mdjs/mdjs-preview';
export const headlineConverter = () => html`
<p>
<strong style="color: red;">TODO: </strong>I will become a web component that has an input and
out that live udpates
</p>
`;
```
-->
How it then works is very similar to https://www.11ty.dev/docs/plugins/navigation/
## Sidebar redirects
By default, the sidebar nav redirects clicks on category headings to the first child page in that category.
To disable those redirects, override `_includes/_joiningBlocks/_layoutSidebar/sidebar/20-navigation.njk` and add the `no-redirects` attribute to the `<rocket-navigation>` element.

View File

@@ -1,5 +0,0 @@
# First Pages >> URLs ||50
URLs will be represented by the folder structure.
You can use front matter with a [permalink](https://www.11ty.dev/docs/permalinks/) to override.

View File

@@ -1,49 +0,0 @@
# First Pages >> Use JavaScript || 40
If you would like to add JavaScript to a page, you can do it inline using the `script` markdown directive. The script you write runs on the page as a module.
<!-- prettier-ignore-start -->
~~~markdown
```js script
const message = 'Hello, World!';
console.log(message);
```
~~~
<!-- prettier-ignore-end -->
Adding the above will log `Hello, World!` to the console without adding a global `message` variable.
This can be useful for importing web components and using them in Markdown. Imagine you had some `magic-reveal` element that you wanted to use on a page:
<!-- prettier-ignore-start -->
~~~markdown
```js script
import 'magic-reveal/magic-reveal.js';
```
<magic-reveal>
This text will get magically revealed.
I can **still** use Markdown as long as there is an empty line
between the opening/closing tags and my text.
</magic-reveal>
~~~
<!-- prettier-ignore-end -->
## Component Story Format
You can also add storybook-style CSF (v2 only) stories to a page using `js story` or `js preview-story`, just make sure to import `html` from `@mdjs/mdjs-preview` instead of from `lit` or `lit-html`.
<!-- prettier-ignore-start -->
~~~markdown
```js story
import { html } from '@mdjs/mdjs-preview';
export const StoryPreview = () => html`
<p>Use stories in Rocket!</p>
`;
```
~~~
<!-- prettier-ignore-end -->

View File

@@ -1 +0,0 @@
# Go Live || 40

View File

@@ -1,54 +0,0 @@
# Go Live >> Overview || 10
A few things are usually needed before going live "for real".
## Add a Not Found Page
When a user enters a URL that does not exist, a "famous" 404 Page Not Found error occurs.
Many servers are configured to handle this automatically and to serve a 404.html page instead.
The [Rocket Launch preset](../../docs/presets/launch.md) ships a default 404 template you can use.
To enable it, you need to create a `404.md` and use the 404 layout.
👉 `docs/404.md`
```markdown copy
---
layout: layout-404
permalink: 404.html
---
```
This results in a `404.html` page, which will do nothing by itself. But many hosting services like netlify or firebase, for example will redirect 404s to this `404.html` by default.
If the hosting provider doesn't already do this, then you may be able to accomplish it via some settings for example by using a `.htaccess` file in case of an apache server.
## Add a Sitemap
A sitemap can be used to inform search engines or services about the pages your site has.
You can create one by adding this file:
👉 `docs/sitemap.njk`
```markdown copy
---
layout: layout-raw
permalink: /sitemap.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% raw %}{% for page in collections.all %}
{%- if page.url !== '/404.html' -%}
<url>
<loc>{{ rocketConfig.absoluteBaseUrl }}{{ page.url | url }}</loc>
<lastmod>{{ page.date.toISOString() }}</lastmod>
<changefreq>{{ page.data.changeFreq if page.data.changeFreq else "monthly" }}</changefreq>
</url>
{%- endif -%}
{% endfor %}{% endraw %}
</urlset>
```

View File

@@ -1,164 +0,0 @@
# Go Live >> Social Media || 20
Having a nice preview image for social media can be very helpful.
For that reason Rocket creates those automatically with the title, parent title, section and your logo.
It will look like this but with your logo:
<img src="{{ socialMediaImage | url }}" width="1200" height="630" alt="Social Media Image of this page" style="border: 1px solid #000" />
There are multiple ways you can modify it.
Note: If your logo has an `<?xml>` tag it will throw an error as it will be inlined into this SVG and nested XML tags are not allowed.
## Setting it via Front Matter
You can create your own image and link it with something like this
```markdown copy
---
socialMediaImage: path/to/my/image.png
---
```
## Providing Your Own Text
Sometimes extracting the title + title of parent is not enough but you still want to use the "default image".
You can create an `11tydata.cjs` file next to your page. If your page is `docs/guides/overview.md` then you create a `docs/guides/overview.11tydata.cjs`.
In there you can use the default `createSocialImage` but provide your own values.
```js copy
const { createSocialImage } = require('@rocket/cli');
module.exports = async function () {
const socialMediaImage = await createSocialImage({
title: 'Learning Rocket',
subTitle: 'Have a website',
subTitle2: 'in 5 Minutes',
footer: 'Rocket Guides',
// you can also override the svg only for this page by providing
// createSocialImageSvg: async () => '{%raw%}<svg>...</svg>{%endraw%}'
});
return {
socialMediaImage,
};
};
```
## Override the Default Image
Often you want to have a unique style for your social media images.
For that you can provide your own function which returns a string of an SVG to render the image.
👉 `rocket.config.js`
<!-- prettier-ignore-start -->
```js copy
import { adjustPluginOptions } from 'plugins-manager';
/** @type {import('@rocket/cli').RocketCliOptions} */
export default ({
setupEleventyComputedConfig: [
adjustPluginOptions('socialMediaImage', {
createSocialImageSvg: async ({
title = '',
subTitle = '',
subTitle2 = '',
footer = '',
logo = '',
}) => {
let svgStr = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" style="fill: #ecedef;">
<defs/>
<rect width="100%" height="100%" fill="#38393e"/>
<g transform="matrix(0.45, 0, 0, 0.45, 300, 60)">${logo}</g>
<g style="
font-size: 70px;
text-anchor: middle;
font-family: 'Bitstream Vera Sans','Helvetica',sans-serif;
font-weight: 700;
">
<text x="50%" y="470">
${title}
</text>
<text x="50%" y="520" style="font-size: 30px;">
${subTitle}
</text>
</g>
<text x="10" y="620" style="font-size: 30px; fill: gray;">
${footer}
</text>
</svg>
`;
return svgStr;
},
}),
],
});
```
<!-- prettier-ignore-end -->
## Using an SVG File as a src with Nunjucks
If you have multiple variations it may be easier to save them as SVG files and use a template system.
<!-- prettier-ignore-start -->
<code-tabs default-tab="rocket.config.js">
```js tab rocket.config.js
import { adjustPluginOptions } from 'plugins-manager';
/** @type {import('@rocket/cli').RocketCliOptions} */
export default ({
setupEleventyComputedConfig: [
adjustPluginOptions('socialMediaImage', {
createSocialImageSvg: async (args = {}) => {
const svgBuffer = await fs.promises.readFile('/path/to/your/template.svg');
const svg = logoBuffer.toString();
return nunjucks.renderString(svg, args);
},
}),
],
});
```
```svg tab /path/to/your/template.svg
{%raw%}<svg xmlns="http://www.w3.org/2000/svg" fill="#e63946" viewBox="0 0 511.998 511.998">
<text font-family="'Open Sans', sans-serif" font-size="39" transform="translate(422.99 408.53)">
<tspan x="-89.26" y="12.25">{{ title }}</tspan>
</text>
<path d="M98.649 430.256c-46.365 28.67-71.17 30.939-78.916 23.51-7.75-7.433-6.519-32.307 20.182-79.832 24.953-44.412 65.374-96.693 113.818-147.211l-11.279-10.817c-49.33 51.442-90.583 104.845-116.163 150.373-19.228 34.22-37.848 79.134-17.375 98.766 5.84 5.6 13.599 7.935 22.484 7.935 22.269 0 51.606-14.677 75.469-29.432 44.416-27.464 96.044-70.919 145.373-122.362l-11.279-10.817c-48.446 50.519-98.987 93.095-142.314 119.887zM254.734 294.95l-18.47-17.71 10.816-11.281 18.47 17.71zM285.516 324.473l-18.47-17.71 10.816-11.28 18.47 17.71zM315.543 317.807l-73.886-70.847 10.816-11.28 73.886 70.846zM500.916 41.287c-7.769 1.59-76.412 16.062-93.897 34.294l-50.728 52.899-114.703-3.629-39.198 40.876 79.28 40.569-21.755 22.687 72.848 69.858 21.755-22.687 43.857 77.51 39.197-40.876-8.433-114.451 50.727-52.899c17.485-18.234 29.067-87.422 30.331-95.251l1.801-11.169-11.082 2.269zM228.209 161.383l19.842-20.692 93.688 2.964-48.775 50.864-64.755-33.136zm173.423 166.303l-35.822-63.308 48.776-50.865 6.886 93.482-19.84 20.691zm-69.334-50.943l-50.287-48.223L412.89 92.037l50.288 48.223-130.88 136.483zm140.711-148.707l-48.316-46.334c14.54-8.427 44.787-17.217 68.076-22.632-4.433 23.497-11.949 54.085-19.76 68.966z"/>
<path d="M326.335 257.25l-24.628-23.614 10.816-11.28 24.628 23.615zM431.385 134.414l-11.808 12.315-11.28-10.816 11.808-12.315zM401.838 165.183l-11.28-10.816 11.807-12.314 11.28 10.816zM384.121 183.66l-11.28-10.816 11.807-12.314 11.28 10.816zM175.19 184.515l11.051 11.05-23.582 23.582-11.05-11.05zM190.903 168.796l11.05 11.052-7.863 7.86-11.05-11.052z"/>
</svg>{%endraw%}
```
</code-tabs>
<!-- prettier-ignore-end -->
## Enabling / Disabling
Generating images from SVG is quite fast but it can still add that's why by default during `rocket start` there will be no social media images created.
If you with so create them also during start you can
<!-- prettier-ignore-start -->
```js copy
export default ({
start: {
createSocialMediaImages: true,
},
});
```
<!-- prettier-ignore-end -->
Similarly, if you never want to create social media images even during build then you can globally disable it via
<!-- prettier-ignore-start -->
```js copy
export default ({
createSocialMediaImages: true,
});
```
<!-- prettier-ignore-end -->

View File

@@ -1,13 +0,0 @@
const { createSocialImage } = require('@rocket/cli');
module.exports = async function () {
const socialMediaImage = await createSocialImage({
title: 'Learning Rocket',
subTitle: 'Have a website',
subTitle2: 'in 5 Minutes',
footer: 'Rocket Guides',
});
return {
socialMediaImage,
};
};

View File

@@ -1,54 +0,0 @@
# Presets >> Create your Own >> Getting Started || 10
A preset is a setup function and a folder including `_assets`, `_data` and `_includes` (all optional).
To play around with a preset you can create a folder `fire-theme`.
You then create the setup function for it with only one property called `path` which will allow Rocket to properly resolve it.
## Create a Preset Config File
👉 `fire-theme/fireTheme.js`
```js copy
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export function fireTheme() {
return {
path: path.resolve(__dirname),
};
}
```
Once you have that you can start filling in content you need.
For example we could override the full `layout.css` by adding it like so
👉 `fire-theme/layout.css`
```css copy
body {
background: hotpink;
}
```
Once you have that you can add it to your Rocket config.
NOTE: The order of presets is important, as for example in this case we take everything from `rocketLaunch` but later override via `fireTheme`.
👉 `rocket.config.js`
<!-- prettier-ignore-start -->
```js copy
import { rocketLaunch } from '@rocket/launch';
import { fireTheme } from 'path/to/fire-theme/fireTheme.js';
/** @type {import('@rocket/cli').RocketCliOptions} */
export default ({
presets: [rocketLaunch(), fireTheme()],
});
```
<!-- prettier-ignore-end -->

View File

@@ -1,22 +0,0 @@
# Presets >> Create your Own >> Hooks || 20
Your preset can hook into the rocket lifecycle by specifying a function for `before11ty`. This function runs before 11ty calls it's write method. If it is an async function, Rocket will await it's promise.
<!-- prettier-ignore-start -->
```js
/** @type {import('@rocket/cli').RocketPreset} */
export default ({
async before11ty() {
await copyDataFiles();
},
});
```
<!-- prettier-ignore-end -->
## Preset Interface
The full preset interface is copied below for your reference.
```ts
{% include ../../../../packages/cli/types/preset.d.ts %}
```

View File

@@ -1,7 +0,0 @@
# Presets >> Create your Own || 40
## Contents
- [Getting Started](./getting-started/)
- [Hooks](./hooks/)
- [Publishing your Preset](./publishing/)

View File

@@ -1,60 +0,0 @@
# Presets >> Create your Own >> Publishing || 100
If you would like to publish a preset to use it on multiple websites or share it with your friends you can do like so.
1. Pick a name for the package
- use the convention `rocket-preset-${name}`
- for this example we use `rocket-preset-fire-theme`.
2. Create a new folder `fire-theme`
3. Create a folder `fire-theme/preset` copy `fireTheme.js` from [above](../getting-started/) into `preset/fireTheme.js`
4. Add a 👉 `package.json`
```json copy
{
"name": "rocket-preset-fire-theme",
"version": "0.3.0",
"description": "Fire Theme for Rocket",
"license": "MIT",
"type": "module",
"exports": {
".": "./index.js",
"./preset/": "./preset/"
},
"files": ["*.js", "preset"],
"keywords": ["rocket", "preset"]
}
```
5. Add a 👉 `index.js`
```js copy
export { fireTheme } from './preset/fireTheme.js';
```
<!-- prettier-ignore-start -->
6. Add a 👉 `README.md`
~~~markdown copy
# FireTheme
This is a theme/preset for [Rocket](https://rocket.modern-web.dev/).
## Installation
```
npm i -D fire-theme
```
Add it to your 👉 `rocket.config.js`
```js
import { fireTheme } from 'fire-theme';
/** @type {import('@rocket/cli').RocketCliOptions} */
export default ({
presets: [rocketLaunch(), fireTheme()],
});
```
~~~
<!-- prettier-ignore-end -->

View File

@@ -1,36 +0,0 @@
# Presets >> Getting Started || 10
Presets are partial rocket configs that combine any number of plugins to add specific features. Rocket is built on these presets, like `rocketLaunch`, `rocketBlog`, and `rocketSearch`
You can use a preset via the config by adding it to the `presets` array
<!-- prettier-ignore-start -->
```js copy
import { rocketLaunch } from '@rocket/launch';
import { rocketBlog } from '@rocket/blog';
import { rocketSearch } from '@rocket/search';
/** @type {import('@rocket/cli').RocketCliOptions} */
export default ({
presets: [rocketLaunch(), rocketBlog(), rocketSearch()],
});
```
<!-- prettier-ignore-end -->
## Community Presets
There are a number of community-made presets available:
<!--
-- Thank you for your interest in rocket. To add your preset,
-- follow the format below. Please add your preset in alphabetical order.
-->
- [rocket-preset-code-tabs](https://www.npmjs.com/package/rocket-preset-code-tabs) - Add tab elements for code blocks
- [rocket-preset-custom-elements-manifest](https://www.npmjs.com/package/rocket-preset-custom-elements-manifest) - Documents code generation for JavaScript libraries, particularly custom elements.
- [rocket-preset-markdown-directive](https://www.npmjs.com/package/rocket-preset-markdown-directive) - Add your own custom md code block directives
- [rocket-preset-playground-elements](https://www.npmjs.com/package/rocket-preset-playground-elements) - Live code editors that run in-browser
- [rocket-preset-slide-decks](https://www.npmjs.com/package/rocket-preset-slide-decks) - Slide decks in Markdown and HTML
- [rocket-preset-webcomponents-dev](https://www.npmjs.com/package/rocket-preset-webcomponents-dev) - Live code editors that run on webcomponents.dev
> Want your plugin listed here? Please [create a PR](https://github.com/modernweb-dev/rocket/edit/main/docs/guides/presets/getting-started.md)!

View File

@@ -1,6 +0,0 @@
# Presets || 20
- [Getting Started](./getting-started/)
- [Overriding](./overriding/)
- [Using Templates](./using-templates/)
- [Create Your Own](./create-your-own/getting-started/)

View File

@@ -1,26 +0,0 @@
# Presets >> Overriding ||20
All loaded presets will be combined but you can override each file.
Take a look at `docs/_merged_includes` and override what you want to override by placing the same filename into `_includes`.
For example, to override the css files loaded in the `<head>`,
```bash
cp docs/_merged_includes/_joiningBlocks/head/40-stylesheets.njk \
docs/_includes/_joiningBlocks/head/40-stylesheets.njk
```
then edit the file to suit your needs.
Also works for `_assets`, `_data` ...
<inline-notification type="warning">
If you don't [add `.eleventyignore`](/guides/first-pages/getting-started/#setup), you may receive error messages when running `rocket build`.
</inline-notification>
```js script
import '@rocket/launch/inline-notification/inline-notification.js';
```

View File

@@ -1,71 +0,0 @@
# Presets >> Using templates ||30
The template system allows for very granular control of how individual parts will be merged, overwritten, or reordered.
On top of the [Overriding](./overriding.md) you can do with the presets alone templates have another superpower and that is automatically joining of parts.
It is generally preferred to use `Joining Blocks` before overriding.
## Adding html to the html head
Often you will want to load some more fonts or an additional CSS file. You can do so by adding a file to the head Joining Block.
👉 `docs/_includes/_joiningBlocks/head/additional-styles.njk`
```html
<link rel="stylesheet" href="{{ '/_assets/additional-styles.css' | asset | url }}" />
```
This will add the html at the bottom of the head.
## Adding JavaScript to the bottom of the body
For executing a script you can use the `bottom` Joining Block.
👉 `docs/_includes/_joiningBlocks/bottom/my-script.njk`
```html
<script>
console.log('hello world');
</script>
```
If you look into `docs/_merged_includes/_joiningBlocks/bottom/` you will see a few scripts
- `10-init-navigation.njk`
- `180-service-worker-update.njk`
- `190-google-analytics.njk`
- `my-script.njk`
<inline-notification type="tip">
File names without an order/number in front are considered with the order number `10 000` so the generally end up at the bottom. If you need something even below unordered items you can use numbers that are greater then `10 000`.
_Note: For unordered files there is no guarantee of any order._
</inline-notification>
## Controlling the order
In the html `<head>` order is usually not that important but when adding script it does.
If you look into the dom then you see that its order matches with the file system order.
Now if you want to move your script in-between `init-nagivation` and `service-worker-update` then you can rename your file to
👉 `docs/_includes/_joiningBlocks/bottom/20-my-script.njk`
which brings the order to
- `10-init-navigation.njk`
- `20-my-script.njk`
- `180-service-worker-update.njk`
- `190-google-analytics.njk`
## More information
For more details please see the [Joining Blocks Docs](../../docs/presets/joining-blocks.md)
```js script
import '@rocket/launch/inline-notification/inline-notification.js';
```

View File

@@ -1,13 +0,0 @@
const { createSocialImage } = require('@rocket/cli');
module.exports = async function () {
const socialMediaImage = await createSocialImage({
title: 'Rocket',
subTitle: 'Static sites with',
subTitle2: 'a sprinkle of JavaScript.',
footer: 'A Modern Web Product',
});
return {
socialMediaImage,
};
};

View File

@@ -1,24 +0,0 @@
---
title: Rocket
layout: layout-home-background
slogan: The modern web setup for static sites with a sprinkle of JavaScript.
callToActionItems:
- text: Follow Guides
href: /guides/
- text: Browse Docs
href: /docs/
reasonHeader: Why Rocket?
reasons:
- header: Small
text: No overblown tools or frontend frameworks, add JavaScript and/or Web Components only on pages where needed.
- header: Pre-Rendered
text: Statically generated content means less JavaScript to ship and process.
- header: Zero Configuration
text: Automatic code splitting, filesystem based routing, and JavaScript in Markdown.
- header: Meta Framework
text: 'Build on top of giants like <a href="https://www.11ty.dev/">Eleventy</a>, <a href="https://rollupjs.org/">Rollup</a>, and <a href="https://www.modern-web.dev/">Modern Web</a>.'
- header: Powerful Default Template
text: Provide content and you are ready to go.
- header: Ready for Production
text: Optimized for a smaller build size, faster dev compilation and dozens of other improvements.
---

View File

@@ -1,5 +0,0 @@
---
layout: layout-simulator
eleventyExcludeFromCollections: true
excludeFromSearch: true
---

View File

@@ -1,15 +0,0 @@
---
layout: layout-raw
permalink: /sitemap.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for page in collections.all %}
<url>
<loc>{{ rocketConfig.absoluteBaseUrl }}{{ page.url | url }}</loc>
<lastmod>{{ page.date.toISOString() }}</lastmod>
<changefreq>{{ page.data.changeFreq if page.data.changeFreq else "monthly" }}</changefreq>
</url>
{% endfor %}
</urlset>

22
examples/blog/.gitignore vendored Normal file
View File

@@ -0,0 +1,22 @@
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
# Rocket ignore files
*-mdjs-generated.js
*-converted-html.js
*-converted-md.js
*-converted-md-source.js
_site
_site-dev

44
examples/blog/README.md Normal file
View File

@@ -0,0 +1,44 @@
# Rocket Starter Kit: Blog
```
npx @rocket/create@latest --template blog
```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
## 🚀 Project Structure
Inside of your Rocket project, you'll see the following folders and files:
```
.
├── config
│ └── rocket.config.js
├── site
│ ├── pages
│ │ └── index.rocket.html
│ └── public
│ └── favicon.ico
└── package.json
```
Rocket looks for `.rocket.md` or `.rocket.js` or `.rocket.html` files in the `site/pages` directory. Each page is exposed as a route based on its file name.
There's nothing special about `site/src/components/`, but that's where we like to put our web components.
Any static assets, that is not referenced via HTML but you still want to be on the web server we can place in the `site/public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :---------------- | :------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run start` | Starts local dev server at `localhost:8000` |
| `npm run build` | Build your production site to `./_site/` |
| `npm run preview` | Preview your build locally, before deploying |
## 👀 Want to learn more?
Feel free to check [our documentation](https://rocket.modern-web.dev) or jump into our [Discord server](https://rocket.modern-web.dev/chat).

View File

@@ -0,0 +1,24 @@
{
"name": "@example/blog",
"version": "0.0.1",
"private": true,
"description": "Get started with a new blog",
"type": "module",
"exports": {
".": "./src/index.js",
"./styles/*": "./site/src/styles/*",
"./components/*": "./site/src/components/*"
},
"scripts": {
"build": "rocket build",
"dev": "npm start",
"preview": "rocket preview",
"start": "NODE_DEBUG=engine:rendering rocket start --open"
},
"devDependencies": {
"@rocket/cli": "^0.20.0-alpha.11",
"@rocket/engine": "^0.1.0-alpha.11",
"lit": "^2.0.0"
},
"@rocket/template-name": "Blog"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -0,0 +1,37 @@
```js server
/* START - Rocket auto generated - do not touch */
export const sourceRelativeFilePath = 'blog/hello-world.rocket.md';
import { html } from '../recursive.data.js';
import { layout } from './local.data.js';
export { html, layout };
/* END - Rocket auto generated - do not touch */
export const title = 'Hello world!';
export const publishDate = '12 Sep 2021';
export const author = 'Thomas Allmer (@daKmoR)';
export const authorHref = 'https://twitter.com/daKmoR';
export const value = 128;
export const description = 'Just a Hello World Post!';
// TODO: remove once lit-ssr can handle undefined values https://github.com/lit/lit/issues/2572
export const heroImage = '';
export const alt = '';
import '../../src/components/blog-author.js';
```
hey
This is so cool!
Do variables work ${value \* 2}?
<br>
---
<br>
There are multiple Co-Authors:
- <blog-author name="Another Author" href="https://twitter.com/daKmoR"></blog-author>

View File

@@ -0,0 +1,9 @@
/* START - Rocket auto generated - do not touch */
export const sourceRelativeFilePath = 'blog/index.rocket.js';
import { html } from '../recursive.data.js';
export { html };
/* END - Rocket auto generated - do not touch */
export const layout = false;
export default () => 'posts';

View File

@@ -0,0 +1,5 @@
// everything you export here will be automatically injected into all pages
import { LayoutBlogPost } from '../../src/layouts/LayoutBlogPost.js';
export const layout = new LayoutBlogPost();

View File

@@ -0,0 +1,27 @@
```js server
/* START - Rocket auto generated - do not touch */
export const sourceRelativeFilePath = 'blog/with-image.rocket.md';
import { html } from '../recursive.data.js';
import { layout } from './local.data.js';
export { html, layout };
/* END - Rocket auto generated - do not touch */
export const title = 'With Image!';
export const publishDate = '13 Sep 2021';
export const author = 'Thomas Allmer (@daKmoR)';
export const authorHref = 'https://twitter.com/daKmoR';
export const value = 128;
export const description = 'Now with an image!';
export const heroImage = './assets/liftoff-flames.jpg';
export const alt = 'Liftoff Flames';
import '../../src/components/blog-author.js';
```
hey
<blog-author name="Another Author" href="https://twitter.com/daKmoR"></blog-author>
This is so cool!
Do variables work ${value \* 2}?

View File

@@ -0,0 +1,96 @@
/* START - Rocket auto generated - do not touch */
export const sourceRelativeFilePath = 'index.rocket.js';
import { html } from './recursive.data.js';
export { html };
/* END - Rocket auto generated - do not touch */
import { PageTree } from '@rocket/engine';
import { nothing } from 'lit';
import { baseHead } from '../src/parts/baseHead.js';
import '../src/components/blog-post-preview.js';
import '../src/components/blog-header.js';
export const title = 'Example Blog';
export const description = 'The perfect starter for your perfect blog.';
export const permalink = 'https://example.com/';
export const pageTree = new PageTree();
await pageTree.restore(new URL('./pageTreeData.rocketGenerated.json', import.meta.url));
class BlogMenu {
/**
* @returns {TemplateResult | nothing}
*/
render() {
if (!this.currentNode || !this.currentNode.children) {
return nothing;
}
return html`
<div>
${this.currentNode.children.map(
/** @param {NodeOfPage} child */ child => html`
<blog-post-preview .post=${child.model}></blog-post-preview>
`,
)}
</div>
`;
}
}
export default () => html`
<html lang="en">
<head>
${baseHead({ title, description, permalink })}
<style>
header {
width: 100%;
height: 100%;
background-color: var(--theme-bg-offset);
display: flex;
align-items: center;
justify-content: center;
}
.content {
margin-top: 4rem;
margin-bottom: 8rem;
}
.content :global(main > * + *) {
margin-top: 1rem;
}
.intro {
padding-bottom: 4rem;
margin-bottom: 2rem;
border-bottom: 4px solid var(--theme-divider);
}
.intro > * {
margin: 0;
}
.latest {
font-size: 2.5rem;
font-weight: 700;
}
</style>
</head>
<body>
<blog-header></blog-header>
<div class="wrapper">
<main class="content">
<section class="intro">
<h1 class="latest">${title}</h1>
<p>${description}</p>
</section>
<section aria-label="Blog post list">
${pageTree.renderMenu(new BlogMenu(), 'blog/index.rocket.js')}
</section>
</main>
</div>
</body>
</html>
`;

View File

@@ -0,0 +1,58 @@
{
"title": "Example Blog",
"h1": "\n \n ",
"name": "\n \n ",
"menuLinkText": "\n \n ",
"url": "/",
"outputRelativeFilePath": "index.html",
"sourceRelativeFilePath": "index.rocket.js",
"level": 0,
"description": "The perfect starter for your perfect blog.",
"permalink": "https://example.com/",
"children": [
{
"name": "blog/index.rocket.js",
"menuLinkText": "blog/index.rocket.js",
"url": "/blog/",
"outputRelativeFilePath": "blog/index.html",
"sourceRelativeFilePath": "blog/index.rocket.js",
"level": 1,
"children": [
{
"title": "Hello world!",
"h1": "\n \n ",
"name": "\n \n ",
"menuLinkText": "\n \n ",
"url": "/blog/hello-world/",
"outputRelativeFilePath": "blog/hello-world/index.html",
"sourceRelativeFilePath": "blog/hello-world.rocket.md",
"level": 2,
"alt": "",
"author": "Thomas Allmer (@daKmoR)",
"authorHref": "https://twitter.com/daKmoR",
"description": "Just a Hello World Post!",
"heroImage": "",
"publishDate": "12 Sep 2021",
"value": 128
},
{
"title": "With Image!",
"h1": "\n \n ",
"name": "\n \n ",
"menuLinkText": "\n \n ",
"url": "/blog/with-image/",
"outputRelativeFilePath": "blog/with-image/index.html",
"sourceRelativeFilePath": "blog/with-image.rocket.md",
"level": 2,
"alt": "Liftoff Flames",
"author": "Thomas Allmer (@daKmoR)",
"authorHref": "https://twitter.com/daKmoR",
"description": "Now with an image!",
"heroImage": "./assets/liftoff-flames.jpg",
"publishDate": "13 Sep 2021",
"value": 128
}
]
}
]
}

View File

@@ -0,0 +1,3 @@
// everything you export here will be automatically injected into all pages
export { html } from 'lit';

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,28 @@
import { html, css, LitElement } from 'lit';
export class BlogAuthor extends LitElement {
static get properties() {
return {
name: { type: String },
href: { type: String },
};
}
static get styles() {
return css`
.author {
margin-bottom: 0.75rem;
}
`;
}
render() {
return html`
<div class="author">
<p><a href=${this.href}>${this.name}</a></p>
</div>
`;
}
}
customElements.define('blog-author', BlogAuthor);

View File

@@ -0,0 +1,91 @@
import { html, css, LitElement } from 'lit';
import { shared } from '../styles/shared.js';
export class BlogHeader extends LitElement {
static get properties() {
return {
name: { type: String },
href: { type: String },
};
}
render() {
return html`
<header class="wrapper">
<article>
<h1>
<a href="/">
<img src="resolve:@rocket/engine/assets/logo.svg" class="logo" />
<span>My Blog</span>
</a>
</h1>
</article>
</header>
`;
}
static get styles() {
return [
shared,
css`
header {
padding-top: 1rem;
padding-bottom: 1rem;
height: 5rem;
}
article {
display: flex;
align-items: center;
justify-content: space-between;
}
.header-subitem {
display: flex;
flex-grow: 0;
gap: 0.5em;
align-items: center;
justify-content: center;
color: var(--theme-text-lighter);
font-size: initial;
padding: 0.5rem;
}
.header-subitem:hover {
color: var(--theme-accent);
}
.header-subitem svg {
width: 1.5rem;
height: 1.5rem;
}
@media (max-width: 32em) {
.header-subitem {
display: none;
}
}
h1 {
margin: 0;
font-size: 1.5rem;
max-width: 100%;
display: flex;
flex-grow: 1;
}
img {
width: 2.5rem;
height: 2.5rem;
}
span {
margin-left: 0.5rem;
}
h1 a {
text-decoration: none;
display: inline-flex;
}
`,
];
}
}
customElements.define('blog-header', BlogHeader);

View File

@@ -0,0 +1,65 @@
import { html, css, LitElement } from 'lit';
export class BlogPostPreview extends LitElement {
static get properties() {
return {
post: { type: Object },
};
}
render() {
return html`
<article class="post-preview">
<header>
<p class="publish-date">${this.post.publishDate}</p>
<a href="${this.post.url}"><h1 class="title">${this.post.title}</h1></a>
</header>
<p>${this.post.description}</p>
<a href=${this.post.url}>Read more</a>
</article>
`;
}
static get styles() {
return css`
.content :global(main > * + *) {
margin-top: 1rem;
}
.post-preview {
padding-bottom: 2rem;
margin-bottom: 2rem;
border-bottom: 4px solid var(--theme-divider);
}
header {
align-items: flex-start;
display: flex;
flex-direction: column;
justify-content: center;
padding-bottom: 2rem;
text-align: left;
}
.title,
.author,
.publish-date {
margin: 0;
}
.publish-date,
.author {
font-size: 1.25rem;
color: var(--theme-text-lighter);
}
.title {
font-size: 2.25rem;
font-weight: 700;
color: var(--theme-text);
}
`;
}
}
customElements.define('blog-post-preview', BlogPostPreview);

View File

@@ -0,0 +1,107 @@
import { html, css, LitElement } from 'lit';
import './blog-author.js';
export class BlogPost extends LitElement {
static get properties() {
return {
title: { type: String },
author: { type: String },
authorHref: { type: String },
publishDate: { type: String, attribute: 'publish-date' },
heroImage: { type: String, attribute: 'hero-image' },
alt: { type: String },
};
}
render() {
return html`
<div class="layout">
<article class="content">
<div>
<header>
${this.heroImage
? html`<img
width="600"
height="400"
class="hero-image"
loading="lazy"
src="${this.heroImage}"
alt="${this.alt}"
/>`
: ''}
<p class="publish-date">${this.publishDate}</p>
<h1 class="title">${this.title}</h1>
<blog-author name=${this.author} href=${this.authorHref}></blog-author>
</header>
<main>
<slot></slot>
</main>
</div>
</article>
</div>
`;
}
static get styles() {
return css`
.hero-image {
width: 100vw;
object-fit: cover;
object-position: center;
margin-top: 2rem;
margin-bottom: 4rem;
max-width: 1280px;
}
@media (max-width: 50em) {
.hero-image {
height: 260px;
margin-top: 0;
margin-bottom: 2rem;
}
}
.content {
margin-bottom: 8rem;
}
.content :global(main > * + *) {
margin-top: 1rem;
}
.content :global(h2) {
margin-top: 4rem;
}
header {
display: flex;
flex-direction: column;
text-align: center;
align-items: center;
justify-content: center;
padding-bottom: 2rem;
margin-bottom: 2rem;
border-bottom: 4px solid var(--theme-divider);
}
.title,
.author,
.publish-date {
margin: 0;
}
.publish-date,
.author {
color: var(--theme-text-lighter);
}
.title {
font-size: 2.25rem;
font-weight: 700;
}
`;
}
}
customElements.define('blog-post', BlogPost);

View File

@@ -0,0 +1,43 @@
import { html } from 'lit';
import { baseHead } from '../parts/baseHead.js';
import '../components/blog-header.js';
import '../components/blog-post.js';
export class LayoutBlogPost {
render(data) {
const {
title,
description,
publishDate,
author,
authorHref,
heroImage,
permalink,
alt,
lang,
} = data;
return html`
<html-server-only lang=${lang || 'en'}>
<head>
${baseHead({ title, description, permalink })}
</head>
<body>
<blog-header></blog-header>
<div class="wrapper">
<blog-post
title=${title}
author=${author}
.authorHref=${authorHref}
hero-image=${heroImage}
publish-date=${publishDate}
alt=${alt}
>
${data.content()}
</blog-post>
</div>
</body>
</html-server-only>
`;
}
}

View File

@@ -0,0 +1,39 @@
import { html } from 'lit';
/**
* @param {{ title: string, description: string, permalink: string }} options
* @returns {import('@rocket/engine').TemplateResult}
*/
export function baseHead({ title, description, permalink }) {
return html`
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<!-- Primary Meta Tags -->
<title-server-only>${title}</title-server-only>
<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}" />
<!-- 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}" />
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&family=IBM+Plex+Sans:wght@400;700&display=swap"
/>
<link rel="stylesheet" href="resolve:@example/blog/styles/blog.css" />
`;
}

View File

@@ -0,0 +1,284 @@
:root {
--font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
--font-body: 'IBM Plex Sans', var(--font-fallback);
--font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono',
'Liberation Mono', 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace;
--color-white: #fff;
--color-black: #000014;
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-300: #d1d5db;
--color-gray-400: #9ca3af;
--color-gray-500: #6b7280;
--color-gray-600: #4b5563;
--color-gray-700: #374151;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
--color-blue: #3894ff;
--color-blue-rgb: 56, 148, 255;
--color-green: #17c083;
--color-green-rgb: 23, 192, 131;
--color-orange: #ff5d01;
--color-orange-rgb: 255, 93, 1;
--color-purple: #882de7;
--color-purple-rgb: 136, 45, 231;
--color-red: #ff1639;
--color-red-rgb: 255, 22, 57;
--color-yellow: #ffbe2d;
--color-yellow-rgb: 255, 190, 45;
}
:root {
color-scheme: light;
--theme-accent: var(--color-orange);
--theme-accent-rgb: var(--color-orange-rgb);
--theme-accent-opacity: 0.1;
--theme-divider: var(--color-gray-100);
--theme-text: var(--color-gray-800);
--theme-text-light: var(--color-gray-600);
--theme-text-lighter: var(--color-gray-400);
--theme-bg: var(--color-white);
--theme-bg-offset: var(--color-gray-100);
--theme-bg-accent: rgba(var(--theme-accent-rgb), var(--theme-accent-opacity));
--theme-code-inline-bg: var(--color-gray-100);
--theme-code-text: var(--color-gray-100);
--theme-code-bg: var(--color-gray-700);
}
body {
background: var(--theme-bg);
color: var(--theme-text);
}
:root.theme-dark {
color-scheme: dark;
--theme-accent-opacity: 0.3;
--theme-divider: var(--color-gray-900);
--theme-text: var(--color-gray-200);
--theme-text-light: var(--color-gray-400);
--theme-text-lighter: var(--color-gray-600);
--theme-bg: var(--color-black);
--theme-bg-offset: var(--color-gray-900);
--theme-code-inline-bg: var(--color-gray-800);
--theme-code-text: var(--color-gray-200);
--theme-code-bg: var(--color-gray-900);
}
::selection {
color: var(--theme-accent);
background-color: rgba(var(--theme-accent-rgb), var(--theme-accent-opacity));
}
* {
box-sizing: border-box;
margin: 0;
}
:root {
--user-font-scale: 1rem - 16px;
--max-width: calc(100% - 2rem);
}
@media (min-width: 50em) {
:root {
--max-width: 40em;
}
}
body {
font-family: var(--font-body);
font-size: 1rem;
font-size: clamp(0.875rem, 0.4626rem + 1.0309vw + var(--user-font-scale), 1.125rem);
line-height: 1.625;
}
.wrapper {
margin-left: auto;
margin-right: auto;
max-width: 65em;
padding-left: 2rem;
padding-right: 2rem;
width: 100%;
}
nav ul {
list-style: none;
padding: 0;
}
/* Typography */
:is(h1, h2, h3, h4, h5, h6) {
margin-bottom: 1.38rem;
font-weight: 400;
line-height: 1.3;
}
:is(h1, h2) {
max-width: 40ch;
}
:is(h2, h3):not(:first-child) {
margin-top: 3rem;
}
h1 {
font-size: clamp(2.488rem, 1.924rem + 1.41vw, 3.052rem);
}
h2 {
font-size: clamp(2.074rem, 1.707rem + 0.9175vw, 2.441rem);
}
h3 {
font-size: clamp(1.728rem, 1.503rem + 0.5625vw, 1.953rem);
}
h4 {
font-size: clamp(1.44rem, 1.317rem + 0.3075vw, 1.563rem);
}
h5 {
font-size: clamp(1.2rem, 1.15rem + 0.125vw, 1.25rem);
}
p {
color: var(--theme-text-light);
}
small,
.text_small {
font-size: 0.833rem;
}
a {
color: var(--theme-accent);
font-weight: 400;
text-underline-offset: 0.08em;
text-decoration: none;
align-items: center;
gap: 0.5rem;
}
a > code:not([class*='language']) {
position: relative;
color: var(--theme-accent);
background: transparent;
text-underline-offset: var(--padding-block);
}
a > code:not([class*='language'])::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: block;
background: var(--theme-accent);
opacity: var(--theme-accent-opacity);
border-radius: var(--border-radius);
}
a:hover,
a:focus {
text-decoration: underline;
}
a:focus {
outline: 2px solid currentColor;
outline-offset: 0.25em;
}
strong {
font-weight: 600;
color: inherit;
}
/* Supporting Content */
code:not([class*='language']) {
--border-radius: 3px;
--padding-block: 0.2rem;
--padding-inline: 0.33rem;
font-family: var(--font-mono);
font-size: 0.85em;
color: inherit;
background-color: var(--theme-code-inline-bg);
padding: var(--padding-block) var(--padding-inline);
margin: calc(var(--padding-block) * -1) -0.125em;
border-radius: var(--border-radius);
word-break: break-word;
}
pre > code:not([class*='language']) {
background-color: transparent;
padding: 0;
margin: 0;
border-radius: 0;
color: inherit;
}
pre {
position: relative;
background-color: var(--theme-code-bg);
color: var(--theme-code-text);
--padding-block: 1rem;
--padding-inline: 2rem;
padding: var(--padding-block) var(--padding-inline);
padding-right: calc(var(--padding-inline) * 2);
margin-left: calc(50vw - var(--padding-inline));
transform: translateX(-50vw);
line-height: 1.414;
width: calc(100vw + (var(--padding-inline) * 2));
max-width: calc(100% + (var(--padding-inline) * 2));
overflow-y: hidden;
overflow-x: auto;
}
@media (min-width: 37.75em) {
pre {
--padding-inline: 1.25rem;
border-radius: 8px;
}
}
.flex {
display: flex;
align-items: center;
}
img.cover {
width: 100%;
max-height: 50vh;
object-fit: cover;
}
blockquote {
font-size: 1.5rem;
--padding-block: 1rem;
--padding-inline: 1.25rem;
--color: var(--theme-divider);
display: flex;
flex-direction: column;
padding: var(--padding-block) var(--padding-inline);
margin-left: calc(var(--padding-inline) * -1);
margin-right: calc(var(--padding-inline) * -1);
background: transparent;
border-left: calc(var(--padding-inline) / 2) solid var(--color);
border-radius: 0;
}
blockquote .source {
font-weight: 500;
color: var(--color);
font-size: 1rem;
}

View File

@@ -0,0 +1,12 @@
import { css } from 'lit';
export const shared = css`
.wrapper {
margin-left: auto;
margin-right: auto;
max-width: 65em;
padding-left: 2rem;
padding-right: 2rem;
width: 100%;
}
`;

View File

@@ -0,0 +1,7 @@
{
"compilerOptions": {
"moduleResolution": "node",
"allowJs": true,
"checkJs": true,
}
}

22
examples/minimal/.gitignore vendored Normal file
View File

@@ -0,0 +1,22 @@
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
# Rocket ignore files
*-mdjs-generated.js
*-converted-html.js
*-converted-md.js
*-converted-md-source.js
_site
_site-dev

View File

@@ -0,0 +1,8 @@
{
"files.exclude": {
"**/*-mdjs-generated.js": true,
},
"search.exclude": {
"**/*-mdjs-generated.js": true,
}
}

View File

@@ -0,0 +1,44 @@
# Rocket Starter Kit: Minimal
```
npx @rocket/create@latest --template minimal
```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
## 🚀 Project Structure
Inside of your Rocket project, you'll see the following folders and files:
```
.
├── config
│ └── rocket.config.js
├── site
│ ├── pages
│ │ └── index.rocket.html
│ └── public
│ └── favicon.ico
└── package.json
```
Rocket looks for `.rocket.md` or `.rocket.js` or `.rocket.html` files in the `site/pages` directory. Each page is exposed as a route based on its file name.
There's nothing special about `site/src/components/`, but that's where we like to put our web components.
Any static assets, that is not referenced via HTML but you still want to be on the web server we can place in the `site/public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :---------------- | :------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run start` | Starts local dev server at `localhost:8000` |
| `npm run build` | Build your production site to `./_site/` |
| `npm run preview` | Preview your build locally, before deploying |
## 👀 Want to learn more?
Feel free to check [our documentation](https://rocket.modern-web.dev) or jump into our [Discord server](https://rocket.modern-web.dev/chat).

View File

@@ -0,0 +1,3 @@
export default /** @type {import('@rocket/cli').RocketCliOptions} */ ({
absoluteBaseUrl: 'http://localhost:8080',
});

Some files were not shown because too many files have changed in this diff Show More