Code for https://gm112.neocities.org/ gm112.neocities.org/

feat: add initial port to nuxt

gm112.bsky.social f246973c

Waiting for spindle ...
+450
+12
.editorconfig
··· 1 + root = true 2 + 3 + [*] 4 + indent_size = 2 5 + indent_style = space 6 + end_of_line = lf 7 + charset = utf-8 8 + trim_trailing_whitespace = true 9 + insert_final_newline = true 10 + 11 + [*.md] 12 + trim_trailing_whitespace = false
+1
.gitattributes
··· 1 + * text=auto eol=lf
+26
.gitignore
··· 1 + # Nuxt dev/build outputs 2 + .output 3 + .data 4 + .nuxt 5 + .nitro 6 + .cache 7 + dist 8 + 9 + # Node dependencies 10 + node_modules 11 + 12 + # Logs 13 + logs 14 + *.log 15 + 16 + # Misc 17 + .DS_Store 18 + .fleet 19 + .idea 20 + 21 + # Local env files 22 + .env 23 + .env.* 24 + !.env.example 25 + 26 + pnpm-lock.yaml
+4
.markdownlint.json
··· 1 + { 2 + "no-inline-html": false, 3 + "no-missing-space-atx": false 4 + }
+1
.nuxtrc
··· 1 + setups.@nuxt/test-utils="3.23.0"
+1
.nvmrc
··· 1 + lts/*
+8
.oxfmtrc.json
··· 1 + { 2 + "$schema": "./node_modules/oxfmt/configuration_schema.json", 3 + "singleQuote": true, 4 + "semi": false, 5 + "trailingComma": "all", 6 + "embeddedLanguageFormatting": "auto", 7 + "arrowParens": "avoid" 8 + }
+20
.tangled/workflows/deploy.yaml
··· 1 + engine: nixery 2 + when: 3 + - event: ['push'] 4 + branch: ['main'] 5 + 6 + dependencies: 7 + nixpkgs: 8 + - nodejs 9 + 10 + steps: 11 + - name: Configure pnpm 12 + run: | 13 + corepack enable 14 + pnpm install --frozen-lockfile 15 + 16 + - name: Build 17 + run: pnpm build 18 + 19 + - name: Deploy to neocities 20 + run: echo "Not implemented yet"
+33
.vscode/launch.json
··· 1 + { 2 + "version": "0.2.0", 3 + "configurations": [ 4 + { 5 + "name": "Debug", 6 + "type": "node-terminal", 7 + "request": "launch", 8 + "command": "pnpm run dev", 9 + "outputCapture": "std", 10 + "sourceMaps": true, 11 + "skipFiles": ["<node_internals>/**", "node_modules/**"] 12 + }, 13 + { 14 + "type": "chrome", 15 + "request": "launch", 16 + "name": "Launch Chrome", 17 + "url": "http://localhost:3000", 18 + "webRoot": "${workspaceFolder}", 19 + "sourceMapPathOverrides": { 20 + "webpack:///./src/*": "${webRoot}/*" 21 + }, 22 + "sourceMaps": true, 23 + "runtimeArgs": ["--remote-debugging-port=9222", "--profile-directory=debug-profile"], 24 + "userDataDir": false 25 + } 26 + ], 27 + "compounds": [ 28 + { 29 + "name": "Debug & Preview", 30 + "configurations": ["Debug", "Launch Chrome"] 31 + } 32 + ] 33 + }
+58
.vscode/settings.json
··· 1 + { 2 + "deno.enable": false, 3 + "prettier.enable": false, 4 + "eslint.enable": true, 5 + "eslint.format.enable": true, 6 + "eslint.validate": [ 7 + "javascript", 8 + "javascriptreact", 9 + "typescript", 10 + "typescriptreact", 11 + "vue", 12 + "json" 13 + ], 14 + "editor.formatOnSave": false, 15 + "editor.defaultFormatter": "dbaeumer.vscode-eslint", 16 + "[vue]": { 17 + "editor.defaultFormatter": "dbaeumer.vscode-eslint" 18 + }, 19 + "[jsonc]": { 20 + "editor.formatOnSave": true 21 + }, 22 + "[json]": { 23 + "editor.formatOnSave": true 24 + }, 25 + "editor.codeActionsOnSave": { 26 + "source.fixAll": "never", 27 + "source.organizeImports": "never", 28 + "source.fixAll.eslint": "explicit" 29 + }, 30 + "files.associations": { 31 + "*.css": "tailwindcss" 32 + }, 33 + "editor.quickSuggestions": { 34 + "strings": "on" 35 + }, 36 + "tailwindCSS.classAttributes": ["class", "ui", "active-class", "inactive-class"], 37 + "tailwindCSS.experimental.classRegex": [["ui:\\s*{([^)]*)\\s*}", "(?:'|\"|`)([^']*)(?:'|\"|`)"]], 38 + "typescript.tsdk": "node_modules/typescript/lib", 39 + "typescript.enablePromptUseWorkspaceTsdk": true, 40 + "explorer.fileNesting.enabled": true, 41 + "explorer.fileNesting.expand": false, 42 + "explorer.sortOrder": "filesFirst", 43 + "explorer.fileNesting.patterns": { 44 + "package.json": "*.json, *.yml, *.config.js, *.config.ts, *.yaml, *.workspace.ts, .nvmrc, yarn.lock, .npmrc", 45 + ".editorconfig": "eslint.config.mjs, .prettierrc, .prettierignore, .gitignore", 46 + ".env.local": "*.env, .env.*, .envrc, .env.d.ts", 47 + ".gitignore": ".gitattributes, .gitmodules, .gitmessage, .lfsconfig, .mailmap, .git-blame*", 48 + "README*": "AUTHORS, Authors, BACKERS*, Backers*, CHANGELOG*, CITATION*, CODEOWNERS, CODE_OF_CONDUCT*, CONTRIBUTING*, CONTRIBUTORS, COPYING*, CREDITS, Changelog*, Citation*, Code_Of_Conduct*, Codeowners, Contributing*, Contributors, Copying*, Credits, GOVERNANCE.MD, Governance.md, HISTORY.MD, History.md, LICENSE*, License*, MAINTAINERS, Maintainers, README-*, README_*, RELEASE_NOTES*, ROADMAP.MD, Readme-*, Readme_*, Release_Notes*, Roadmap.md, SECURITY.MD, SPONSORS*, Security.md, Sponsors*, authors, backers*, changelog*, citation*, code_of_conduct*, codeowners, contributing*, contributors, copying*, credits, governance.md, history.md, license*, maintainers, readme-*, readme_*, release_notes*, roadmap.md, security.md, sponsors*", 49 + "Dockerfile": "*.dockerfile, .devcontainer.*, .dockerignore, captain-definition, compose.*, docker-compose.*, dockerfile*", 50 + "*.ts": "${basename}.*.${extname}, ${capture}.*.tsx", 51 + "*.tsx": "${basename}*.tsx, ${capture}.*.tsx", 52 + "_index.tsx": "$.tsx", 53 + "app.vue": "app.config.ts" 54 + } 55 + // "[vue]": { 56 + // "editor.defaultFormatter": "dbaeumer.vscode-eslint" 57 + // } 58 + }
+3
README.md
··· 1 + # gm112.neocities.org 2 + 3 + TBD.
+10
app/app.config.ts
··· 1 + export default defineAppConfig({ 2 + ui: { 3 + colors: { 4 + neutral: 'neutral', 5 + }, 6 + main: { 7 + base: 'p-4 sm:p-6 lg:p-8', 8 + }, 9 + }, 10 + })
+8
app/app.vue
··· 1 + <template> 2 + <u-app> 3 + <nuxt-route-announcer /> 4 + <nuxt-layout> 5 + <nuxt-page /> 6 + </nuxt-layout> 7 + </u-app> 8 + </template>
+28
app/assets/animations/rotate.css
··· 1 + @keyframes rotate { 2 + 0% { 3 + transform: translate(0, 0) rotate(0deg) scale(0.75); 4 + } 5 + 25% { 6 + transform: translate(80%, 0) rotate(90deg) scale(0.7); 7 + } 8 + 50% { 9 + transform: translate(80%, 90%) rotate(180deg) scale(0.75); 10 + } 11 + 75% { 12 + transform: translate(0, 90%) rotate(270deg) scale(0.7); 13 + } 14 + 100% { 15 + transform: translate(0, 0) rotate(360deg) scale(0.75); 16 + } 17 + } 18 + 19 + @theme static { 20 + --animate-rotate: rotate; 21 + } 22 + 23 + .animate-rotate { 24 + animation-name: var(--animate-rotate); 25 + animation-duration: 10s; 26 + animation-timing-function: linear; 27 + animation-iteration-count: infinite; 28 + }
+9
app/assets/main.css
··· 1 + @import 'tailwindcss' theme(static); 2 + @import '@nuxt/ui'; 3 + 4 + @import './animations/rotate.css'; 5 + @theme static { 6 + --font-sans: 'Comic Sans MS', system-ui, sans-serif; 7 + --font-serif: 'Comic Sans MS', ui-serif, serif; 8 + --font-mono: 'Comic Sans MS', ui-monospace, monospace; 9 + }
+29
app/components/derp/counter.vue
··· 1 + <template> 2 + <div> 3 + <h3>Counter: {{ count }}</h3> 4 + <button @click="increment"> 5 + Increment 6 + </button> 7 + <button @click="decrement"> 8 + Decrement 9 + </button> 10 + </div> 11 + </template> 12 + 13 + <script setup lang="ts"> 14 + const count = ref(0) 15 + 16 + const increment = () => { 17 + count.value++ 18 + } 19 + 20 + const decrement = () => { 21 + count.value-- 22 + } 23 + </script> 24 + 25 + <style scoped> 26 + button { 27 + margin: 5px; 28 + } 29 + </style>
+18
app/pages/[...slug].vue
··· 1 + <script setup lang="ts"> 2 + const route = useRoute() 3 + 4 + const { data: page } = await useAsyncData('page-' + route.path, () => { 5 + return queryCollection('content').path(route.path).first() 6 + }) 7 + 8 + if (!page.value) { 9 + throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true }) 10 + } 11 + </script> 12 + 13 + <template> 14 + <ContentRenderer 15 + v-if="page" 16 + :value="page" 17 + /> 18 + </template>
+10
content.config.ts
··· 1 + import { defineContentConfig, defineCollection } from '@nuxt/content' 2 + 3 + export default defineContentConfig({ 4 + collections: { 5 + content: defineCollection({ 6 + type: 'page', 7 + source: '**', 8 + }), 9 + }, 10 + })
+3
content/about.mdx
··· 1 + # About Content Version 3 2 + 3 + [Back home](/)
+9
content/index.md
··· 1 + # Howdy 2 + 3 + gm112 waz here. I will make this into a little corner of the internet soon! 4 + 5 + <!-- markdownlint-disable-next-line MD013 --> 6 + 7 + ![sonic](/images/sonic-running.gif){ 8 + class="h-full w-full max-w-lg animate-rotate object-cover" 9 + }
+30
content/test.md
··· 1 + # Welcome to Nuxt Content Starter 2 + 3 + This is the main page displaying Markdown located at [content/index.md](https://github.com/nuxt/starter/blob/content/content/index.md). 4 + 5 + Move to [about](/about) page. 6 + 7 + ## Manage your Contents 8 + 9 + Create new pages or modify the existing ones in `content/` directory. 10 + 11 + ## Query & Render Pages 12 + 13 + You can find an example of querying contents and rendering them in a 14 + [catch-all page](https://github.com/nuxt/starter/blob/content/app/pages/%5B...slug%5D.vue) 15 + 16 + ## Integrate Vue Component 17 + 18 + ::u-alert{icon="i-lucide-info" title="Nuxt Content is optional" color="info"} 19 + #description 20 + The current [alert](https://github.com/nuxt/starter/blob/content/app/components/Alert.vue) 21 + and the [counter](https://github.com/nuxt/starter/blob/content/app/components/Counter.vue) 22 + below are `Vue` components integrated into the Markdown. 23 + :: 24 + :: 25 + 26 + ::derp-counter 27 + :: 28 + 29 + Checkout out the [documentation](https://content.nuxt.com/docs/getting-started) 30 + to learn more.
+6
eslint.config.mjs
··· 1 + // @ts-check 2 + import withNuxt from './.nuxt/eslint.config.mjs' 3 + 4 + export default withNuxt( 5 + // Your custom configs here 6 + )
+1
layers/base/.nuxtrc
··· 1 + compatibilityDate='2026-01-24'
+5
layers/base/layouts/default.vue
··· 1 + <template> 2 + <u-main> 3 + <slot /> 4 + </u-main> 5 + </template>
+39
layers/base/nuxt.config.ts
··· 1 + export default defineNuxtConfig({ 2 + modules: [ 3 + '@nuxt/content', 4 + '@nuxt/eslint', 5 + '@nuxt/image', 6 + '@nuxt/scripts', 7 + '@nuxt/test-utils', 8 + '@nuxt/ui', 9 + '@vite-pwa/nuxt', 10 + ], 11 + $development: { 12 + sourcemap: true, 13 + }, 14 + $meta: { 15 + name: 'org.neocities.gm112.layers.base', 16 + }, 17 + 18 + devtools: { enabled: true }, 19 + sourcemap: false, 20 + future: { 21 + compatibilityVersion: 5, 22 + typescriptBundlerResolution: true, 23 + }, 24 + experimental: { 25 + nitroAutoImports: true, 26 + asyncContext: true, 27 + asyncEntry: true, 28 + }, 29 + compatibilityDate: '2026-01-24', 30 + typescript: { 31 + typeCheck: true, 32 + }, 33 + 34 + eslint: { 35 + config: { 36 + stylistic: true, 37 + }, 38 + }, 39 + })
+6
nuxt.config.ts
··· 1 + // https://nuxt.com/docs/api/configuration/nuxt-config 2 + export default defineNuxtConfig({ 3 + extends: ['org.neocities.gm112.layers.base'], 4 + css: ['@/assets/main.css'], 5 + pwa: {}, 6 + })
+34
package.json
··· 1 + { 2 + "name": "org-neocities-gm112", 3 + "private": true, 4 + "type": "module", 5 + "scripts": { 6 + "build": "nuxt build", 7 + "dev": "nuxt dev", 8 + "generate": "nuxt generate", 9 + "preview": "nuxt preview", 10 + "format": "oxfmt . && eslint . --fix", 11 + "lint": "eslint ." 12 + }, 13 + "dependencies": { 14 + "@nuxt/content": "^3.11.0", 15 + "@nuxt/eslint": "1.13.0", 16 + "@nuxt/image": "2.0.0", 17 + "@nuxt/scripts": "0.13.2", 18 + "@nuxt/test-utils": "3.23.0", 19 + "@nuxt/ui": "4.4.0", 20 + "@vite-pwa/nuxt": "1.1.0", 21 + "better-sqlite3": "^12.6.2", 22 + "nuxt": "^4.3.0" 23 + }, 24 + "devDependencies": { 25 + "@iconify-json/lucide": "^1.2.86", 26 + "eslint": "^9.39.2", 27 + "oxfmt": "^0.26.0", 28 + "tailwindcss": "^4.1.18", 29 + "typescript": "^5.9.3", 30 + "vitest": "^4.0.18", 31 + "vue-tsc": "^3.2.3" 32 + }, 33 + "packageManager": "pnpm@10.28.1+sha512.7d7dbbca9e99447b7c3bf7a73286afaaf6be99251eb9498baefa7d406892f67b879adb3a1d7e687fc4ccc1a388c7175fbaae567a26ab44d1067b54fcb0d6a316" 34 + }
+9
pnpm-workspace.yaml
··· 1 + ignoredBuiltDependencies: 2 + - vue-demi 3 + 4 + onlyBuiltDependencies: 5 + - '@parcel/watcher' 6 + - better-sqlite3 7 + - esbuild 8 + - sharp 9 + - unrs-resolver
public/favicon.ico

This is a binary file and will not be displayed.

public/images/sonic-running.gif

This is a binary file and will not be displayed.

+11
test/e2e/example.test.ts
··· 1 + import { describe, expect, it } from 'vitest' 2 + import { $fetch, setup } from '@nuxt/test-utils/e2e' 3 + 4 + describe('example e2e test', async () => { 5 + await setup() 6 + 7 + it('renders the index page', async () => { 8 + const html = await $fetch('/') 9 + expect(html).toContain('Nuxt') 10 + }) 11 + })
+18
tsconfig.json
··· 1 + { 2 + // https://nuxt.com/docs/guide/concepts/typescript 3 + "files": [], 4 + "references": [ 5 + { 6 + "path": "./.nuxt/tsconfig.app.json" 7 + }, 8 + { 9 + "path": "./.nuxt/tsconfig.server.json" 10 + }, 11 + { 12 + "path": "./.nuxt/tsconfig.shared.json" 13 + }, 14 + { 15 + "path": "./.nuxt/tsconfig.node.json" 16 + } 17 + ] 18 + }