├── public ├── robots.txt ├── favicon.ico ├── img │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── mstile-150x150.png │ ├── apple-touch-icon.png │ ├── android-chrome-192x192.png │ └── android-chrome-512x512.png ├── sw.js ├── manifest.webmanifest ├── 404.html └── index.css ├── .prettierrc ├── wrangler.toml ├── src ├── pages │ ├── users │ │ ├── [id].data.js │ │ └── [id].jsx │ ├── stories │ │ ├── [id].data.js │ │ └── [id].jsx │ ├── [...stories].data.js │ └── [...stories].jsx ├── lib │ └── api.js ├── index.jsx ├── components │ ├── nav.jsx │ ├── comment.jsx │ └── story.jsx └── routes.js ├── index.js ├── .gitignore ├── README.md ├── package.json ├── rollup.config.js ├── worker └── script.js └── pnpm-lock.yaml /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidjs/solid-hackernews/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidjs/solid-hackernews/HEAD/public/img/favicon-16x16.png -------------------------------------------------------------------------------- /public/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidjs/solid-hackernews/HEAD/public/img/favicon-32x32.png -------------------------------------------------------------------------------- /public/img/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidjs/solid-hackernews/HEAD/public/img/mstile-150x150.png -------------------------------------------------------------------------------- /public/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidjs/solid-hackernews/HEAD/public/img/apple-touch-icon.png -------------------------------------------------------------------------------- /public/img/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidjs/solid-hackernews/HEAD/public/img/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/img/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solidjs/solid-hackernews/HEAD/public/img/android-chrome-512x512.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": false, 6 | "printWidth": 100 7 | } -------------------------------------------------------------------------------- /wrangler.toml: -------------------------------------------------------------------------------- 1 | name = "hackernews-csr" 2 | type = "javascript" 3 | workers_dev = true 4 | main = "index.js" 5 | compatibility_date = "2023-12-08" 6 | 7 | [site] 8 | bucket = "./public" -------------------------------------------------------------------------------- /src/pages/users/[id].data.js: -------------------------------------------------------------------------------- 1 | import { cache } from "@solidjs/router"; 2 | import fetchAPI from "../../lib/api"; 3 | 4 | export const getUser = cache((id) => fetchAPI(`user/${id}`), "user"); 5 | 6 | export default ({ params }) => getUser(params.id); 7 | -------------------------------------------------------------------------------- /src/pages/stories/[id].data.js: -------------------------------------------------------------------------------- 1 | import { cache } from "@solidjs/router"; 2 | import fetchAPI from "../../lib/api"; 3 | 4 | export const getStory = cache((id) => fetchAPI(`item/${id}`), "story"); 5 | 6 | export default ({ params }) => getStory(params.id); 7 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { getAssetFromKV, serveSinglePageApp } from '@cloudflare/kv-asset-handler'; 2 | 3 | addEventListener("fetch", event => { 4 | event.respondWith(handleEvent(event)) 5 | }) 6 | 7 | async function handleEvent(event) { 8 | return await getAssetFromKV(event, { mapRequestToAsset: serveSinglePageApp }); 9 | } -------------------------------------------------------------------------------- /public/sw.js: -------------------------------------------------------------------------------- 1 | self.addEventListener("fetch",e=>{(e.request.url.includes("localhost")||e.request.url.includes("solidjs"))&&e.respondWith(caches.open("solid-hn").then(t=>t.match(e.request).then(n=>n||fetch(e.request).then(n=>(t.put(e.request,n.clone()),n)))))}),self.addEventListener("activate",e=>e.waitUntil(caches.delete("solid-hn"))) -------------------------------------------------------------------------------- /src/lib/api.js: -------------------------------------------------------------------------------- 1 | const story = (path) => `https://node-hnapi.herokuapp.com/${path}`; 2 | const user = (path) => 3 | `https://hacker-news.firebaseio.com/v0/${path}.json`; 4 | 5 | export default function fetchAPI(path) { 6 | const url = path.startsWith("user") ? user(path) : story(path); 7 | 8 | return fetch(url).then((r) => r.json()); 9 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | public/* 2 | !public/404.html 3 | !public/index.css 4 | !public/favicon.ico 5 | !public/robots.txt 6 | !public/manifest.webmanifest 7 | !public/img 8 | !public/sw.js 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # IDEs and editors 14 | /.idea 15 | .project 16 | .classpath 17 | *.launch 18 | .settings/ 19 | 20 | #System Files 21 | .DS_Store 22 | Thumbs.db 23 | -------------------------------------------------------------------------------- /src/pages/[...stories].data.js: -------------------------------------------------------------------------------- 1 | import { cache } from "@solidjs/router"; 2 | import fetchAPI from "../lib/api"; 3 | 4 | const mapStories = { 5 | top: "news", 6 | new: "newest", 7 | show: "show", 8 | ask: "ask", 9 | job: "jobs" 10 | }; 11 | 12 | export const getStories = cache( 13 | (type, page) => fetchAPI(`${mapStories[type]}?page=${page}`), 14 | "stories" 15 | ); 16 | 17 | export default ({ location, params }) => 18 | getStories(params.stories || "top", +(location.query.page || 1)); 19 | -------------------------------------------------------------------------------- /public/manifest.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Solid Hackernews", 3 | "short_name": "Solid HN", 4 | "icons": [ 5 | { 6 | "src": "img/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "img/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "/solid-hackernews/", 17 | "background_color": "#f2f3f5", 18 | "display": "standalone", 19 | "theme_color": "#f60" 20 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solid Hacker News 2 | 3 | Demo app based on [Vue Hackernews 2.0](https://github.com/vuejs/vue-hackernews-2.0). Uses Solid and Solid App Router. 4 | 5 | You can view it [here](https://hackernews-csr.ryansolid.workers.dev/). 6 | 7 | ## Testing Locally: 8 | First, you'll need to clone this repo, then cd into the `solid-hackernews` folder 9 | 10 | Then, run `npm install` to install all dependencies 11 | 12 | Lastly, run `npm run start` and the web-app will open in your default browser at `http://localhost:5000/` 13 | 14 | Happy Hacking! 15 | -------------------------------------------------------------------------------- /src/index.jsx: -------------------------------------------------------------------------------- 1 | import { render } from "solid-js/web"; 2 | import { Router } from "@solidjs/router"; 3 | 4 | import routes from "./routes"; 5 | 6 | render( 7 | () => ( 8 | 9 | {routes} 10 | 11 | ), 12 | document.body 13 | ); 14 | 15 | // if ("serviceWorker" in navigator) { 16 | // // Use the window load event to keep the page load performant 17 | // window.addEventListener("load", () => { 18 | // navigator.serviceWorker.register(`${process.env.PUBLIC_URL}sw.js`); 19 | // }); 20 | // } 21 | -------------------------------------------------------------------------------- /src/components/nav.jsx: -------------------------------------------------------------------------------- 1 | export default function Nav() { 2 | return ( 3 |
4 | 24 |
25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | import { lazy } from "solid-js"; 2 | import Nav from "./components/nav"; 3 | import StoriesData from "./pages/[...stories].data"; 4 | import StoryData from "./pages/stories/[id].data"; 5 | import UserData from "./pages/users/[id].data"; 6 | 7 | export default { 8 | path: "", 9 | component: (props) => ( 10 | <> 11 |