{"id":13523264,"url":"https://github.com/dappblock/nextjs-ic-starter","last_synced_at":"2025-04-01T00:31:18.017Z","repository":{"id":40417495,"uuid":"379596403","full_name":"dappblock/nextjs-ic-starter","owner":"dappblock","description":"Next.js Internet Computer Starter Template","archived":false,"fork":false,"pushed_at":"2025-03-01T08:57:35.000Z","size":542,"stargazers_count":61,"open_issues_count":2,"forks_count":24,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-01T09:27:34.624Z","etag":null,"topics":["canister","dfinity","dfx","ic","internet-computer","javascript","motoko","nextjs","nextjs-starter","nextjs-template","react"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/dappblock.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}},"created_at":"2021-06-23T12:31:22.000Z","updated_at":"2025-03-01T08:54:33.000Z","dependencies_parsed_at":"2024-01-13T22:25:26.211Z","dependency_job_id":null,"html_url":"https://github.com/dappblock/nextjs-ic-starter","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dappblock%2Fnextjs-ic-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dappblock%2Fnextjs-ic-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dappblock%2Fnextjs-ic-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dappblock%2Fnextjs-ic-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dappblock","download_url":"https://codeload.github.com/dappblock/nextjs-ic-starter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246563351,"owners_count":20797441,"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":["canister","dfinity","dfx","ic","internet-computer","javascript","motoko","nextjs","nextjs-starter","nextjs-template","react"],"created_at":"2024-08-01T06:00:58.010Z","updated_at":"2025-04-01T00:31:18.005Z","avatar_url":"https://github.com/dappblock.png","language":"JavaScript","funding_links":[],"categories":["Starters","Front-end"],"sub_categories":["Tutorials and Samples"],"readme":"# Next.js Internet Computer Starter Template\n\nThis project provides a simple starter template for Dfinity Internet Computer using Next.js framework as frontend.\n\n**The Most Recent Updates**\n\n- NextJS 15.2.0\n- DFX 0.25.0\n- NodeJS 22.12.0\n\n**Backend**\n\n- A simple greeting hello world canister written in Motoko\n- ImageBucket canister written in Motoko with create image, delete image and getImageById\n\n**Frontend**\n\n- A simple React HTML form with name input, sending it to greet canister and showing the returned result\n- An Image Upload HTML form with Pick an Image button, upload the image to image canister, loading the image back from the canister and display it using useImageObject React Hook\n\n## Live Demo in IC Mainnet 🥳\n\nhttps://u4gun-5aaaa-aaaah-qabma-cai.raw.ic0.app\n\n![Screenshot](/public/demo-screenshot.png)\n\n## Quick Start (Run locally)\n\nInstall:\n\n- NodeJS 18.\\* or higher https://nodejs.org/en/download/\n- Internet Computer dfx CLI https://internetcomputer.org/docs/current/developer-docs/setup/install/\n- Visual Studio Code (Recommended Code Editor) https://code.visualstudio.com/Download\n- VSCode extension - Motoko (Recommended) https://marketplace.visualstudio.com/items?itemName=dfinity-foundation.vscode-motoko\n\n```bash\nsh -ci \"$(curl -fsSL https://internetcomputer.org/install.sh)\"\n```\n\nClone this Git repository:\n\n```bash\ngit clone https://github.com/dappblock/nextjs-ic-starter\n```\n\nOpen command terminal:\nEnter the commands to start dfx local server in background:\n\n```bash\ncd nextjs-ic-starter\ndfx start --background\n```\n\nNote: If you run it in MacOS, you may be asked to allow connections from dfx local server.\n\nEnter the commands to install dependencies, deploy canister and run Next.js dev server:\n\n```bash\nnpm install\ndfx deploy --network local\nnpm run dev\n```\n\nhttp://localhost:3000/\n\nCleanup - stop dfx server running in background:\n\n```bash\ndfx stop\n```\n\n## Project Structure\n\nInternet Computer has the concept of [Canister](https://smartcontracts.org/docs/current/concepts/canisters-code/) which is a computation unit. This project has 3 canisters:\n\n- hello (backend)\n- image (backend)\n- hello_assets (frontend)\n\nCanister configurations are stored in dfx.json.\n\n### Backend\n\nBackend code is inside /backend/ written in [Motoko language](https://internetcomputer.org/docs/current/motoko/main/motoko-introduction). Motoko is a type-safe language with modern language features like async/await and actor build-in. It also has [Orthogonal persistence](https://internetcomputer.org/docs/current/motoko/main/motoko/#orthogonal-persistence) which I find very interesting.\n\nImage canister is introduced from release v0.2.0. It makes use of orthogonal persistence through stable variables and provides functions for create, delete and get image. See /backend/service/Image.mo.\n\n### Frontend\n\nFrontend code follows Next.js folder convention with /pages storing page React code, /public storing static files including images. This project uses CSS modules for styling which is stored in /ui/styles. React Components are stored in /ui/components\n\nEntry page code is inside /pages/index.js where the magic starts. With the DFX UI declarations generated code, frontend can use RPC style call to server side actor and its functions without worrying about HTTP request and response parsing.\n\nTo generate UI declarations:\n\n```\ndfx generate\n```\n\nIt will generate files in src/declarations for each canister. In our case, it is image, hello and hello_assets but we only need the backend canister image and hello UI declarations here.\n\nThe next step is to adapt it to work with Next.js.\nThe final adapted code is in ui/declaration/hello/index.js.\nYou can also follow the steps below to update it.\n\nBasically, copy image.did.js and index.js from src/declarations/image/\n\n```\ncp src/declarations/image/image.did.js ui/declarations/image/image.did.js\ncp src/declarations/image/index.js ui/declarations/image/index.js\n```\n\nRepeat the same for hello.\n\n```\ncp src/declarations/hello/hello.did.js ui/declarations/hello/hello.did.js\ncp src/declarations/hello/index.js ui/declarations/hello/index.js\n```\n\nThe next step is to update the canister ID env variable in each canister index.js to use NEXT_PUBLIC prefix so that NextJS can recognize when compiling it.\n\nOpen ui/declarations/hello/index.js and look for the line:\n\n```\nexport const canisterId = process.env.HELLO_CANISTER_ID;\n```\n\nUpdate HELLO_CANISTER_ID to NEXT_PUBLIC_HELLO_CANISTER_ID:\n\n```\nexport const canisterId = process.env.NEXT_PUBLIC_HELLO_CANISTER_ID\n```\n\nTo see the final code, check the original ui/declarations in the Git repo.\n\nThe generated UI declarations also support TypeScript if you prefer TypeScript.\n\nWe use a service locator pattern through actor-locator.js that will handle the dfx agent host using env var NEXT_PUBLIC_IC_HOST.\n\nCreating hello actor:\n\n```javascript\nimport { makeHelloActor } from \"../ui/service/actor-adapter\"\nconst hello = makeHelloActor()\n```\n\nCalling hello actor:\n\n```javascript\nconst greeting = await hello.greet(name)\n```\n\nThe beautiful part is you can invoke the hello actor greet function with async/await style as if they are on the same platform. For details, see React Components GreetingSection.js and ImageSection.js in /ui/components/.\n\nWebpack configuration:  \nIn Next.js, it's located in next.config.js.\n\n## React Hook\n\nBy using React Hook with actor UI declaration, it can greatly simplify frontend dev. It encourages component based composable logic. A great example is useImageObject.js React Hook in /ui/hooks. Given an imageId, useImageObject can load the image binary and convert it to a HTML image source object ready for use in \u003cimg\u003e.\n\nIf you look closer, useImageObject.js depends on image-serivce.js which depends on actor-locator.js. When you open ImageSection.js, you can find how useImageObject is being used to greatly reduce the complexity and the underlying calls with Canister. This is the pattern I used very often in my Content Fly Dapp project.\n\n## Backend dev\n\nAfter marking changes in backend code e.g main.mo in /backend/service/hello, you can deploy it to the local DFX server using:\n\n```bash\ndfx deploy hello\n```\n\n**hello** is the backend canister name defined in dfx.json.\n\n## Frontend dev - Next.js Static Code\n\nNext.js developers are familiar with the handy hot code deployed in the Next.js dev environment when making changes in frontend code.\n\nAfter deploying your backend code as shown above, you can run Next.js local dev server **npm run dev** and edit your frontend code with all the benefits of hot code deploy.\n\nOne thing to note is we use Next.js static code export here for hosting in Internet Computer so we can't use any features of Next.js that require server side NodeJS. Potentially, there might be ways to use Internet Computer canister as backend while deploying Next.js dapp to a hosting like Vercel that supports NodeJS server in the future. Further research is needed on that aspect. However, if you do want to run everything decentralized on blockchain including the frontend, you would want to deploy the exported static code to Internet Computer as well.\n\n## Deploy and run frontend in local DFX server\n\nIn order to simulate the whole Internet Computer experience, you can deploy and run frontend code to local DFX server by running:\n\n```bash\ndfx start --background\nnpm run build\ndfx deploy hello_assets\n```\n\n**hello_assets** is the frontend canister defined in dfx.json.\n\n**npm run build** builds and export Next.js as static code storing in **/out** folder which would be picked up by **dfx deploy hello_assets** as defined in dfx.json with **/out** as the source.\n\nWhen it completes, you can open Chrome and browse to:  \nhttp://localhost:8000/?canisterId=[canisterId]\n\nReplace [canisterId] with the hello_assets canister ID which you can find by running:\n\n```bash\ndfx canister id hello_assets\n```\n\n## Environment Configuration\n\nThere are three key configs following Next.js [Environment Variables](https://nextjs.org/docs/basic-features/environment-variables) configuration:\n\n**.env.development** stores configs for use in local dev.\n\n```\nNEXT_PUBLIC_IC_HOST=http://localhost:8000\n```\n\n**.env.production** is used when building and exporting static code using **npm run build**\n\n```\nNEXT_PUBLIC_IC_HOST=http://localhost:8000\n```\n\nNotice both files are identical if we want the Next.js dapp to interact with the local dfx server.\n\nNote **NEXT_PUBLIC** is the prefix used by Next.js to make env vars available to client side code through [build time inlining](https://nextjs.org/docs/basic-features/environment-variables).\n\n**.env.icprod** is included for deployment to Internet Computer ic network which would be covered below.\n\n## Deploy to IC Network Canister\n\nThe most exciting part is to deploy your Next.js / Internet Computer Dapp to production Internet Computer mainnet blockchain network.\n\nTo do that you will need:\n\n- ICP tokens and convert it to [cycles](https://internetcomputer.org/docs/current/concepts/tokens-cycles/)\n- Cycles wallet\n\nFollow the [Network Deployment](https://internetcomputer.org/docs/current/developer-docs/setup/cycles/cycles-wallet/) guide to create a wallet.  \nDfinity offers [free cycle](https://faucet.dfinity.org/) to developers.\n\nNow, you can deploy your Next.js Dapp to Internet Computer IC network by adding **--network ic** to the dfx subcommand. We will first update our env var to point to IC network host. Then deploy the backend canister first, export Next.js static code and deploy frontend canister **hello_assets**.\n\n```bash\ncp .env.icprod .env.production\ndfx deploy --network ic\n```\n\nOpen Chrome and go to https://[canisterId].raw.ic0.app/  \nReplace [canisterId] by the hello_assets canister id in the IC network. You can find it by running:\n\n```bash\ndfx canister --network ic id hello_assets\n```\n\nCongratulations !! Well Done !! 👏 🚀 🎉\n\n## Troubleshooting\n\nUse Chrome Dev Tools / Console / Network. Check if the dapp uses the right canister id and hostname.\n\n## Author\n\nHenry Chan, henry@contentfly.app\nTwitter: @kinwo\n\n## Contributing\n\nPlease feel free to raise an issue or submit a pull request.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdappblock%2Fnextjs-ic-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdappblock%2Fnextjs-ic-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdappblock%2Fnextjs-ic-starter/lists"}