{"id":23270104,"url":"https://github.com/xwirkijowski/jals","last_synced_at":"2026-04-12T06:32:47.985Z","repository":{"id":260004611,"uuid":"428735903","full_name":"xwirkijowski/jals","owner":"xwirkijowski","description":"🌐 Just Another Link Shortener - simple link shortener made with React, Next.js and GraphQL","archived":false,"fork":false,"pushed_at":"2025-03-04T11:24:39.000Z","size":4646,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-10T22:12:01.326Z","etag":null,"topics":["api","apollo-graphql","graphql","link-manager","link-shortener","mongodb","mongoose","nextjs","portfolio","react","redis","redis-om","tailwindcss","typescript"],"latest_commit_sha":null,"homepage":"https://jals2.wirkijowski.dev","language":"TypeScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xwirkijowski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-16T16:40:19.000Z","updated_at":"2025-03-08T08:55:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"c480dbaf-eea5-4278-a787-86dc6093f755","html_url":"https://github.com/xwirkijowski/jals","commit_stats":{"total_commits":30,"total_committers":1,"mean_commits":30.0,"dds":0.0,"last_synced_commit":"84282bae527e8bc331a4be6a16b91a6789f36be6"},"previous_names":["xwirkijowski/jals"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/xwirkijowski/jals","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwirkijowski%2Fjals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwirkijowski%2Fjals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwirkijowski%2Fjals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwirkijowski%2Fjals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xwirkijowski","download_url":"https://codeload.github.com/xwirkijowski/jals/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xwirkijowski%2Fjals/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31706764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-12T06:22:27.080Z","status":"ssl_error","status_checked_at":"2026-04-12T06:21:52.710Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","apollo-graphql","graphql","link-manager","link-shortener","mongodb","mongoose","nextjs","portfolio","react","redis","redis-om","tailwindcss","typescript"],"created_at":"2024-12-19T18:39:45.104Z","updated_at":"2026-04-12T06:32:47.965Z","avatar_url":"https://github.com/xwirkijowski.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Header](./header.png)\n\n# JALS / Just Another Link Shortener v2\n\n\u003e [!WARNING]\n\u003e As of 09.02.2025 this project is on the back burner, since all basic functionality that has been planned is now done. I will be moving on to my next project.\n\nA solution for shortening links built with React, Next.js and GraphQL with basic safety features included. Initially designed and developed in 2021 as a personal challenge and to get some new experience.\n\nI began work on a refactor in december 2024. Primary goal was to gain practical knowledge of current React (v19) and Next.js (v15) features, including the new App router. As a secondary goal, client application was to fully leverage TailwindCSS features and implement some subtle animations.\n\nReact and Next.js features used are listed in separate [api](./api/README.md) and [client](./client/README.md) `README.md` files.\n\n\u003e [!NOTE]\n\u003e **Now live!** Current state demo available at [jals2.wirkijowski.dev](https://jals2.wirkijowski.dev/). I recommend creating an account and trying out the dashboard :)\n\n| Deployment |\n|------------|\n| [![CircleCI](https://dl.circleci.com/status-badge/img/circleci/8Np7CK78S4uw4ebGLepWmK/MzQiBDF67dqMd44rGhkv6K/tree/deploy-prod.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/circleci/8Np7CK78S4uw4ebGLepWmK/MzQiBDF67dqMd44rGhkv6K/tree/deploy-prod) |\n\n## Technology stack\n\n###  Client\n\n- **React 19**\n- **Next.js 15** with App router\n- **TypeScript**\n- **Apollo Client** + `experimental-nextjs-app-support` \n- **PostCSS**\n  - Tailwind-CSS\n  - Autoprefixer\n- **Eslint**\n- Motion (Framer Motion)\n- `classnames`, `tailwind-merge` — class utilities\n\n### API server\n\n- **Apollo Server**\n- **GraphQL**\n  - `@graphql-tools` — schema loading and merging utilities\n  - `graphql-scalars` — additional scalars (e.g. `EmailAddress`)\n- **Redis** \u0026 **Redis OM** — Redis client and ORM interface\n- **Mongoose** — ORM interface for MongoDB\n- **Eudoros** - logging utility\n- **Luxon** — date utilities\n- **Resend** — transactional emails\n- **ulid** — internal unique identifiers\n\n### Environment\n\n- Redis-Stack\n- MongoDB Community\n- Docker\n- CircleCI — deployment pipeline\n- Nginx — reverse proxy on remote\n\n#### Observability\n- Sentry.io — error monitoring\n- Axiom — collection of telemetry data, errors and warnings\n\n## Functionality\n\n### Done\n- [x] Session management on both client and api\n- [x] Auth code transactional emails\n- [x] Short link creation\n- [x] Redirection logic with safeguards\n- [x] Link inspection (`/inspect/[linkId]` \u0026 `/[linkId]/+`)\n- [x] Reporting functionality — link flagging\n- [x] User-agent and address collection (`@todo: levarage User-Agent Client Hints API`)\n- [x] Light and dark themes\n- [x] Link management\n- [x] Magic link functionality\n\n### Planned \u0026 In-progress\n- [ ] Transitions, animations\n- [ ] Dashboards\n- [ ] User management\n- [ ] Client to API health checks\n- [ ] Full query error handling\n- [ ] Fully mobile-friendly UI\n\n---\n## Version 1 (2021)\n\n\u003e **See it in action!** Production demo of v1 available at [jals.wirkijowski.dev](https://jals.wirkijowski.dev/)\n\n### Tech stack\n- **Client**\n  - **React** — frontend framework\n  - **React Router** — navigation\n  - **SCSS** — CSS preprocessor\n  - **CSS Modules** — styling approach\n  - **BEM** — class naming methodology\n  - **Apollo Client** — communication with API\n- **API server**\n  - **Apollo Server** — GraphQL server\n  - **Mongoose** — ORM interface for MongoDB\n  - **Ioredis** — Redis client used for cache\n  - **Sentry.io** — monitoring \u0026 error tracking\n  - **Dotenv** — environment variables loader\n\n### Functionality\n- Functional link shortening\n- Link inspection using `+` as a modifier at the end of the URL\n- Collected data included user's platform, if is mobile device and timestamp of click\n- Users were redirected the moment a click is registered (positive response from API)\n- If a link is flagged multiple times, users were warned about it and asked to confirm before proceeding with the redirect.\n\n\n---\n## License\nThis project is not licensed for commercial use. You are free to explore the code, propose changes, and take inspiration, but redistribution or commercial repurposing is not permitted.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxwirkijowski%2Fjals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxwirkijowski%2Fjals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxwirkijowski%2Fjals/lists"}