├── public ├── robots.txt ├── manifest.json └── favicon.svg ├── .gitignore ├── postcss.config.js ├── tailwind.config.js ├── src ├── components │ ├── footer │ │ ├── footer.module.css │ │ └── footer.tsx │ ├── header │ │ ├── header.module.css │ │ └── header.tsx │ ├── router-head │ │ └── router-head.tsx │ └── icons │ │ └── qwik.tsx ├── entry.dev.tsx ├── entry.preview.tsx ├── routes │ ├── layout.tsx │ ├── service-worker.ts │ ├── index.tsx │ └── modular-forms │ │ └── index.tsx ├── entry.ssr.tsx ├── root.tsx └── global.css ├── vite.config.ts ├── tsconfig.json ├── .vscode └── settings.json ├── package.json └── README.md /public/robots.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .history 3 | /server -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/footer/footer.module.css: -------------------------------------------------------------------------------- 1 | .anchor { 2 | color: white !important; 3 | display: block; 4 | font-size: 0.8rem; 5 | text-align: center; 6 | text-decoration: none; 7 | } 8 | 9 | .spacer { 10 | padding: 0 15px; 11 | } 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/components/footer/footer.tsx: -------------------------------------------------------------------------------- 1 | import { component$ } from '@builder.io/qwik'; 2 | import { useServerTimeLoader } from '~/routes/layout'; 3 | import styles from './footer.module.css'; 4 | 5 | export default component$(() => { 6 | const serverTime = useServerTimeLoader(); 7 | 8 | return ( 9 | 16 | ); 17 | }); 18 | -------------------------------------------------------------------------------- /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, type 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/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 adapter used by Vite preview. 19 | */ 20 | export default createQwikCity({ render, qwikCityPlan }); 21 | -------------------------------------------------------------------------------- /src/routes/layout.tsx: -------------------------------------------------------------------------------- 1 | import { component$, Slot } from '@builder.io/qwik'; 2 | import { routeLoader$ } from '@builder.io/qwik-city'; 3 | 4 | import Header from '~/components/header/header'; 5 | import Footer from '~/components/footer/footer'; 6 | 7 | export const useServerTimeLoader = routeLoader$(() => { 8 | return { 9 | date: new Date().toISOString(), 10 | }; 11 | }); 12 | 13 | export default component$(() => { 14 | return ( 15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | ); 27 | }); 28 | -------------------------------------------------------------------------------- /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/components/header/header.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | display: flex; 3 | align-items: center; 4 | padding: 20px 10px 0; 5 | } 6 | 7 | .header .logo a { 8 | display: inline-block; 9 | } 10 | 11 | .header ul { 12 | margin: 0; 13 | list-style: none; 14 | flex: 1; 15 | text-align: right; 16 | } 17 | 18 | .header li { 19 | display: none; 20 | margin: 0; 21 | padding: 0; 22 | } 23 | 24 | .header li a { 25 | color: white; 26 | display: inline-block; 27 | padding: 0 1em; 28 | text-decoration: none; 29 | } 30 | 31 | .header li a:hover { 32 | color: var(--qwik-dark-purple); 33 | } 34 | 35 | @media (min-width: 450px) { 36 | .header li { 37 | display: inline-block; 38 | } 39 | } 40 | 41 | @media (min-width: 768px) { 42 | .header { 43 | padding: 20px 70px 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /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, type 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 | -------------------------------------------------------------------------------- /src/root.tsx: -------------------------------------------------------------------------------- 1 | import { component$ } 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 './global.css'; 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 | 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | }); 29 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /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 |