├── public
├── robots.txt
├── manifest.json
└── favicon.svg
├── .prettierignore
├── vite.config.ts
├── .eslintignore
├── src
├── routes
│ ├── layout.tsx
│ ├── index.tsx
│ └── service-worker.ts
├── entry.dev.tsx
├── components
│ ├── header
│ │ ├── header.css
│ │ └── header.tsx
│ ├── router-head
│ │ └── router-head.tsx
│ └── icons
│ │ └── qwik.tsx
├── entry.preview.tsx
├── entry.ssr.tsx
├── root.tsx
└── global.css
├── .gitignore
├── tsconfig.json
├── .eslintrc.cjs
├── package.json
└── README.md
/public/robots.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Files Prettier should not format
2 | **/*.log
3 | **/.DS_Store
4 | *.
5 | dist
6 | node_modules
7 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/web-manifest-combined.json",
3 | "name": "qwik-project-name",
4 | "short_name": "Welcome to Qwik",
5 | "start_url": ".",
6 | "display": "standalone",
7 | "background_color": "#fff",
8 | "description": "A Qwik project app."
9 | }
10 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import { qwikVite } from '@builder.io/qwik/optimizer';
3 | import { qwikCity } from '@builder.io/qwik-city/vite';
4 | import tsconfigPaths from 'vite-tsconfig-paths';
5 |
6 | export default defineConfig(() => {
7 | return {
8 | plugins: [qwikCity(), qwikVite(), tsconfigPaths()],
9 | preview: {
10 | headers: {
11 | 'Cache-Control': 'public, max-age=600',
12 | },
13 | },
14 | };
15 | });
16 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/*.log
2 | **/.DS_Store
3 | *.
4 | .vscode/settings.json
5 | .history
6 | .yarn
7 | bazel-*
8 | bazel-bin
9 | bazel-out
10 | bazel-qwik
11 | bazel-testlogs
12 | dist
13 | dist-dev
14 | lib
15 | lib-types
16 | etc
17 | external
18 | node_modules
19 | temp
20 | tsc-out
21 | tsdoc-metadata.json
22 | target
23 | output
24 | rollup.config.js
25 | build
26 | .cache
27 | .vscode
28 | .rollup.cache
29 | dist
30 | tsconfig.tsbuildinfo
31 | vite.config.ts
32 | *.spec.tsx
33 | *.spec.ts
34 |
--------------------------------------------------------------------------------
/src/routes/layout.tsx:
--------------------------------------------------------------------------------
1 | import { component$, Slot } from '@builder.io/qwik';
2 | import Header from '../components/header/header';
3 |
4 | export default component$(() => {
5 | return (
6 | <>
7 |
8 |
9 |
12 |
13 |
18 | >
19 | );
20 | });
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build
2 | /dist
3 | /lib
4 | /lib-types
5 | /server
6 |
7 | # Development
8 | node_modules
9 |
10 | # Cache
11 | .cache
12 | .mf
13 | .vscode
14 | .rollup.cache
15 | tsconfig.tsbuildinfo
16 |
17 | # Logs
18 | logs
19 | *.log
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 | pnpm-debug.log*
24 | lerna-debug.log*
25 |
26 | # Editor
27 | !.vscode/extensions.json
28 | .idea
29 | .DS_Store
30 | *.suo
31 | *.ntvs*
32 | *.njsproj
33 | *.sln
34 | *.sw?
35 |
36 | # Yarn
37 | .yarn/*
38 | !.yarn/releases
39 |
--------------------------------------------------------------------------------
/src/entry.dev.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * WHAT IS THIS FILE?
3 | *
4 | * Development entry point using only client-side modules:
5 | * - Do not use this mode in production!
6 | * - No SSR
7 | * - No portion of the application is pre-rendered on the server.
8 | * - All of the application is running eagerly in the browser.
9 | * - More code is transferred to the browser than in SSR mode.
10 | * - Optimizer/Serialization/Deserialization code is not exercised!
11 | */
12 | import { render, RenderOptions } from '@builder.io/qwik';
13 | import Root from './root';
14 |
15 | export default function (opts: RenderOptions) {
16 | return render(document, , opts);
17 | }
18 |
--------------------------------------------------------------------------------
/src/routes/index.tsx:
--------------------------------------------------------------------------------
1 | import { component$, useSignal } from '@builder.io/qwik';
2 | import type { DocumentHead } from '@builder.io/qwik-city';
3 |
4 | export default component$(() => {
5 | const count = useSignal(0);
6 | return (
7 |
8 |
9 | Counter is {count.value} ⚡️
10 |
11 |
12 |
13 | );
14 | });
15 |
16 | export const head: DocumentHead = {
17 | title: 'Welcome to Qwik Demo',
18 | meta: [
19 | {
20 | name: 'description',
21 | content: 'Qwik site description',
22 | },
23 | ],
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/header/header.css:
--------------------------------------------------------------------------------
1 | header {
2 | display: flex;
3 | background: white;
4 | border-bottom: 10px solid var(--qwik-dark-purple);
5 | }
6 |
7 | header .logo a {
8 | display: inline-block;
9 | padding: 10px 10px 7px 20px;
10 | }
11 |
12 | header ul {
13 | margin: 0;
14 | padding: 3px 10px 0 0;
15 | list-style: none;
16 | flex: 1;
17 | text-align: right;
18 | }
19 |
20 | header li {
21 | display: inline-block;
22 | margin: 0;
23 | padding: 0;
24 | }
25 |
26 | header li a {
27 | display: inline-block;
28 | padding: 15px 10px;
29 | text-decoration: none;
30 | }
31 |
32 | header li a:hover {
33 | text-decoration: underline;
34 | }
35 |
--------------------------------------------------------------------------------
/src/entry.preview.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * WHAT IS THIS FILE?
3 | *
4 | * It's the bundle entry point for `npm run preview`.
5 | * That is, serving your app built in production mode.
6 | *
7 | * Feel free to modify this file, but don't remove it!
8 | *
9 | * Learn more about Vite's preview command:
10 | * - https://vitejs.dev/config/preview-options.html#preview-options
11 | *
12 | */
13 | import { createQwikCity } from '@builder.io/qwik-city/middleware/node';
14 | import render from './entry.ssr';
15 | import qwikCityPlan from '@qwik-city-plan';
16 |
17 | /**
18 | * The default export is the QwikCity adaptor used by Vite preview.
19 | */
20 | export default createQwikCity({ render, qwikCityPlan });
21 |
--------------------------------------------------------------------------------
/src/routes/service-worker.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * WHAT IS THIS FILE?
3 | *
4 | * The service-worker.ts file is used to have state of the art prefetching.
5 | * https://qwik.builder.io/qwikcity/prefetching/overview/
6 | *
7 | * Qwik uses a service worker to speed up your site and reduce latency, ie, not used in the traditional way of offline.
8 | * You can also use this file to add more functionality that runs in the service worker.
9 | */
10 | import { setupServiceWorker } from '@builder.io/qwik-city/service-worker';
11 |
12 | setupServiceWorker();
13 |
14 | addEventListener('install', () => self.skipWaiting());
15 |
16 | addEventListener('activate', () => self.clients.claim());
17 |
18 | declare const self: ServiceWorkerGlobalScope;
19 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "target": "ES2017",
5 | "module": "ES2020",
6 | "lib": ["es2020", "DOM", "WebWorker", "DOM.Iterable"],
7 | "jsx": "react-jsx",
8 | "jsxImportSource": "@builder.io/qwik",
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "resolveJsonModule": true,
12 | "moduleResolution": "node",
13 | "esModuleInterop": true,
14 | "skipLibCheck": true,
15 | "incremental": true,
16 | "isolatedModules": true,
17 | "outDir": "tmp",
18 | "noEmit": true,
19 | "types": ["node", "vite/client"],
20 | "paths": {
21 | "~/*": ["./src/*"]
22 | }
23 | },
24 | "files": ["./.eslintrc.cjs"],
25 | "include": ["src"]
26 | }
27 |
--------------------------------------------------------------------------------
/src/entry.ssr.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * WHAT IS THIS FILE?
3 | *
4 | * SSR entry point, in all cases the application is render outside the browser, this
5 | * entry point will be the common one.
6 | *
7 | * - Server (express, cloudflare...)
8 | * - npm run start
9 | * - npm run preview
10 | * - npm run build
11 | *
12 | */
13 | import { renderToStream, RenderToStreamOptions } from '@builder.io/qwik/server';
14 | import { manifest } from '@qwik-client-manifest';
15 | import Root from './root';
16 |
17 | export default function (opts: RenderToStreamOptions) {
18 | return renderToStream(, {
19 | manifest,
20 | ...opts,
21 | // Use container attributes to set attributes on the html tag.
22 | containerAttributes: {
23 | lang: 'en-us',
24 | ...opts.containerAttributes,
25 | },
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/root.tsx:
--------------------------------------------------------------------------------
1 | import { component$, useStyles$ } from '@builder.io/qwik';
2 | import { QwikCityProvider, RouterOutlet, ServiceWorkerRegister } from '@builder.io/qwik-city';
3 | import { RouterHead } from './components/router-head/router-head';
4 |
5 | import globalStyles from './global.css?inline';
6 |
7 | export default component$(() => {
8 | /**
9 | * The root of a QwikCity site always start with the component,
10 | * immediately followed by the document's and .
11 | *
12 | * Dont remove the `` and `` elements.
13 | */
14 | useStyles$(globalStyles);
15 |
16 | return (
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | );
29 | });
30 |
--------------------------------------------------------------------------------
/src/components/router-head/router-head.tsx:
--------------------------------------------------------------------------------
1 | import { component$ } from '@builder.io/qwik';
2 | import { useDocumentHead, useLocation } from '@builder.io/qwik-city';
3 |
4 | /**
5 | * The RouterHead component is placed inside of the document `` element.
6 | */
7 | export const RouterHead = component$(() => {
8 | const head = useDocumentHead();
9 | const loc = useLocation();
10 |
11 | return (
12 | <>
13 | {head.title}
14 |
15 |
16 |
17 |
18 |
19 | {head.meta.map((m) => (
20 |
21 | ))}
22 |
23 | {head.links.map((l) => (
24 |
25 | ))}
26 |
27 | {head.styles.map((s) => (
28 |
29 | ))}
30 | >
31 | );
32 | });
33 |
--------------------------------------------------------------------------------
/src/components/header/header.tsx:
--------------------------------------------------------------------------------
1 | import { component$, useStylesScoped$ } from '@builder.io/qwik';
2 | import { QwikLogo } from '../icons/qwik';
3 | import styles from './header.css?inline';
4 |
5 | export default component$(() => {
6 | useStylesScoped$(styles);
7 |
8 | return (
9 |
33 | );
34 | });
35 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | browser: true,
5 | es2021: true,
6 | node: true,
7 | },
8 | extends: [
9 | 'eslint:recommended',
10 | 'plugin:@typescript-eslint/recommended',
11 | 'plugin:qwik/recommended',
12 | ],
13 | parser: '@typescript-eslint/parser',
14 | parserOptions: {
15 | tsconfigRootDir: __dirname,
16 | project: ['./tsconfig.json'],
17 | ecmaVersion: 2021,
18 | sourceType: 'module',
19 | ecmaFeatures: {
20 | jsx: true,
21 | },
22 | },
23 | plugins: ['@typescript-eslint'],
24 | rules: {
25 | '@typescript-eslint/no-explicit-any': 'off',
26 | '@typescript-eslint/explicit-module-boundary-types': 'off',
27 | '@typescript-eslint/no-inferrable-types': 'off',
28 | '@typescript-eslint/no-non-null-assertion': 'off',
29 | '@typescript-eslint/no-empty-interface': 'off',
30 | '@typescript-eslint/no-namespace': 'off',
31 | '@typescript-eslint/no-empty-function': 'off',
32 | '@typescript-eslint/no-this-alias': 'off',
33 | '@typescript-eslint/ban-types': 'off',
34 | '@typescript-eslint/ban-ts-comment': 'off',
35 | 'prefer-spread': 'off',
36 | 'no-case-declarations': 'off',
37 | 'no-console': 'off',
38 | '@typescript-eslint/no-unused-vars': ['error'],
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-qwik-basic-starter",
3 | "description": "App with Routing built-in (recommended)",
4 | "engines": {
5 | "node": ">=15.0.0"
6 | },
7 | "private": true,
8 | "scripts": {
9 | "build": "qwik build",
10 | "build.client": "vite build",
11 | "build.preview": "vite build --ssr src/entry.preview.tsx",
12 | "build.types": "tsc --incremental --noEmit",
13 | "deploy": "echo 'Run \"npm run qwik add\" to install a server adaptor'",
14 | "dev": "vite --mode ssr",
15 | "dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
16 | "fmt": "prettier --write .",
17 | "fmt.check": "prettier --check .",
18 | "lint": "eslint \"src/**/*.ts*\"",
19 | "preview": "qwik build preview && vite preview --open",
20 | "start": "vite --open --mode ssr",
21 | "qwik": "qwik"
22 | },
23 | "devDependencies": {
24 | "@builder.io/qwik": "0.15.2",
25 | "@builder.io/qwik-city": "0.0.128",
26 | "@types/eslint": "8.4.10",
27 | "@types/node": "latest",
28 | "@typescript-eslint/eslint-plugin": "5.45.0",
29 | "@typescript-eslint/parser": "5.45.0",
30 | "eslint": "8.28.0",
31 | "eslint-plugin-qwik": "0.15.2",
32 | "node-fetch": "3.3.0",
33 | "prettier": "2.8.0",
34 | "typescript": "4.9.3",
35 | "vite": "3.2.4",
36 | "vite-tsconfig-paths": "3.5.0"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Qwik City App ⚡️
2 |
3 | - [Qwik Docs](https://qwik.builder.io/)
4 | - [Discord](https://qwik.builder.io/chat)
5 | - [Qwik GitHub](https://github.com/BuilderIO/qwik)
6 | - [@QwikDev](https://twitter.com/QwikDev)
7 | - [Vite](https://vitejs.dev/)
8 |
9 | ---
10 |
11 | ## Project Structure
12 |
13 | This project is using Qwik with [QwikCity](https://qwik.builder.io/qwikcity/overview/). QwikCity is just a extra set of tools on top of Qwik to make it easier to build a full site, including directory-based routing, layouts, and more.
14 |
15 | Inside your project, you'll see the following directory structure:
16 |
17 | ```
18 | ├── public/
19 | │ └── ...
20 | └── src/
21 | ├── components/
22 | │ └── ...
23 | └── routes/
24 | └── ...
25 | ```
26 |
27 | - `src/routes`: Provides the directory based routing, which can include a hierarchy of `layout.tsx` layout files, and an `index.tsx` file as the page. Additionally, `index.ts` files are endpoints. Please see the [routing docs](https://qwik.builder.io/qwikcity/routing/overview/) for more info.
28 |
29 | - `src/components`: Recommended directory for components.
30 |
31 | - `public`: Any static assets, like images, can be placed in the public directory. Please see the [Vite public directory](https://vitejs.dev/guide/assets.html#the-public-directory) for more info.
32 |
33 | ## Add Integrations and deployment
34 |
35 | Use the `npm run qwik add` command to add additional integrations. Some examples of integrations include: Cloudflare, Netlify or Express server, and the [Static Site Generator (SSG)](https://qwik.builder.io/qwikcity/static-site-generation/static-site-config/).
36 |
37 | ```shell
38 | npm run qwik add # or `yarn qwik add`
39 | ```
40 |
41 | ## Development
42 |
43 | Development mode uses [Vite's development server](https://vitejs.dev/). During development, the `dev` command will server-side render (SSR) the output.
44 |
45 | ```shell
46 | npm start # or `yarn start`
47 | ```
48 |
49 | > Note: during dev mode, Vite may request a significant number of `.js` files. This does not represent a Qwik production build.
50 |
51 | ## Preview
52 |
53 | The preview command will create a production build of the client modules, a production build of `src/entry.preview.tsx`, and run a local server. The preview server is only for convenience to locally preview a production build, and it should not be used as a production server.
54 |
55 | ```shell
56 | npm run preview # or `yarn preview`
57 | ```
58 |
59 | ## Production
60 |
61 | The production build will generate client and server modules by running both client and server build commands. Additionally, the build command will use Typescript to run a type check on the source code.
62 |
63 | ```shell
64 | npm run build # or `yarn build`
65 | ```
66 |
--------------------------------------------------------------------------------
/src/global.css:
--------------------------------------------------------------------------------
1 | /**
2 | * WHAT IS THIS FILE?
3 | *
4 | * Globally applied styles. No matter which components are in the page or matching route,
5 | * the styles in here will be applied to the Document, without any sort of CSS scoping.
6 | *
7 | */
8 |
9 | :root {
10 | --qwik-dark-blue: #006ce9;
11 | --qwik-light-blue: #18b6f6;
12 | --qwik-light-purple: #ac7ff4;
13 | --qwik-dark-purple: #713fc2;
14 | }
15 |
16 | body {
17 | background-color: #fafafa;
18 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
19 | padding: 20px 20px 40px 20px;
20 | }
21 |
22 | main {
23 | max-width: 760px;
24 | margin: 0 auto;
25 | background-color: white;
26 | border-radius: 5px;
27 | box-shadow: 0px 0px 130px -50px var(--qwik-light-purple);
28 | overflow: hidden;
29 | }
30 |
31 | h1,
32 | h2 {
33 | margin: 0 0 5px 0;
34 | }
35 |
36 | .lightning {
37 | filter: hue-rotate(180deg);
38 | }
39 |
40 | section {
41 | padding: 20px;
42 | border-bottom: 10px solid var(--qwik-dark-blue);
43 | }
44 |
45 | ul {
46 | list-style-type: square;
47 | margin: 5px 0 30px 0;
48 | padding-left: 25px;
49 | }
50 |
51 | li {
52 | padding: 8px 0;
53 | }
54 |
55 | li::marker {
56 | color: var(--qwik-light-blue);
57 | }
58 |
59 | a,
60 | a:visited {
61 | color: var(--qwik-dark-blue);
62 | }
63 |
64 | a:hover {
65 | text-decoration: none;
66 | }
67 |
68 | table.commands {
69 | margin: 0 0 30px 0;
70 | }
71 |
72 | .commands td {
73 | padding: 5px;
74 | }
75 |
76 | .commands td:first-child {
77 | white-space: nowrap;
78 | padding-right: 20px;
79 | }
80 |
81 | code {
82 | font-family: Menlo, Monaco, Courier New, monospace;
83 | font-size: 0.9em;
84 | background-color: rgb(224, 224, 224);
85 | padding: 2px 4px;
86 | border-radius: 3px;
87 | border-bottom: 2px solid #bfbfbf;
88 | }
89 |
90 | footer {
91 | padding: 15px;
92 | text-align: center;
93 | font-size: 0.8em;
94 | }
95 |
96 | footer a {
97 | text-decoration: none;
98 | }
99 |
100 | footer a:hover {
101 | text-decoration: underline;
102 | }
103 |
104 | a.mindblow {
105 | margin: 0 auto;
106 | display: block;
107 | background: var(--qwik-light-purple);
108 | padding: 10px 20px;
109 | border-radius: 10px;
110 | border: 0;
111 | color: white;
112 | text-decoration: none;
113 | font-size: 20px;
114 | width: fit-content;
115 | border-bottom: 4px solid black;
116 | cursor: url("data:image/svg+xml;utf8,")
117 | 16 0,
118 | auto; /*!emojicursor.app*/
119 | }
120 |
121 | a.mindblow:hover {
122 | border-bottom-width: 0px;
123 | margin-bottom: 4px;
124 | transform: translateY(4px);
125 | }
126 |
--------------------------------------------------------------------------------
/src/components/icons/qwik.tsx:
--------------------------------------------------------------------------------
1 | export const QwikLogo = () => (
2 |
32 | );
33 |
--------------------------------------------------------------------------------