{"id":21238698,"url":"https://github.com/shahradelahi/next-extra","last_synced_at":"2025-05-15T00:13:10.751Z","repository":{"id":279459997,"uuid":"812424472","full_name":"shahradelahi/next-extra","owner":"shahradelahi","description":"⚡ Enhance Next.js Beyond Limits","archived":false,"fork":false,"pushed_at":"2025-04-05T03:27:05.000Z","size":134,"stargazers_count":481,"open_issues_count":7,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-06T18:11:22.250Z","etag":null,"topics":["nextjs","react","typescript"],"latest_commit_sha":null,"homepage":"https://npmjs.com/next-extra","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/shahradelahi.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}},"created_at":"2024-06-08T21:16:04.000Z","updated_at":"2025-04-03T17:45:22.000Z","dependencies_parsed_at":"2025-03-13T08:20:23.905Z","dependency_job_id":"36f3d9a6-1e52-435e-9dee-8b8eee02ae67","html_url":"https://github.com/shahradelahi/next-extra","commit_stats":null,"previous_names":["shahradelahi/next-extra"],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahradelahi%2Fnext-extra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahradelahi%2Fnext-extra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahradelahi%2Fnext-extra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahradelahi%2Fnext-extra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shahradelahi","download_url":"https://codeload.github.com/shahradelahi/next-extra/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248784796,"owners_count":21161180,"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":["nextjs","react","typescript"],"created_at":"2024-11-21T00:37:48.033Z","updated_at":"2025-04-13T21:28:41.037Z","avatar_url":"https://github.com/shahradelahi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n\u003csup\u003eNext.JS EXTRA\u003c/sup\u003e\n\u003cbr\u003e\n\u003ca href=\"https://github.com/shahradelahi/next-extra/actions/workflows/ci.yml\" title=\"Build status\"\u003e\u003cimg src=\"https://github.com/shahradelahi/next-extra/actions/workflows/ci.yml/badge.svg\" alt=\"Build status\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/next-extra\" title=\"NPM Version\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/next-extra\" alt=\"npm\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/next-extra\" title=\"Downloads\"\u003e\u003cimg alt=\"NPM Downloads\" src=\"https://img.shields.io/npm/dm/next-extra.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opensource.org/licenses/MIT\" title=\"License\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-blue.svg?style=flat\" alt=\"MIT Licensed\"\u003e\u003c/a\u003e\n\u003c/h1\u003e\n\n_next-extra_ is a utility package that allows you to enhance your Next.js projects with additional methods not found in the core package.\n\n---\n\n- [Installation](#-installation)\n- [Usage](#-usage)\n  - [`next-extra/action`](#next-extraaction)\n  - [`next-extra/context`](#next-extracontext)\n  - [`next-extra/pathname`](#next-extrapathname)\n- [Contributing](#-contributing)\n- [Relevant](#relevant)\n- [License](#license)\n- [Notice of Non-Affiliation and Disclaimer](#notice-of-non-affiliation-and-disclaimer)\n\n## 📦 Installation\n\n```bash\nnpm install next-extra\n```\n\n## 📖 Usage\n\n### `next-extra/action`\n\n###### API\n\n```typescript\nfunction createAction(fn: Function): ActionFunc;\nfunction actionError(code: string, message: string): never;\nfunction cookies(): ResponseCookies;\nfunction clientIP(): Promise\u003cstring | null\u003e;\n```\n\n###### Example\n\n```typescript jsx\n// -- actions.ts\n'use server';\n\nimport { actionError, createAction } from 'next-extra/action';\n\nexport const hello = createAction(async (name: string) =\u003e {\n  if (!name) {\n    actionError('NAME_REQUIRED', 'Name is required');\n  }\n  return `Hello, ${name}!`;\n});\n```\n\n```typescript jsx\n// -- page.tsx\nimport { hello } from './actions';\n\nexport default async function Page() {\n  const { data, error } = await hello('John');\n  if (error) {\n    return \u003ch1\u003eERROR: {error.message}\u003c/h1\u003e;\n  }\n  return \u003ch1\u003e{data}\u003c/h1\u003e;\n}\n```\n\n### `next-extra/context`\n\nThis module provides utilities for passing serializable data from the **server layout** to **client page components** in the Next.js [App Router](https://nextjs.org/docs/app). It is particularly useful for sharing context-specific data across your application without the need to re-fetch data, thereby saving computing resources and improving performance.\n\n###### API\n\n```typescript\nfunction PageContext\u003cT\u003e(props: PageContextProps\u003cT\u003e): JSX.Element;\nfunction usePageContext\u003cT\u003e(): Readonly\u003cT\u003e;\nfunction useServerInsertedContext\u003cT\u003e(): Readonly\u003cT | undefined\u003e;\n```\n\n###### Example\n\n```typescript jsx\n// -- layout.tsx\nimport { PageContext } from 'next-extra/context';\n\nexport default async function RootLayout({ children }: { children: React.ReactNode }) {\n  return \u003cPageContext data={{ ts: Date.now() }}\u003e{children}\u003c/PageContext\u003e;\n}\n```\n\n```typescript jsx\n// -- quotes/layout.tsx\nimport { PageContext } from 'next-extra/context';\n\nexport default async function Layout({ children }: { children: React.ReactNode }) {\n  return \u003cPageContext data={{ quote: 'Guillermo Rauch is a handsome dude!' }}\u003e{children}\u003c/PageContext\u003e;\n}\n```\n\n```typescript jsx\n// -- quotes/page.tsx\n'use client';\n\nimport { useServerInsertedContext, usePageContext } from 'next-extra/context';\n\ninterface Context {\n  message: string;\n}\n\ninterface InsertedContext extends Context {\n  ts: number;\n}\n\nexport default function Page() {\n  const insertedCtx = useServerInsertedContext\u003cInsertedContext\u003e();\n  console.log(insertedCtx); // undefined in server or Object { ts: ..., message: \"...\" }\n\n  const ctx = usePageContext\u003cContext\u003e();\n  console.log(ctx); // Object { message: \"...\" }\n\n  return \u003ch3\u003eMessage: {ctx.message}\u003c/h3\u003e;\n}\n```\n\n### `next-extra/pathname`\n\nAccess `pathname` and `searchParams` of the incoming request for server-side components in the [App Router](https://nextjs.org/docs/app).\n\n###### API\n\n```typescript\nfunction pathname(): Promise\u003cstring\u003e;\nfunction searchParams(): Promise\u003cReadonlyURLSearchParams\u003e;\n```\n\n###### Example\n\n```typescript\nimport { pathname, searchParams } from 'next-extra/pathname';\n\nexport default async function Layout({\n  children,\n}: Readonly\u003c{ children: React.ReactNode }\u003e) {\n  // Assuming a request to \"/hello?name=John\"\n\n  const route = await pathname(); // /hello\n  const params = await searchParams(); // ReadonlyURLSearchParams { 'name' =\u003e 'John' }\n\n  return children;\n}\n```\n\n## 🤝 Contributing\n\nWant to contribute? Awesome! To show your support is to star the project, or to raise issues on [GitHub](https://github.com/shahradelahi/next-extra).\n\nThanks again for your support, it is much appreciated! 🙏\n\n## Relevant\n\n- [NextJs CSRF Protection](https://github.com/shahradelahi/next-csrf)\n\n## License\n\n[MIT](/LICENSE) © [Shahrad Elahi](https://github.com/shahradelahi)\n\n## Notice of Non-Affiliation and Disclaimer\n\nThis project, [`next-extra`](https://github.com/shahradelahi/next-extra), is an independent, community-driven project and is not affiliated with, endorsed by, or sponsored by Vercel, the creators of Next.js. Next.js is a registered trademark of Vercel, Inc.\n\nThis project utilizes the Next.js framework but is not a part of the official Next.js distribution. Any features, functionalities, or integrations provided by [`next-extra`](https://github.com/shahradelahi/next-extra) are solely the responsibility of the project maintainers and contributors. Vercel and the Next.js team hold no responsibility for the content, quality, or support of this project.\n\nWhile we strive to ensure compatibility and proper functionality with Next.js, there is no guarantee of seamless integration or continued support in future Next.js releases. Use of [`next-extra`](https://github.com/shahradelahi/next-extra) is at your own discretion and risk. We recommend thoroughly testing this project in your environment before deploying it to production.\n\nAll trademarks, service marks, and registered trademarks are the property of their respective owners. The use of any third-party names or trademarks in this project is for identification purposes only and does not imply any affiliation or endorsement.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshahradelahi%2Fnext-extra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshahradelahi%2Fnext-extra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshahradelahi%2Fnext-extra/lists"}