{"id":26738699,"url":"https://github.com/miroslavpetrik/gnt-starter","last_synced_at":"2025-06-21T04:08:41.960Z","repository":{"id":207212932,"uuid":"718694033","full_name":"MiroslavPetrik/gnt-starter","owner":"MiroslavPetrik","description":"Gel + Next.js + T3 (Tailwind, TypeScript, tRPC) starter","archived":false,"fork":false,"pushed_at":"2025-04-01T17:13:57.000Z","size":1403,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-14T14:56:40.269Z","etag":null,"topics":["edgedb","edgedb-auth","gel","gel-auth","i18next","next-js","react-form-action","tailwind","trpc","typescript"],"latest_commit_sha":null,"homepage":"https://net3-miroslavpetriks-projects.vercel.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MiroslavPetrik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2023-11-14T15:57:53.000Z","updated_at":"2025-04-01T17:14:01.000Z","dependencies_parsed_at":"2024-02-21T12:30:57.564Z","dependency_job_id":"cd302da1-2f38-4823-a6c8-dc7e414dff3d","html_url":"https://github.com/MiroslavPetrik/gnt-starter","commit_stats":null,"previous_names":["miroslavpetrik/net3-starter"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/MiroslavPetrik/gnt-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MiroslavPetrik%2Fgnt-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MiroslavPetrik%2Fgnt-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MiroslavPetrik%2Fgnt-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MiroslavPetrik%2Fgnt-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MiroslavPetrik","download_url":"https://codeload.github.com/MiroslavPetrik/gnt-starter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MiroslavPetrik%2Fgnt-starter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261060154,"owners_count":23103985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["edgedb","edgedb-auth","gel","gel-auth","i18next","next-js","react-form-action","tailwind","trpc","typescript"],"created_at":"2025-03-28T03:36:12.864Z","updated_at":"2025-06-21T04:08:36.943Z","avatar_url":"https://github.com/MiroslavPetrik.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GNT = Gel + Next.js + T3 (Tailwind, TypeScript, tRPC)\n\nThis is Next.js + Gel starter project bootstraped on the [T3 Stack](https://create.t3.gg/)\n\n- [Next.js](https://nextjs.org) Fullstack React framework using the **app router**\n- [Gel](https://www.geldata.com/) Graph-relational database with a custom query language, Auth extension and more\n- [tRPC](https://trpc.io) typesafe end-2-end API definition \u0026 access\n- [Tailwind CSS](https://tailwindcss.com) with [Flowbite React](https://www.flowbite-react.com/) componentss\n- [TypeScript](https://www.typescriptlang.org) language for JavaScript autocompletion\n- [i18next](https://www.i18next.com) localization integrated with [zod-i18n](https://github.com/aiji42/zod-i18n/)\n- [Storybook](https://storybook.js.org) for building \u0026 testing UI in isolation\n\n# Installation Steps\n\nforce install (while the react RC version is used)\n\n```\nnpm i -f\n```\n\n## Gel\n\n### 1. Initiate\n\n`gel project init`\n\n### 2. Configure the Auth extension\n\n#### Set the allowed redirect url via the REPL (run `gel`):\n\n```edgeql\nconfigure current database set ext::auth::AuthConfig::allowed_redirect_urls := {\"http://localhost:3000/\"};\n```\n\n#### Configure email-password Provider\n\nVia `gel ui`\n\n#### Configure SMTP Provider\n\nRequired for `ext::auth` to work.\nEdit the `sandbox.smtp.config.edgeql` with your provider (the default is Mailtrap) and variables.\nRun `npm run db:smtp`.\n\n## Docs\n\n### i18n\n\n- ✅ Works for client \u0026 server components and server actions.\n- ✅ Support for active pathname checks via `useLngPathname()`.\n- ✅ Extraction of translation keys via `i18next-parser`.\n- ✅ Integrated with `zod` both for key translation \u0026 extraction including custom translation keys.\n\n#### Configuration\n\n1. Add your language code into [options array](./src/i18n/options.ts#L5).\n2. Import your `zod` translations and add into [resources map](./src/i18n/options.ts#L12)\n3. Run `npm run i18n` which will create empty folders \u0026 json maps for your locales from added in step 1.\n4. Fill the translations \u0026 commit changes.\n5. 🎉 Your app is translated!\n\n#### Server Components\n\n```tsx\n/**\n * Use the custom RSC Params type which gives you the global `[lng]` param.\n */\nimport { Params } from \"@/types\";\n/**\n * Import the SSR translation helper from a local `i18n` folder.\n * NOTE: the SSR helper is awaited!\n */\nimport { translate } from \"@/i18n\";\n\nexport default async function Page({ params }: Params) {\n  const { lng } = await params;\n  // Specify the feature name as your namespace.\n  // Use the \"global\" namespace for reusable components like Button.\n  const { t } = await translate(\"feature\", lng);\n\n  return \u003ch1\u003e{t(\"title\")}\u003c/h1\u003e;\n}\n```\n\nYou can also use this 'hook' in the server actions. See the [auth actions](./src/app/actions/auth.ts#L27) as an example.\n\n#### Client Components\n\nIn client components, we use the hook `useTranslation()` from a library.\n\n```tsx\nimport { useTranslation } from \"react-i18next\";\n\nexport function CreateUserForm() {\n  const { t } = useTranslation(\"onboarding\");\n}\n```\n\nOn the client side, the import of translation files is handled in the `RootLayout` by the [`\u003cLanguage /\u003e` component](./src/i18n/client.tsx#L33).\n\n#### Client Navigation Components\n\nSince the `[lng]` param is present in every `pathname`, we extend the `usePathame()` from Next.js,\nwith a functionality to strip the prefix away, so you can check for active path easily:\n\n```tsx\n\"use client\";\n/**\n * Import useLngPathname instead of the usePathname\n */\nimport { useLngPathname } from \"@/i18n/use-lng-pathname\";\n/**\n * Get the type for prop which will be passed from the server component params.\n */\nimport { type LanguageParam } from \"@/i18n\";\n\nexport function NavbarLinks({ lng }: LanguageParam) {\n  // pathname no longer contains the lng prefix!\n  const pathname = useLngPathname(lng);\n  const { t } = useTranslation(\"global\");\n\n  // we can check if the path is active without worrying about the language:\n  return (\n    \u003cnav\u003e\n      \u003cNavbarLink href=\"/\" active={pathname === \"/\"}\u003e\n        {t(\"link.home\")}\n      \u003c/NavbarLink\u003e\n      \u003cNavbarLink href=\"/dashboard\" active={pathname.startsWith(\"/dashboard\")}\u003e\n        {t(\"link.dashboard\")}\n      \u003c/NavbarLink\u003e\n    \u003c/nav\u003e\n  );\n}\n```\n\nSee [full code of the `\u003cNavbarLinks /\u003e`](\u003c./src/app/[lng]/(user)/_components/navbar-links.tsx\u003e).\n\n#### Custom Zod Errors\n\nWhen you use `.refine()` API of `zod`, the custom error must be defined in `params` as follows:\n\n```tsx\n/**\n * The local \"t\" function is necessary for the i18next-parser to extract the translation key properly.\n */\nimport { t } from \"@/i18n\";\n\nconst customError = z.string().refine((val) =\u003e val, {\n  // The \"zodError\" namespace here is mandatory \u0026 typechecked\n  // The actual key, will be passed down to the zod-i18n-map which will do the translation.\n  params: { i18n: t(\"zodError:passwordsMustMatch\") },\n});\n```\n\nSee the translation of the [`passwordsMustMatch` refinement](./src/app/actions/auth.ts#L85) .\n\n# FAQ\n\n## How does Next.js communicate with the Gel Auth extension?\n\n[Using the `@gel/auth-nextjs`](https://github.com/edgedb/edgedb-js/tree/master/packages/auth-nextjs)\n\n# Troubleshooting\n\n## Gel\n\n### Database Connection refused when generating `edgeql-js`\n\nThis is related to ipv6 in Node18 (often on Windows 11).\n\n0. Make sure your `node -v` is equal to the one in `.nvmrc`\n\nRun `nvm use` to apply the project node version.\nRun `nvm alias default node` to make it default.\n\n1.  Configure Gel. See [Source](https://github.com/edgedb/edgedb-js/issues/376#issuecomment-1173840632).\n\n```\ngel configure set listen_addresses 127.0.0.1 ::1\n```\n\n2. or [Update operating system routing](https://github.com/nodejs/node/issues/40537#issuecomment-1706257550)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiroslavpetrik%2Fgnt-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmiroslavpetrik%2Fgnt-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiroslavpetrik%2Fgnt-starter/lists"}