[{"data":1,"prerenderedAt":2449},["ShallowReactive",2],{"post-\u002Fposts\u002Fthe-perfect-guide-to-setting-up-a-new-nuxt-project":3,"post-link-en-external":2444},{"id":4,"title":5,"body":6,"contentId":2437,"date":2438,"description":2439,"extension":2440,"meta":2441,"navigation":1027,"path":2442,"rawbody":2443,"robots":2444,"schemaOrg":2444,"seo":2445,"sitemap":2446,"stem":2447,"__hash__":2448},"posts\u002Fposts\u002Fthe-perfect-guide-to-setting-up-a-new-nuxt-project.md","The Perfect Guide to Setting Up a New Nuxt Project",{"type":7,"value":8,"toc":2428},"minimark",[9,21,28,33,39,79,98,112,123,127,130,145,167,170,177,245,252,262,287,297,2424],[10,11,12,13,17,18,20],"p",{},"Every time I create a new ",[14,15,16],"strong",{},"Nuxt"," project, I follow specific steps to ensure an optimal setup. I've been working with ",[14,19,16],{}," since 2019 and have developed specific habits when initiating new projects.",[10,22,23,24,27],{},"Through my experience, I've explored numerous modules and reviewed projects from both experts and beginners. This has given me a solid understanding of what works well in the ",[14,25,26],{},"Nuxt ecosystem",". Setting up a new project can be daunting, especially for newcomers, so I've decided to share this guide to help you set up your Nuxt project as efficiently as possible.",[29,30,32],"h2",{"id":31},"creating-a-new-nuxt-project","Creating a new Nuxt project",[10,34,35,36,38],{},"Let's begin with creating a new ",[14,37,16],{}," project. This is the simplest step, requiring just one command:",[40,41,46],"pre",{"className":42,"code":43,"language":44,"meta":45,"style":45},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx nuxi@latest init \u003Cproject-name>\n","bash","",[47,48,49],"code",{"__ignoreMap":45},[50,51,54,58,62,65,69,72,76],"span",{"class":52,"line":53},"line",1,[50,55,57],{"class":56},"sBMFI","npx",[50,59,61],{"class":60},"sfazB"," nuxi@latest",[50,63,64],{"class":60}," init",[50,66,68],{"class":67},"sMK4o"," \u003C",[50,70,71],{"class":60},"project-nam",[50,73,75],{"class":74},"sTEyZ","e",[50,77,78],{"class":67},">\n",[80,81,82],"blockquote",{},[10,83,84,87,88,91,92,97],{},[50,85,86],{},"!TIP","\nYou can also create a v4 ready project with ",[47,89,90],{},"npx nuxi init nuxt-app -t v4-compat",", avoiding the need for ",[93,94,96],"a",{"href":95},"#prepare-for-nuxt-4","Prepare for Nuxt 4",".",[80,99,100],{},[10,101,102,105,106,109,110,97],{},[50,103,104],{},"!NOTE","\nI always choose ",[14,107,108],{},"pnpm"," as my package manager. You can select the one you prefer, but I recommend trying ",[14,111,108],{},[10,113,114,115,118,119,122],{},"Running this command will scaffold a new Nuxt project within the ",[47,116,117],{},"\u003Cproject-name>"," directory. The app is minimalistic, no configuration, no modules, just Nuxt and an ",[47,120,121],{},"app.vue"," file.",[29,124,126],{"id":125},"update-the-dependencies","Update the dependencies",[10,128,129],{},"Before proceeding, it's essential to update dependencies to their latest versions. This ensures you can leverage the newest features and bug fixes while avoiding issues that outdated dependencies might cause. Execute the following command to update them:",[40,131,133],{"className":42,"code":132,"language":44,"meta":45,"style":45},"npx taze -w\n",[47,134,135],{"__ignoreMap":45},[50,136,137,139,142],{"class":52,"line":53},[50,138,57],{"class":56},[50,140,141],{"class":60}," taze",[50,143,144],{"class":60}," -w\n",[10,146,147,148,151,152,158,159,162,163,166],{},"The ",[14,149,150],{},"taze"," package, developed by ",[93,153,157],{"href":154,"rel":155},"https:\u002F\u002Fantfu.me",[156],"nofollow","Anthony Fu",", updates all dependencies to their latest versions. It's similar to ",[47,160,161],{},"npm-check-updates"," but more powerful due to its adherence to ",[14,164,165],{},"semver"," versioning, offering both speed and reliability.",[29,168,96],{"id":169},"prepare-for-nuxt-4",[10,171,172,173,176],{},"Currently, the latest stable version of Nuxt is version 3. However, version 4 is in development and promises numerous features and enhancements. Although not officially released, you can prepare your projects for this future update by adding the following configuration in your ",[47,174,175],{},"nuxt.config.js",":",[40,178,182],{"className":179,"code":180,"language":181,"meta":45,"style":45},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  future: {\n    compatibilityVersion: 4,\n  }\n})\n","ts",[47,183,184,203,215,230,236],{"__ignoreMap":45},[50,185,186,190,193,197,200],{"class":52,"line":53},[50,187,189],{"class":188},"s7zQu","export",[50,191,192],{"class":188}," default",[50,194,196],{"class":195},"s2Zo4"," defineNuxtConfig",[50,198,199],{"class":74},"(",[50,201,202],{"class":67},"{\n",[50,204,206,210,212],{"class":52,"line":205},2,[50,207,209],{"class":208},"swJcz","  future",[50,211,176],{"class":67},[50,213,214],{"class":67}," {\n",[50,216,218,221,223,227],{"class":52,"line":217},3,[50,219,220],{"class":208},"    compatibilityVersion",[50,222,176],{"class":67},[50,224,226],{"class":225},"sbssI"," 4",[50,228,229],{"class":67},",\n",[50,231,233],{"class":52,"line":232},4,[50,234,235],{"class":67},"  }\n",[50,237,239,242],{"class":52,"line":238},5,[50,240,241],{"class":67},"}",[50,243,244],{"class":74},")\n",[10,246,247,248,251],{},"This setup enables you to start developing your projects as though you're already using ",[14,249,250],{},"Nuxt 4",". This foresight not only allows you to benefit from upcoming features but also minimizes the work required to upgrade when Nuxt 4 is released.",[10,253,254,255,258,259,261],{},"To make the most of Nuxt 4, create a new ",[47,256,257],{},"app"," folder and move the ",[47,260,121],{}," file into it:",[40,263,265],{"className":42,"code":264,"language":44,"meta":45,"style":45},"mkdir app && mv app.vue app\n",[47,266,267],{"__ignoreMap":45},[50,268,269,272,275,278,281,284],{"class":52,"line":53},[50,270,271],{"class":56},"mkdir",[50,273,274],{"class":60}," app",[50,276,277],{"class":67}," &&",[50,279,280],{"class":56}," mv",[50,282,283],{"class":60}," app.vue",[50,285,286],{"class":60}," app\n",[80,288,289],{},[10,290,291,293,294,296],{},[50,292,86],{},"\nYou can also create a v4 ready project by using the ",[47,295,90],{}," command.",[298,299,302,306,309,344,360,426,433,466,473,544,555,570,574,580,585,600],"callout-read-more",{"text":300,"href":301},"Upgrading to Nuxt 4","https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fupgrade#opting-in-to-nuxt-4",[29,303,305],{"id":304},"linting-and-formatting","Linting and formatting",[10,307,308],{},"Nuxt provides an excellent developer experience for linting and formatting. Install both the linter and the formatter with the following command:",[40,310,312],{"className":42,"code":311,"language":44,"meta":45,"style":45},"npx nuxi module add eslint && npx @antfu\u002Fni -D typescript\n",[47,313,314],{"__ignoreMap":45},[50,315,316,318,321,324,327,330,332,335,338,341],{"class":52,"line":53},[50,317,57],{"class":56},[50,319,320],{"class":60}," nuxi",[50,322,323],{"class":60}," module",[50,325,326],{"class":60}," add",[50,328,329],{"class":60}," eslint",[50,331,277],{"class":67},[50,333,334],{"class":56}," npx",[50,336,337],{"class":60}," @antfu\u002Fni",[50,339,340],{"class":60}," -D",[50,342,343],{"class":60}," typescript\n",[10,345,346,347,350,351,356,357,176],{},"This command installs the ",[47,348,349],{},"@nuxt\u002Feslint"," module, which offers a ",[93,352,355],{"href":353,"rel":354},"https:\u002F\u002Feslint.nuxt.com",[156],"0-config ESLint setup for Nuxt"," projects. Enable formatting, and it will automatically fix issues upon saving a file. I always configure it in my ",[47,358,359],{},"nuxt.config.ts",[40,361,364],{"className":362,"code":363,"language":181,"meta":45,"style":45},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight has-highlighted","export default defineNuxtConfig({\n  eslint: {\n    config: {\n      stylistic: true \u002F\u002F [!code highlight]\n    }\n  }\n})\n",[47,365,366,378,387,396,409,414,419],{"__ignoreMap":45},[50,367,368,370,372,374,376],{"class":52,"line":53},[50,369,189],{"class":188},[50,371,192],{"class":188},[50,373,196],{"class":195},[50,375,199],{"class":74},[50,377,202],{"class":67},[50,379,380,383,385],{"class":52,"line":205},[50,381,382],{"class":208},"  eslint",[50,384,176],{"class":67},[50,386,214],{"class":67},[50,388,389,392,394],{"class":52,"line":217},[50,390,391],{"class":208},"    config",[50,393,176],{"class":67},[50,395,214],{"class":67},[50,397,400,403,405],{"class":398,"line":232},[52,399],"highlighted",[50,401,402],{"class":208},"      stylistic",[50,404,176],{"class":67},[50,406,408],{"class":407},"sfNiH"," true",[50,410,411],{"class":52,"line":238},[50,412,413],{"class":67},"    }\n",[50,415,417],{"class":52,"line":416},6,[50,418,235],{"class":67},[50,420,422,424],{"class":52,"line":421},7,[50,423,241],{"class":67},[50,425,244],{"class":74},[10,427,428,429,432],{},"Additionally, create a ",[47,430,431],{},".vscode\u002Fsettings.json"," file to disable the prettier extension, preventing conflicts with the ESLint formatter:",[40,434,438],{"className":435,"code":436,"language":437,"meta":45,"style":45},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"prettier.enable\": false\n}\n","json",[47,439,440,444,461],{"__ignoreMap":45},[50,441,442],{"class":52,"line":53},[50,443,202],{"class":67},[50,445,446,449,453,456,458],{"class":52,"line":205},[50,447,448],{"class":67},"  \"",[50,450,452],{"class":451},"spNyl","prettier.enable",[50,454,455],{"class":67},"\"",[50,457,176],{"class":67},[50,459,460],{"class":67}," false\n",[50,462,463],{"class":52,"line":217},[50,464,465],{"class":67},"}\n",[10,467,468,469,472],{},"Add two scripts to your ",[47,470,471],{},"package.json"," file:",[40,474,476],{"className":435,"code":475,"language":437,"meta":45,"style":45},"{\n  \"scripts\": {\n    \"lint\": \"eslint .\",\n    \"lint:fix\": \"eslint --fix .\"\n  }\n}\n",[47,477,478,482,495,517,536,540],{"__ignoreMap":45},[50,479,480],{"class":52,"line":53},[50,481,202],{"class":67},[50,483,484,486,489,491,493],{"class":52,"line":205},[50,485,448],{"class":67},[50,487,488],{"class":451},"scripts",[50,490,455],{"class":67},[50,492,176],{"class":67},[50,494,214],{"class":67},[50,496,497,500,503,505,507,510,513,515],{"class":52,"line":217},[50,498,499],{"class":67},"    \"",[50,501,502],{"class":56},"lint",[50,504,455],{"class":67},[50,506,176],{"class":67},[50,508,509],{"class":67}," \"",[50,511,512],{"class":60},"eslint .",[50,514,455],{"class":67},[50,516,229],{"class":67},[50,518,519,521,524,526,528,530,533],{"class":52,"line":232},[50,520,499],{"class":67},[50,522,523],{"class":56},"lint:fix",[50,525,455],{"class":67},[50,527,176],{"class":67},[50,529,509],{"class":67},[50,531,532],{"class":60},"eslint --fix .",[50,534,535],{"class":67},"\"\n",[50,537,538],{"class":52,"line":238},[50,539,235],{"class":67},[50,541,542],{"class":52,"line":416},[50,543,465],{"class":67},[10,545,546,547,550,551,554],{},"Now, you can run ",[47,548,549],{},"pnpm run lint"," to check for issues and ",[47,552,553],{},"pnpm run lint:fix"," to automatically fix them.",[10,556,557,558,561,562,565,566,569],{},"These predefined configurations make it straightforward to set up ",[14,559,560],{},"ESLint"," with ",[14,563,564],{},"TypeScript"," and ",[14,567,568],{},"Vue"," support, ensuring consistent and clean code.",[29,571,573],{"id":572},"ui-and-components","UI and components",[10,575,576,577,579],{},"With a clean project setup, the latest dependencies, preparation for ",[14,578,250],{},", and robust linting and formatting, it's time to focus on UI and components. This step varies based on project objectives and design requirements.",[581,582,584],"h3",{"id":583},"nuxt-ui-and-nuxt-ui-pro","Nuxt UI and Nuxt UI Pro",[10,586,587,588,593,594,599],{},"If the project emphasizes business logic over UI, I use the ",[93,589,592],{"href":590,"rel":591},"https:\u002F\u002Fui.nuxt.com",[156],"Nuxt UI"," and Nuxt UI Pro component libraries. They are well-designed and easy to use. Reading the ",[93,595,598],{"href":596,"rel":597},"https:\u002F\u002Fgithub.com\u002Fnuxt\u002Fui",[156],"Nuxt UI source code"," is insightful, and I also have an article on building a component library with Vue.",[298,601,603,610,613,630,635,679,685,719,724,765,776,860,871,927,934,938,950,953,970,976,993,998,1104,1113,1189,1192,1196,1205,1208,1211,1224,1242,1245,1256,1272,1279,1412,1417,1444,1450,1454,1466,1484,1487,1491,1498,1508,1761,1769,1993,1997,2006,2012,2052,2055,2059,2062,2066,2076,2139,2143,2156,2194,2205,2215,2229,2275,2292,2298,2306,2315,2337,2344,2349],{"id":602},"55d2cdcf-ba27-4bfe-9bc1-492e866ff3b1",[80,604,605],{},[10,606,607,609],{},[50,608,104],{},"\nAs of writing, Nuxt UI 3 is not officially released, but it can be used in projects. If you're reading this later, let me know in the comments, and I'll update this guide.",[10,611,612],{},"First, install Nuxt UI and Tailwind CSS:",[40,614,616],{"className":42,"code":615,"language":44,"meta":45,"style":45},"pnpm add @nuxt\u002Fui@next tailwindcss@next\n",[47,617,618],{"__ignoreMap":45},[50,619,620,622,624,627],{"class":52,"line":53},[50,621,108],{"class":56},[50,623,326],{"class":60},[50,625,626],{"class":60}," @nuxt\u002Fui@next",[50,628,629],{"class":60}," tailwindcss@next\n",[10,631,632,633,472],{},"Add the module to your ",[47,634,359],{},[40,636,638],{"className":179,"code":637,"language":181,"meta":45,"style":45},"export default defineNuxtConfig({\n  modules: ['@nuxt\u002Fui']\n})\n",[47,639,640,652,673],{"__ignoreMap":45},[50,641,642,644,646,648,650],{"class":52,"line":53},[50,643,189],{"class":188},[50,645,192],{"class":188},[50,647,196],{"class":195},[50,649,199],{"class":74},[50,651,202],{"class":67},[50,653,654,657,659,662,665,668,670],{"class":52,"line":205},[50,655,656],{"class":208},"  modules",[50,658,176],{"class":67},[50,660,661],{"class":74}," [",[50,663,664],{"class":67},"'",[50,666,667],{"class":60},"@nuxt\u002Fui",[50,669,664],{"class":67},[50,671,672],{"class":74},"]\n",[50,674,675,677],{"class":52,"line":217},[50,676,241],{"class":67},[50,678,244],{"class":74},[10,680,681,682,472],{},"Import necessary CSS in your ",[47,683,684],{},"app\u002Fassets\u002Fcss\u002Fmain.css",[40,686,690],{"className":687,"code":688,"language":689,"meta":45,"style":45},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","@import \"tailwindcss\";\n@import \"@nuxt\u002Fui\";\n","css",[47,691,692,707],{"__ignoreMap":45},[50,693,694,697,699,702,704],{"class":52,"line":53},[50,695,696],{"class":188},"@import",[50,698,509],{"class":67},[50,700,701],{"class":60},"tailwindcss",[50,703,455],{"class":67},[50,705,706],{"class":67},";\n",[50,708,709,711,713,715,717],{"class":52,"line":205},[50,710,696],{"class":188},[50,712,509],{"class":67},[50,714,667],{"class":60},[50,716,455],{"class":67},[50,718,706],{"class":67},[10,720,721,722,472],{},"Ensure this CSS file is included in the ",[47,723,359],{},[40,725,727],{"className":179,"code":726,"language":181,"meta":45,"style":45},"export default defineNuxtConfig({\n  css: ['~\u002Fassets\u002Fcss\u002Fmain.css']\n})\n",[47,728,729,741,759],{"__ignoreMap":45},[50,730,731,733,735,737,739],{"class":52,"line":53},[50,732,189],{"class":188},[50,734,192],{"class":188},[50,736,196],{"class":195},[50,738,199],{"class":74},[50,740,202],{"class":67},[50,742,743,746,748,750,752,755,757],{"class":52,"line":205},[50,744,745],{"class":208},"  css",[50,747,176],{"class":67},[50,749,661],{"class":74},[50,751,664],{"class":67},[50,753,754],{"class":60},"~\u002Fassets\u002Fcss\u002Fmain.css",[50,756,664],{"class":67},[50,758,672],{"class":74},[50,760,761,763],{"class":52,"line":217},[50,762,241],{"class":67},[50,764,244],{"class":74},[10,766,767,768,770,771,176],{},"Update your ",[47,769,431],{}," file to enhance experience with the ",[93,772,775],{"href":773,"rel":774},"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=bradlc.vscode-tailwindcss",[156],"Tailwind CSS IntelliSense extension",[40,777,779],{"className":435,"code":778,"language":437,"meta":45,"style":45},"{\n  \"files.associations\": {\n    \"*.css\": \"tailwindcss\"\n  },\n  \"editor.quickSuggestions\": {\n    \"strings\": \"on\"\n  }\n}\n",[47,780,781,785,798,815,820,833,851,855],{"__ignoreMap":45},[50,782,783],{"class":52,"line":53},[50,784,202],{"class":67},[50,786,787,789,792,794,796],{"class":52,"line":205},[50,788,448],{"class":67},[50,790,791],{"class":451},"files.associations",[50,793,455],{"class":67},[50,795,176],{"class":67},[50,797,214],{"class":67},[50,799,800,802,805,807,809,811,813],{"class":52,"line":217},[50,801,499],{"class":67},[50,803,804],{"class":56},"*.css",[50,806,455],{"class":67},[50,808,176],{"class":67},[50,810,509],{"class":67},[50,812,701],{"class":60},[50,814,535],{"class":67},[50,816,817],{"class":52,"line":232},[50,818,819],{"class":67},"  },\n",[50,821,822,824,827,829,831],{"class":52,"line":238},[50,823,448],{"class":67},[50,825,826],{"class":451},"editor.quickSuggestions",[50,828,455],{"class":67},[50,830,176],{"class":67},[50,832,214],{"class":67},[50,834,835,837,840,842,844,846,849],{"class":52,"line":416},[50,836,499],{"class":67},[50,838,839],{"class":56},"strings",[50,841,455],{"class":67},[50,843,176],{"class":67},[50,845,509],{"class":67},[50,847,848],{"class":60},"on",[50,850,535],{"class":67},[50,852,853],{"class":52,"line":421},[50,854,235],{"class":67},[50,856,858],{"class":52,"line":857},8,[50,859,465],{"class":67},[10,861,862,863,866,867,870],{},"Lastly, modify your ",[47,864,865],{},"app\u002Fapp.vue"," file to include the Nuxt UI component ",[47,868,869],{},"\u003CUApp>",", automatically injecting global components:",[40,872,876],{"className":873,"code":874,"language":875,"meta":45,"style":45},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Ctemplate>\n  \u003CUApp>\n    \u003CNuxtPage \u002F>\n  \u003C\u002FUApp>\n\u003C\u002Ftemplate>\n","vue",[47,877,878,888,898,909,918],{"__ignoreMap":45},[50,879,880,883,886],{"class":52,"line":53},[50,881,882],{"class":67},"\u003C",[50,884,885],{"class":208},"template",[50,887,78],{"class":67},[50,889,890,893,896],{"class":52,"line":205},[50,891,892],{"class":67},"  \u003C",[50,894,895],{"class":208},"UApp",[50,897,78],{"class":67},[50,899,900,903,906],{"class":52,"line":217},[50,901,902],{"class":67},"    \u003C",[50,904,905],{"class":208},"NuxtPage",[50,907,908],{"class":67}," \u002F>\n",[50,910,911,914,916],{"class":52,"line":232},[50,912,913],{"class":67},"  \u003C\u002F",[50,915,895],{"class":208},[50,917,78],{"class":67},[50,919,920,923,925],{"class":52,"line":238},[50,921,922],{"class":67},"\u003C\u002F",[50,924,885],{"class":208},[50,926,78],{"class":67},[80,928,929],{},[10,930,931,933],{},[50,932,104],{},"\nNuxt UI Pro is a paid extension offering layout components for rapid app development. It's a worthwhile investment that saves time and effort, while supporting the Nuxt team and open-source development. 💚",[581,935,937],{"id":936},"tailwind-css","Tailwind CSS",[10,939,940,941,945,946,949],{},"For projects requiring specific designs or when collaborating with designers, I turn to ",[93,942,937],{"href":943,"rel":944},"https:\u002F\u002Ftailwindcss.com",[156],". It's a utility-first CSS framework that streamlines the design process to such an extent that working without it is unimaginable. The upcoming version, Tailwind CSS 4, includes an indispensable ",[14,947,948],{},"Vite"," plugin, eliminating the need for additional modules and simplifying the setup.",[10,951,952],{},"Install the latest Tailwind CSS version:",[40,954,956],{"className":42,"code":955,"language":44,"meta":45,"style":45},"pnpm add tailwindcss@next @tailwindcss\u002Fvite@next\n",[47,957,958],{"__ignoreMap":45},[50,959,960,962,964,967],{"class":52,"line":53},[50,961,108],{"class":56},[50,963,326],{"class":60},[50,965,966],{"class":60}," tailwindcss@next",[50,968,969],{"class":60}," @tailwindcss\u002Fvite@next\n",[10,971,972,973,975],{},"Create an ",[47,974,684],{}," file and import Tailwind CSS:",[40,977,979],{"className":687,"code":978,"language":689,"meta":45,"style":45},"@import \"tailwindcss\";\n",[47,980,981],{"__ignoreMap":45},[50,982,983,985,987,989,991],{"class":52,"line":53},[50,984,696],{"class":188},[50,986,509],{"class":67},[50,988,701],{"class":60},[50,990,455],{"class":67},[50,992,706],{"class":67},[10,994,767,995,997],{},[47,996,359],{}," file to utilize the Vite plugin:",[40,999,1001],{"className":179,"code":1000,"language":181,"meta":45,"style":45},"import Tailwind from '@tailwindcss\u002Fvite'\n\nexport default defineNuxtConfig({\n  css: ['~\u002Fassets\u002Fcss\u002Fmain.css'],\n  vite: {\n    plugins: [\n      Tailwind()\n    ]\n  }\n})\n",[47,1002,1003,1023,1029,1041,1060,1069,1079,1087,1092,1097],{"__ignoreMap":45},[50,1004,1005,1008,1011,1014,1017,1020],{"class":52,"line":53},[50,1006,1007],{"class":188},"import",[50,1009,1010],{"class":74}," Tailwind ",[50,1012,1013],{"class":188},"from",[50,1015,1016],{"class":67}," '",[50,1018,1019],{"class":60},"@tailwindcss\u002Fvite",[50,1021,1022],{"class":67},"'\n",[50,1024,1025],{"class":52,"line":205},[50,1026,1028],{"emptyLinePlaceholder":1027},true,"\n",[50,1030,1031,1033,1035,1037,1039],{"class":52,"line":217},[50,1032,189],{"class":188},[50,1034,192],{"class":188},[50,1036,196],{"class":195},[50,1038,199],{"class":74},[50,1040,202],{"class":67},[50,1042,1043,1045,1047,1049,1051,1053,1055,1058],{"class":52,"line":232},[50,1044,745],{"class":208},[50,1046,176],{"class":67},[50,1048,661],{"class":74},[50,1050,664],{"class":67},[50,1052,754],{"class":60},[50,1054,664],{"class":67},[50,1056,1057],{"class":74},"]",[50,1059,229],{"class":67},[50,1061,1062,1065,1067],{"class":52,"line":238},[50,1063,1064],{"class":208},"  vite",[50,1066,176],{"class":67},[50,1068,214],{"class":67},[50,1070,1071,1074,1076],{"class":52,"line":416},[50,1072,1073],{"class":208},"    plugins",[50,1075,176],{"class":67},[50,1077,1078],{"class":74}," [\n",[50,1080,1081,1084],{"class":52,"line":421},[50,1082,1083],{"class":195},"      Tailwind",[50,1085,1086],{"class":74},"()\n",[50,1088,1089],{"class":52,"line":857},[50,1090,1091],{"class":74},"    ]\n",[50,1093,1095],{"class":52,"line":1094},9,[50,1096,235],{"class":67},[50,1098,1100,1102],{"class":52,"line":1099},10,[50,1101,241],{"class":67},[50,1103,244],{"class":74},[10,1105,1106,1107,1109,1110,176],{},"Enhance your developer experience by updating your ",[47,1108,431],{}," file for the ",[93,1111,775],{"href":773,"rel":1112},[156],[40,1114,1115],{"className":435,"code":778,"language":437,"meta":45,"style":45},[47,1116,1117,1121,1133,1149,1153,1165,1181,1185],{"__ignoreMap":45},[50,1118,1119],{"class":52,"line":53},[50,1120,202],{"class":67},[50,1122,1123,1125,1127,1129,1131],{"class":52,"line":205},[50,1124,448],{"class":67},[50,1126,791],{"class":451},[50,1128,455],{"class":67},[50,1130,176],{"class":67},[50,1132,214],{"class":67},[50,1134,1135,1137,1139,1141,1143,1145,1147],{"class":52,"line":217},[50,1136,499],{"class":67},[50,1138,804],{"class":56},[50,1140,455],{"class":67},[50,1142,176],{"class":67},[50,1144,509],{"class":67},[50,1146,701],{"class":60},[50,1148,535],{"class":67},[50,1150,1151],{"class":52,"line":232},[50,1152,819],{"class":67},[50,1154,1155,1157,1159,1161,1163],{"class":52,"line":238},[50,1156,448],{"class":67},[50,1158,826],{"class":451},[50,1160,455],{"class":67},[50,1162,176],{"class":67},[50,1164,214],{"class":67},[50,1166,1167,1169,1171,1173,1175,1177,1179],{"class":52,"line":416},[50,1168,499],{"class":67},[50,1170,839],{"class":56},[50,1172,455],{"class":67},[50,1174,176],{"class":67},[50,1176,509],{"class":67},[50,1178,848],{"class":60},[50,1180,535],{"class":67},[50,1182,1183],{"class":52,"line":421},[50,1184,235],{"class":67},[50,1186,1187],{"class":52,"line":857},[50,1188,465],{"class":67},[10,1190,1191],{},"The setup is incredibly straightforward!",[29,1193,1195],{"id":1194},"icons","Icons",[10,1197,1198,1199,1204],{},"Incorporating icons into your project is essential, albeit deceptively complex. ",[93,1200,1203],{"href":1201,"rel":1202},"https:\u002F\u002Fnuxt.com\u002Fblog\u002Fnuxt-icon-v1-0",[156],"Anthony Fu's article"," elaborates on finding the perfect icon solution.",[10,1206,1207],{},"If utilizing Nuxt UI, icons are already included. You can safely skip this section.",[10,1209,1210],{},"For Tailwind CSS users, two options are available:",[1212,1213,1214],"ol",{},[1215,1216,1217,1218,1223],"li",{},"Use the ",[93,1219,1222],{"href":1220,"rel":1221},"https:\u002F\u002Fgithub.com\u002Fnuxt\u002Ficon",[156],"Nuxt Icons"," module provides access to over 200,000 icons from various icon sets:",[40,1225,1227],{"className":42,"code":1226,"language":44,"meta":45,"style":45},"npx nuxi module add icon\n",[47,1228,1229],{"__ignoreMap":45},[50,1230,1231,1233,1235,1237,1239],{"class":52,"line":53},[50,1232,57],{"class":56},[50,1234,320],{"class":60},[50,1236,323],{"class":60},[50,1238,326],{"class":60},[50,1240,1241],{"class":60}," icon\n",[10,1243,1244],{},"This is the simplest solution and with the latest improvements from the v1 release, it's a powerful choice. I recommend starting with this option.",[1212,1246,1247],{"start":205},[1215,1248,1249,1250,1255],{},"Use the Tailwind CSS plugin, ",[93,1251,1254],{"href":1252,"rel":1253},"https:\u002F\u002Fgithub.com\u002Fegoist\u002Ftailwindcss-icons",[156],"Tailwind CSS Icons",", offers similar icons via a different approach:",[40,1257,1259],{"className":42,"code":1258,"language":44,"meta":45,"style":45},"npx @antfu\u002Fni -D @egoist\u002Ftailwindcss-icons\n",[47,1260,1261],{"__ignoreMap":45},[50,1262,1263,1265,1267,1269],{"class":52,"line":53},[50,1264,57],{"class":56},[50,1266,337],{"class":60},[50,1268,340],{"class":60},[50,1270,1271],{"class":60}," @egoist\u002Ftailwindcss-icons\n",[10,1273,1274,1275,1278],{},"Create a ",[47,1276,1277],{},"tailwind.config.js"," file and include the plugin:",[40,1280,1284],{"className":1281,"code":1282,"language":1283,"meta":45,"style":45},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { getIconCollections, iconsPlugin } from '@egoist\u002Ftailwindcss-icons'\n\n\u002F** @type {import('tailwindcss').Config} *\u002F\nmodule.exports = {\n  plugins: [\n    iconsPlugin({\n      collections: getIconCollections([\u002F** ... *\u002F]),\n    }),\n  ],\n}\n","js",[47,1285,1286,1315,1319,1343,1353,1362,1371,1391,1401,1408],{"__ignoreMap":45},[50,1287,1288,1290,1293,1296,1299,1302,1305,1308,1310,1313],{"class":52,"line":53},[50,1289,1007],{"class":188},[50,1291,1292],{"class":67}," {",[50,1294,1295],{"class":74}," getIconCollections",[50,1297,1298],{"class":67},",",[50,1300,1301],{"class":74}," iconsPlugin",[50,1303,1304],{"class":67}," }",[50,1306,1307],{"class":188}," from",[50,1309,1016],{"class":67},[50,1311,1312],{"class":60},"@egoist\u002Ftailwindcss-icons",[50,1314,1022],{"class":67},[50,1316,1317],{"class":52,"line":205},[50,1318,1028],{"emptyLinePlaceholder":1027},[50,1320,1321,1325,1328,1332,1334,1338,1340],{"class":52,"line":217},[50,1322,1324],{"class":1323},"sHwdD","\u002F** ",[50,1326,1327],{"class":188},"@",[50,1329,1331],{"class":1330},"s6hCs","type",[50,1333,1292],{"class":188},[50,1335,1337],{"class":1336},"sFweD","import('tailwindcss').Config",[50,1339,241],{"class":188},[50,1341,1342],{"class":1323}," *\u002F\n",[50,1344,1345,1348,1351],{"class":52,"line":232},[50,1346,1347],{"class":67},"module.exports",[50,1349,1350],{"class":67}," =",[50,1352,214],{"class":67},[50,1354,1355,1358,1360],{"class":52,"line":238},[50,1356,1357],{"class":208},"  plugins",[50,1359,176],{"class":67},[50,1361,1078],{"class":74},[50,1363,1364,1367,1369],{"class":52,"line":416},[50,1365,1366],{"class":195},"    iconsPlugin",[50,1368,199],{"class":74},[50,1370,202],{"class":67},[50,1372,1373,1376,1378,1380,1383,1386,1389],{"class":52,"line":421},[50,1374,1375],{"class":208},"      collections",[50,1377,176],{"class":67},[50,1379,1295],{"class":195},[50,1381,1382],{"class":74},"([",[50,1384,1385],{"class":1323},"\u002F** ... *\u002F",[50,1387,1388],{"class":74},"])",[50,1390,229],{"class":67},[50,1392,1393,1396,1399],{"class":52,"line":857},[50,1394,1395],{"class":67},"    }",[50,1397,1398],{"class":74},")",[50,1400,229],{"class":67},[50,1402,1403,1406],{"class":52,"line":1094},[50,1404,1405],{"class":74},"  ]",[50,1407,229],{"class":67},[50,1409,1410],{"class":52,"line":1099},[50,1411,465],{"class":67},[10,1413,1414,1415,472],{},"Import the configuration in your ",[47,1416,684],{},[40,1418,1420],{"className":687,"code":1419,"language":689,"meta":45,"style":45},"@import \"tailwindcss\";\n@config \"..\u002F..\u002F..\u002Ftailwind.config.js\";\n",[47,1421,1422,1434],{"__ignoreMap":45},[50,1423,1424,1426,1428,1430,1432],{"class":52,"line":53},[50,1425,696],{"class":188},[50,1427,509],{"class":67},[50,1429,701],{"class":60},[50,1431,455],{"class":67},[50,1433,706],{"class":67},[50,1435,1436,1439,1442],{"class":52,"line":205},[50,1437,1438],{"class":188},"@config",[50,1440,1441],{"class":74}," \"..\u002F..\u002F..\u002Ftailwind.config.js\"",[50,1443,706],{"class":67},[10,1445,1446,1447,97],{},"I personally prefer the second solution due to its uniform setup across projects, including non-Nuxt ones, and at the time I made this choice, the Nuxt Icons module was suffering from many drawbacks. However, that's not the case anymore and I highly recommend you to start with ",[93,1448,1222],{"href":1220,"rel":1449},[156],[29,1451,1453],{"id":1452},"fonts","Fonts",[10,1455,1456,1457,1459,1460,1465],{},"Fonts define your project's personality and influence user perception. ",[14,1458,16],{}," provides a solution: ",[93,1461,1464],{"href":1462,"rel":1463},"https:\u002F\u002Ffonts.nuxt.com\u002F",[156],"Nuxt Fonts",". This zero-config module automatically loads required fonts by scanning CSS files. Installation is straightforward:",[40,1467,1469],{"className":42,"code":1468,"language":44,"meta":45,"style":45},"npx nuxi module add fonts\n",[47,1470,1471],{"__ignoreMap":45},[50,1472,1473,1475,1477,1479,1481],{"class":52,"line":53},[50,1474,57],{"class":56},[50,1476,320],{"class":60},[50,1478,323],{"class":60},[50,1480,326],{"class":60},[50,1482,1483],{"class":60}," fonts\n",[10,1485,1486],{},"This module is part of my projects unless I'm using Nuxt UI, where it's included. But I have to say that I rarely need to install it since Nuxt UI suffices for most scenarios.",[29,1488,1490],{"id":1489},"ci","CI",[10,1492,1493,1494,1497],{},"For personal projects, I use ",[14,1495,1496],{},"GitHub"," and always set up a CI to enforce linting and autofix errors. This approach ensures clean, consistent code. While linters and formatters are great, they're useless if unused.",[10,1499,1500,1501,1504,1505,472],{},"I utilize ",[14,1502,1503],{},"GitHub Actions",", detailed in a ",[47,1506,1507],{},".github\u002Fworkflows\u002Fci.yml",[40,1509,1513],{"className":1510,"code":1511,"language":1512,"meta":45,"style":45},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: CI\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n      - main\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions\u002Fcheckout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4\n      - run: corepack enable\n      - uses: actions\u002Fsetup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4\n        with:\n          node-version: 22\n          cache: pnpm\n\n      - name: Install dependencies\n        run: pnpm install\n\n      - name: Lint files\n        run: pnpm run lint\n","yaml",[47,1514,1515,1525,1529,1536,1543,1550,1558,1565,1571,1577,1581,1589,1597,1608,1619,1624,1632,1648,1661,1675,1683,1694,1705,1710,1723,1734,1739,1751],{"__ignoreMap":45},[50,1516,1517,1520,1522],{"class":52,"line":53},[50,1518,1519],{"class":208},"name",[50,1521,176],{"class":67},[50,1523,1524],{"class":60}," CI\n",[50,1526,1527],{"class":52,"line":205},[50,1528,1028],{"emptyLinePlaceholder":1027},[50,1530,1531,1533],{"class":52,"line":217},[50,1532,848],{"class":407},[50,1534,1535],{"class":67},":\n",[50,1537,1538,1541],{"class":52,"line":232},[50,1539,1540],{"class":208},"  push",[50,1542,1535],{"class":67},[50,1544,1545,1548],{"class":52,"line":238},[50,1546,1547],{"class":208},"    branches",[50,1549,1535],{"class":67},[50,1551,1552,1555],{"class":52,"line":416},[50,1553,1554],{"class":67},"      -",[50,1556,1557],{"class":60}," main\n",[50,1559,1560,1563],{"class":52,"line":421},[50,1561,1562],{"class":208},"  pull_request",[50,1564,1535],{"class":67},[50,1566,1567,1569],{"class":52,"line":857},[50,1568,1547],{"class":208},[50,1570,1535],{"class":67},[50,1572,1573,1575],{"class":52,"line":1094},[50,1574,1554],{"class":67},[50,1576,1557],{"class":60},[50,1578,1579],{"class":52,"line":1099},[50,1580,1028],{"emptyLinePlaceholder":1027},[50,1582,1584,1587],{"class":52,"line":1583},11,[50,1585,1586],{"class":208},"jobs",[50,1588,1535],{"class":67},[50,1590,1592,1595],{"class":52,"line":1591},12,[50,1593,1594],{"class":208},"  lint",[50,1596,1535],{"class":67},[50,1598,1600,1603,1605],{"class":52,"line":1599},13,[50,1601,1602],{"class":208},"    name",[50,1604,176],{"class":67},[50,1606,1607],{"class":60}," Lint\n",[50,1609,1611,1614,1616],{"class":52,"line":1610},14,[50,1612,1613],{"class":208},"    runs-on",[50,1615,176],{"class":67},[50,1617,1618],{"class":60}," ubuntu-latest\n",[50,1620,1622],{"class":52,"line":1621},15,[50,1623,1028],{"emptyLinePlaceholder":1027},[50,1625,1627,1630],{"class":52,"line":1626},16,[50,1628,1629],{"class":208},"    steps",[50,1631,1535],{"class":67},[50,1633,1635,1637,1640,1642,1645],{"class":52,"line":1634},17,[50,1636,1554],{"class":67},[50,1638,1639],{"class":208}," uses",[50,1641,176],{"class":67},[50,1643,1644],{"class":60}," actions\u002Fcheckout@b4ffde65f46336ab88eb53be808477a3936bae11",[50,1646,1647],{"class":1323}," # v4\n",[50,1649,1651,1653,1656,1658],{"class":52,"line":1650},18,[50,1652,1554],{"class":67},[50,1654,1655],{"class":208}," run",[50,1657,176],{"class":67},[50,1659,1660],{"class":60}," corepack enable\n",[50,1662,1664,1666,1668,1670,1673],{"class":52,"line":1663},19,[50,1665,1554],{"class":67},[50,1667,1639],{"class":208},[50,1669,176],{"class":67},[50,1671,1672],{"class":60}," actions\u002Fsetup-node@60edb5dd545a775178f52524783378180af0d1f8",[50,1674,1647],{"class":1323},[50,1676,1678,1681],{"class":52,"line":1677},20,[50,1679,1680],{"class":208},"        with",[50,1682,1535],{"class":67},[50,1684,1686,1689,1691],{"class":52,"line":1685},21,[50,1687,1688],{"class":208},"          node-version",[50,1690,176],{"class":67},[50,1692,1693],{"class":225}," 22\n",[50,1695,1697,1700,1702],{"class":52,"line":1696},22,[50,1698,1699],{"class":208},"          cache",[50,1701,176],{"class":67},[50,1703,1704],{"class":60}," pnpm\n",[50,1706,1708],{"class":52,"line":1707},23,[50,1709,1028],{"emptyLinePlaceholder":1027},[50,1711,1713,1715,1718,1720],{"class":52,"line":1712},24,[50,1714,1554],{"class":67},[50,1716,1717],{"class":208}," name",[50,1719,176],{"class":67},[50,1721,1722],{"class":60}," Install dependencies\n",[50,1724,1726,1729,1731],{"class":52,"line":1725},25,[50,1727,1728],{"class":208},"        run",[50,1730,176],{"class":67},[50,1732,1733],{"class":60}," pnpm install\n",[50,1735,1737],{"class":52,"line":1736},26,[50,1738,1028],{"emptyLinePlaceholder":1027},[50,1740,1742,1744,1746,1748],{"class":52,"line":1741},27,[50,1743,1554],{"class":67},[50,1745,1717],{"class":208},[50,1747,176],{"class":67},[50,1749,1750],{"class":60}," Lint files\n",[50,1752,1754,1756,1758],{"class":52,"line":1753},28,[50,1755,1728],{"class":208},[50,1757,176],{"class":67},[50,1759,1760],{"class":60}," pnpm run lint\n",[10,1762,1763,1764,176],{},"To automate code formatting and commits, I use ",[93,1765,1768],{"href":1766,"rel":1767},"https:\u002F\u002Fautofix.ci\u002F",[156],"autofix.ci",[40,1770,1772],{"className":1510,"code":1771,"language":1512,"meta":45,"style":45},"name: autofix.ci # needed to securely identify the workflow\n\non:\n  pull_request:\n  push:\n    branches: [main]\n\npermissions:\n  contents: read\n\njobs:\n  autofix:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4\n      - run: corepack enable\n      - uses: actions\u002Fsetup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4\n        with:\n          node-version: 20.5\n          cache: pnpm\n\n      - name: Install dependencies\n        run: pnpm install\n\n      - name: Lint & Fix\n        run: pnpm run lint:fix\n\n      - uses: autofix-ci\u002Faction@ff86a557419858bb967097bfc916833f5647fa8c\n",[47,1773,1774,1786,1790,1796,1802,1808,1821,1825,1832,1842,1846,1852,1859,1867,1873,1886,1896,1909,1915,1924,1932,1936,1946,1954,1958,1969,1978,1982],{"__ignoreMap":45},[50,1775,1776,1778,1780,1783],{"class":52,"line":53},[50,1777,1519],{"class":208},[50,1779,176],{"class":67},[50,1781,1782],{"class":60}," autofix.ci",[50,1784,1785],{"class":1323}," # needed to securely identify the workflow\n",[50,1787,1788],{"class":52,"line":205},[50,1789,1028],{"emptyLinePlaceholder":1027},[50,1791,1792,1794],{"class":52,"line":217},[50,1793,848],{"class":407},[50,1795,1535],{"class":67},[50,1797,1798,1800],{"class":52,"line":232},[50,1799,1562],{"class":208},[50,1801,1535],{"class":67},[50,1803,1804,1806],{"class":52,"line":238},[50,1805,1540],{"class":208},[50,1807,1535],{"class":67},[50,1809,1810,1812,1814,1816,1819],{"class":52,"line":416},[50,1811,1547],{"class":208},[50,1813,176],{"class":67},[50,1815,661],{"class":67},[50,1817,1818],{"class":60},"main",[50,1820,672],{"class":67},[50,1822,1823],{"class":52,"line":421},[50,1824,1028],{"emptyLinePlaceholder":1027},[50,1826,1827,1830],{"class":52,"line":857},[50,1828,1829],{"class":208},"permissions",[50,1831,1535],{"class":67},[50,1833,1834,1837,1839],{"class":52,"line":1094},[50,1835,1836],{"class":208},"  contents",[50,1838,176],{"class":67},[50,1840,1841],{"class":60}," read\n",[50,1843,1844],{"class":52,"line":1099},[50,1845,1028],{"emptyLinePlaceholder":1027},[50,1847,1848,1850],{"class":52,"line":1583},[50,1849,1586],{"class":208},[50,1851,1535],{"class":67},[50,1853,1854,1857],{"class":52,"line":1591},[50,1855,1856],{"class":208},"  autofix",[50,1858,1535],{"class":67},[50,1860,1861,1863,1865],{"class":52,"line":1599},[50,1862,1613],{"class":208},[50,1864,176],{"class":67},[50,1866,1618],{"class":60},[50,1868,1869,1871],{"class":52,"line":1610},[50,1870,1629],{"class":208},[50,1872,1535],{"class":67},[50,1874,1875,1877,1879,1881,1884],{"class":52,"line":1621},[50,1876,1554],{"class":67},[50,1878,1639],{"class":208},[50,1880,176],{"class":67},[50,1882,1883],{"class":60}," actions\u002Fcheckout@11bd71901bbe5b1630ceea73d27597364c9af683",[50,1885,1647],{"class":1323},[50,1887,1888,1890,1892,1894],{"class":52,"line":1626},[50,1889,1554],{"class":67},[50,1891,1655],{"class":208},[50,1893,176],{"class":67},[50,1895,1660],{"class":60},[50,1897,1898,1900,1902,1904,1907],{"class":52,"line":1634},[50,1899,1554],{"class":67},[50,1901,1639],{"class":208},[50,1903,176],{"class":67},[50,1905,1906],{"class":60}," actions\u002Fsetup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af",[50,1908,1647],{"class":1323},[50,1910,1911,1913],{"class":52,"line":1650},[50,1912,1680],{"class":208},[50,1914,1535],{"class":67},[50,1916,1917,1919,1921],{"class":52,"line":1663},[50,1918,1688],{"class":208},[50,1920,176],{"class":67},[50,1922,1923],{"class":225}," 20.5\n",[50,1925,1926,1928,1930],{"class":52,"line":1677},[50,1927,1699],{"class":208},[50,1929,176],{"class":67},[50,1931,1704],{"class":60},[50,1933,1934],{"class":52,"line":1685},[50,1935,1028],{"emptyLinePlaceholder":1027},[50,1937,1938,1940,1942,1944],{"class":52,"line":1696},[50,1939,1554],{"class":67},[50,1941,1717],{"class":208},[50,1943,176],{"class":67},[50,1945,1722],{"class":60},[50,1947,1948,1950,1952],{"class":52,"line":1707},[50,1949,1728],{"class":208},[50,1951,176],{"class":67},[50,1953,1733],{"class":60},[50,1955,1956],{"class":52,"line":1712},[50,1957,1028],{"emptyLinePlaceholder":1027},[50,1959,1960,1962,1964,1966],{"class":52,"line":1725},[50,1961,1554],{"class":67},[50,1963,1717],{"class":208},[50,1965,176],{"class":67},[50,1967,1968],{"class":60}," Lint & Fix\n",[50,1970,1971,1973,1975],{"class":52,"line":1736},[50,1972,1728],{"class":208},[50,1974,176],{"class":67},[50,1976,1977],{"class":60}," pnpm run lint:fix\n",[50,1979,1980],{"class":52,"line":1741},[50,1981,1028],{"emptyLinePlaceholder":1027},[50,1983,1984,1986,1988,1990],{"class":52,"line":1753},[50,1985,1554],{"class":67},[50,1987,1639],{"class":208},[50,1989,176],{"class":67},[50,1991,1992],{"class":60}," autofix-ci\u002Faction@ff86a557419858bb967097bfc916833f5647fa8c\n",[29,1994,1996],{"id":1995},"keep-dependencies-up-to-date","Keep dependencies up-to-date",[10,1998,1999,2000,2005],{},"Maintaining up-to-date dependencies is crucial. With numerous projects, this can be time-consuming. I use ",[93,2001,2004],{"href":2002,"rel":2003},"https:\u002F\u002Fdocs.renovatebot.com\u002F",[156],"Renovate"," in each project to automate dependency updates:",[10,2007,1274,2008,2011],{},[47,2009,2010],{},"renovate.json"," file with:",[40,2013,2015],{"className":435,"code":2014,"language":437,"meta":45,"style":45},"{\n  \"extends\": [\n    \"github>nuxt\u002Frenovate-config-nuxt\"\n  ]\n}\n",[47,2016,2017,2021,2034,2043,2048],{"__ignoreMap":45},[50,2018,2019],{"class":52,"line":53},[50,2020,202],{"class":67},[50,2022,2023,2025,2028,2030,2032],{"class":52,"line":205},[50,2024,448],{"class":67},[50,2026,2027],{"class":451},"extends",[50,2029,455],{"class":67},[50,2031,176],{"class":67},[50,2033,1078],{"class":67},[50,2035,2036,2038,2041],{"class":52,"line":217},[50,2037,499],{"class":67},[50,2039,2040],{"class":60},"github>nuxt\u002Frenovate-config-nuxt",[50,2042,535],{"class":67},[50,2044,2045],{"class":52,"line":232},[50,2046,2047],{"class":67},"  ]\n",[50,2049,2050],{"class":52,"line":238},[50,2051,465],{"class":67},[10,2053,2054],{},"This tool is indispensable, and I find it challenging to work on projects lacking Renovate (like some work projects).",[29,2056,2058],{"id":2057},"tips-tricks-and-additional-considerations","Tips, tricks, and additional considerations",[10,2060,2061],{},"Here are some extra tips and tricks I find valuable, even if not directly related to the setup:",[581,2063,2065],{"id":2064},"always-place-scripts-first","Always place scripts first",[10,2067,2068,2069,2071,2072,2075],{},"Organize ",[47,2070,875],{}," files by placing the ",[47,2073,2074],{},"script"," section first. This offers clarity by presenting component logic before the template:",[40,2077,2079],{"className":873,"code":2078,"language":875,"meta":45,"style":45},"\u003Cscript lang=\"ts\">\n\u002F\u002F ...\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u002F\u002F ...\n\u003C\u002Ftemplate>\n",[47,2080,2081,2101,2106,2114,2118,2126,2131],{"__ignoreMap":45},[50,2082,2083,2085,2087,2090,2093,2095,2097,2099],{"class":52,"line":53},[50,2084,882],{"class":67},[50,2086,2074],{"class":208},[50,2088,2089],{"class":451}," lang",[50,2091,2092],{"class":67},"=",[50,2094,455],{"class":67},[50,2096,181],{"class":60},[50,2098,455],{"class":67},[50,2100,78],{"class":67},[50,2102,2103],{"class":52,"line":205},[50,2104,2105],{"class":1323},"\u002F\u002F ...\n",[50,2107,2108,2110,2112],{"class":52,"line":217},[50,2109,922],{"class":67},[50,2111,2074],{"class":208},[50,2113,78],{"class":67},[50,2115,2116],{"class":52,"line":232},[50,2117,1028],{"emptyLinePlaceholder":1027},[50,2119,2120,2122,2124],{"class":52,"line":238},[50,2121,882],{"class":67},[50,2123,885],{"class":208},[50,2125,78],{"class":67},[50,2127,2128],{"class":52,"line":416},[50,2129,2130],{"class":74},"  \u002F\u002F ...\n",[50,2132,2133,2135,2137],{"class":52,"line":421},[50,2134,922],{"class":67},[50,2136,885],{"class":208},[50,2138,78],{"class":67},[581,2140,2142],{"id":2141},"embrace-typescript","Embrace TypeScript",[10,2144,2145,2146,2148,2149,2151,2152,2155],{},"I advocate using ",[14,2147,564],{}," across all ",[47,2150,875],{}," files and utility or composable scripts. Adding ",[47,2153,2154],{},"lang=\"ts\""," even without TypeScript code enhances the developer experience:",[40,2157,2159],{"className":873,"code":2158,"language":875,"meta":45,"style":45},"\u003Cscript lang=\"ts\" setup>\n\u002F\u002F ...\n\u003C\u002Fscript>\n",[47,2160,2161,2182,2186],{"__ignoreMap":45},[50,2162,2163,2165,2167,2169,2171,2173,2175,2177,2180],{"class":52,"line":53},[50,2164,882],{"class":67},[50,2166,2074],{"class":208},[50,2168,2089],{"class":451},[50,2170,2092],{"class":67},[50,2172,455],{"class":67},[50,2174,181],{"class":60},[50,2176,455],{"class":67},[50,2178,2179],{"class":451}," setup",[50,2181,78],{"class":67},[50,2183,2184],{"class":52,"line":205},[50,2185,2105],{"class":1323},[50,2187,2188,2190,2192],{"class":52,"line":217},[50,2189,922],{"class":67},[50,2191,2074],{"class":208},[50,2193,78],{"class":67},[80,2195,2196],{},[10,2197,2198,2200,2201,2204],{},[50,2199,104],{},"\nAlways opt for the ",[47,2202,2203],{},"setup"," syntax in components.",[581,2206,2208,2209,2212,2213],{"id":2207},"avoid-using-processenv-in-nuxtconfigts","Avoid using ",[47,2210,2211],{},"process.env"," in ",[47,2214,359],{},[10,2216,2217,2218,2212,2220,2222,2223,2226,2227,176],{},"Refrain from directly accessing ",[47,2219,2211],{},[47,2221,359],{},". For instance, assigning defaults for ",[47,2224,2225],{},"runtimeConfig"," shouldn't use ",[47,2228,2211],{},[40,2230,2232],{"className":179,"code":2231,"language":181,"meta":45,"style":45},"export default defineNuxtConfig({\n  runtimeConfig: {\n    apiUrl: ''\n  }\n})\n",[47,2233,2234,2246,2255,2265,2269],{"__ignoreMap":45},[50,2235,2236,2238,2240,2242,2244],{"class":52,"line":53},[50,2237,189],{"class":188},[50,2239,192],{"class":188},[50,2241,196],{"class":195},[50,2243,199],{"class":74},[50,2245,202],{"class":67},[50,2247,2248,2251,2253],{"class":52,"line":205},[50,2249,2250],{"class":208},"  runtimeConfig",[50,2252,176],{"class":67},[50,2254,214],{"class":67},[50,2256,2257,2260,2262],{"class":52,"line":217},[50,2258,2259],{"class":208},"    apiUrl",[50,2261,176],{"class":67},[50,2263,2264],{"class":67}," ''\n",[50,2266,2267],{"class":52,"line":232},[50,2268,235],{"class":67},[50,2270,2271,2273],{"class":52,"line":238},[50,2272,241],{"class":67},[50,2274,244],{"class":74},[80,2276,2277],{},[10,2278,2279,2281,2282,2285,2286,2288,2289,97],{},[50,2280,86],{},"\nHover over the ",[47,2283,2284],{},"apiUrl"," key in your IDE for environment variable hints. ",[14,2287,16],{}," provides complex typing, such as ",[47,2290,2291],{},"NUXT_API_URL",[10,2293,972,2294,2297],{},[47,2295,2296],{},".env"," file at the project's root to define environment variables:",[40,2299,2304],{"className":2300,"code":2302,"language":2303},[2301],"language-text","NUXT_API_URL=https:\u002F\u002Fapi.example.com\n","text",[47,2305,2302],{"__ignoreMap":45},[10,2307,2308,2309,2311,2312,176],{},"Exclude the ",[47,2310,2296],{}," file using ",[47,2313,2314],{},".gitignore",[40,2316,2318],{"className":42,"code":2317,"language":44,"meta":45,"style":45},"echo \".env\" >> .gitignore\n",[47,2319,2320],{"__ignoreMap":45},[50,2321,2322,2325,2327,2329,2331,2334],{"class":52,"line":53},[50,2323,2324],{"class":195},"echo",[50,2326,509],{"class":67},[50,2328,2296],{"class":60},[50,2330,455],{"class":67},[50,2332,2333],{"class":67}," >>",[50,2335,2336],{"class":60}," .gitignore\n",[10,2338,2339,2340,2343],{},"Provide a ",[47,2341,2342],{},".env.example"," file to guide other developers:",[40,2345,2347],{"className":2346,"code":2302,"language":2303},[2301],[47,2348,2302],{"__ignoreMap":45},[298,2350,2353,2357,2363,2373,2390,2403,2407,2413,2421],{"text":2351,"href":2352},"Runtime Config: The Common Mistakes","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=_FYV5WfiWvs",[581,2354,2356],{"id":2355},"audit-before-installing-modules","Audit before installing modules",[10,2358,2359,2360,2362],{},"Conduct an audit before adding new modules to evaluate necessity and functionality. Sometimes, it's possible to proceed without them or to choose a superior alternative. Avoid basing decisions on stars or downloads. Instead, peruse documentation, source code, issues, and PRs for a comprehensive quality assessment. The ",[14,2361,16],{}," ecosystem evolves rapidly, and some modules may become outdated or incompatible with newer Nuxt versions.",[581,2364,2366,2367,565,2370],{"id":2365},"choosing-between-usefetch-and-fetch","Choosing between ",[47,2368,2369],{},"useFetch",[47,2371,2372],{},"$fetch",[10,2374,2208,2375,2378,2379,2381,2382,2389],{},[47,2376,2377],{},"fetch"," directly; opt for ",[47,2380,2372],{},", an enhanced instance of ",[93,2383,2386],{"href":2384,"rel":2385},"https:\u002F\u002Fgithub.com\u002Funjs\u002Fofetch",[156],[14,2387,2388],{},"ofetch",". Distinguish usage as follows:",[1212,2391,2392,2398],{},[1215,2393,2394,2395,2397],{},"Use ",[47,2396,2372],{}," for client-side operations, such as form data submissions.",[1215,2399,2394,2400,2402],{},[47,2401,2369],{}," where server-side rendering is feasible, like fetching API data to display on pages.",[29,2404,2406],{"id":2405},"the-perfect-setup-is-yours","The perfect setup is yours",[10,2408,2409,2410,2412],{},"This guide embodies everything I do to initialize a new ",[14,2411,16],{}," project. This comprehensive setup takes around 10 minutes, resulting in a clean, powerful, and future-ready project that allows focusing on business logic without distractions.",[80,2414,2415],{},[10,2416,2417,2420],{},[50,2418,2419],{},"!WARNING","\nAvoid creating a template project from this guide. The ecosystem is dynamic, and new modules swiftly emerge. Each project might necessitate nuanced adjustments. This guide is a starting point, a checklist for initial setup. However, always adapt to the specific project needs. Maintaining a template demands effort and is generally not worthwhile.",[10,2422,2423],{},"I hope this guide enhances your Nuxt project setup. If you have questions or want to share your configuration, please leave a comment below.",[2425,2426,2427],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s6hCs, html code.shiki .s6hCs{--shiki-light:#9C3EDA;--shiki-light-font-style:italic;--shiki-default:#C792EA;--shiki-default-font-style:italic;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .sFweD, html code.shiki .sFweD{--shiki-light:#E2931D;--shiki-light-font-style:italic;--shiki-default:#FFCB6B;--shiki-default-font-style:italic;--shiki-dark:#FFCB6B;--shiki-dark-font-style:italic}",{"title":45,"searchDepth":205,"depth":205,"links":2429},[2430,2431,2432,2433,2434],{"id":31,"depth":205,"text":32},{"id":125,"depth":205,"text":126},{"id":169,"depth":205,"text":96},{"id":304,"depth":205,"text":305},{"id":572,"depth":205,"text":573,"children":2435},[2436],{"id":583,"depth":217,"text":584},"17995d3c-aadc-4dc8-a2f0-278bc35157f0","2024-12-21","A comprehensive guide to efficiently setting up a Nuxt project, ensuring a clean, powerful, and future-proof project.","md",{},"\u002Fposts\u002Fthe-perfect-guide-to-setting-up-a-new-nuxt-project","---\ncontentId: 17995d3c-aadc-4dc8-a2f0-278bc35157f0\ntitle: \"The Perfect Guide to Setting Up a New Nuxt Project\"\ndescription: \"A comprehensive guide to efficiently setting up a Nuxt project, ensuring a clean, powerful, and future-proof project.\"\ndate: 2024-12-21\n---\n\nEvery time I create a new **Nuxt** project, I follow specific steps to ensure an optimal setup. I've been working with **Nuxt** since 2019 and have developed specific habits when initiating new projects.\n\nThrough my experience, I've explored numerous modules and reviewed projects from both experts and beginners. This has given me a solid understanding of what works well in the **Nuxt ecosystem**. Setting up a new project can be daunting, especially for newcomers, so I've decided to share this guide to help you set up your Nuxt project as efficiently as possible.\n\n## Creating a new Nuxt project\n\nLet's begin with creating a new **Nuxt** project. This is the simplest step, requiring just one command:\n\n```bash\nnpx nuxi@latest init \u003Cproject-name>\n```\n\n> [!TIP]\n> You can also create a v4 ready project with `npx nuxi init nuxt-app -t v4-compat`, avoiding the need for [Prepare for Nuxt 4](#prepare-for-nuxt-4).\n\n> [!NOTE]\n> I always choose **pnpm** as my package manager. You can select the one you prefer, but I recommend trying **pnpm**.\n\nRunning this command will scaffold a new Nuxt project within the `\u003Cproject-name>` directory. The app is minimalistic, no configuration, no modules, just Nuxt and an `app.vue` file.\n\n## Update the dependencies\n\nBefore proceeding, it's essential to update dependencies to their latest versions. This ensures you can leverage the newest features and bug fixes while avoiding issues that outdated dependencies might cause. Execute the following command to update them:\n\n```bash\nnpx taze -w\n```\n\nThe **taze** package, developed by [Anthony Fu](https:\u002F\u002Fantfu.me), updates all dependencies to their latest versions. It's similar to `npm-check-updates` but more powerful due to its adherence to **semver** versioning, offering both speed and reliability.\n\n## Prepare for Nuxt 4\n\nCurrently, the latest stable version of Nuxt is version 3. However, version 4 is in development and promises numerous features and enhancements. Although not officially released, you can prepare your projects for this future update by adding the following configuration in your `nuxt.config.js`:\n\n```ts\nexport default defineNuxtConfig({\n  future: {\n    compatibilityVersion: 4,\n  }\n})\n```\n\nThis setup enables you to start developing your projects as though you're already using **Nuxt 4**. This foresight not only allows you to benefit from upcoming features but also minimizes the work required to upgrade when Nuxt 4 is released.\n\nTo make the most of Nuxt 4, create a new `app` folder and move the `app.vue` file into it:\n\n```bash\nmkdir app && mv app.vue app\n```\n\n> [!TIP]\n> You can also create a v4 ready project by using the `npx nuxi init nuxt-app -t v4-compat` command.\n\n\u003CCalloutReadMore text=\"Upgrading to Nuxt 4\" href=\"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fupgrade#opting-in-to-nuxt-4\" \u002F>\n\n## Linting and formatting\n\nNuxt provides an excellent developer experience for linting and formatting. Install both the linter and the formatter with the following command:\n\n```bash\nnpx nuxi module add eslint && npx @antfu\u002Fni -D typescript\n```\n\nThis command installs the `@nuxt\u002Feslint` module, which offers a [0-config ESLint setup for Nuxt](https:\u002F\u002Feslint.nuxt.com) projects. Enable formatting, and it will automatically fix issues upon saving a file. I always configure it in my `nuxt.config.ts`:\n\n```ts\nexport default defineNuxtConfig({\n  eslint: {\n    config: {\n      stylistic: true \u002F\u002F [!code highlight]\n    }\n  }\n})\n```\n\nAdditionally, create a `.vscode\u002Fsettings.json` file to disable the prettier extension, preventing conflicts with the ESLint formatter:\n\n```json\n{\n  \"prettier.enable\": false\n}\n```\n\nAdd two scripts to your `package.json` file:\n\n```json\n{\n  \"scripts\": {\n    \"lint\": \"eslint .\",\n    \"lint:fix\": \"eslint --fix .\"\n  }\n}\n```\n\nNow, you can run `pnpm run lint` to check for issues and `pnpm run lint:fix` to automatically fix them.\n\nThese predefined configurations make it straightforward to set up **ESLint** with **TypeScript** and **Vue** support, ensuring consistent and clean code.\n\n## UI and components\n\nWith a clean project setup, the latest dependencies, preparation for **Nuxt 4**, and robust linting and formatting, it's time to focus on UI and components. This step varies based on project objectives and design requirements.\n\n### Nuxt UI and Nuxt UI Pro\n\nIf the project emphasizes business logic over UI, I use the [Nuxt UI](https:\u002F\u002Fui.nuxt.com) and Nuxt UI Pro component libraries. They are well-designed and easy to use. Reading the [Nuxt UI source code](https:\u002F\u002Fgithub.com\u002Fnuxt\u002Fui) is insightful, and I also have an article on building a component library with Vue.\n\n\u003CCalloutReadMore id=\"55d2cdcf-ba27-4bfe-9bc1-492e866ff3b1\" \u002F>\n\n> [!NOTE]\n> As of writing, Nuxt UI 3 is not officially released, but it can be used in projects. If you're reading this later, let me know in the comments, and I'll update this guide.\n\nFirst, install Nuxt UI and Tailwind CSS:\n\n```bash\npnpm add @nuxt\u002Fui@next tailwindcss@next\n```\n\nAdd the module to your `nuxt.config.ts` file:\n\n```ts\nexport default defineNuxtConfig({\n  modules: ['@nuxt\u002Fui']\n})\n```\n\nImport necessary CSS in your `app\u002Fassets\u002Fcss\u002Fmain.css` file:\n\n```css\n@import \"tailwindcss\";\n@import \"@nuxt\u002Fui\";\n```\n\nEnsure this CSS file is included in the `nuxt.config.ts` file:\n\n```ts\nexport default defineNuxtConfig({\n  css: ['~\u002Fassets\u002Fcss\u002Fmain.css']\n})\n```\n\nUpdate your `.vscode\u002Fsettings.json` file to enhance experience with the [Tailwind CSS IntelliSense extension](https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=bradlc.vscode-tailwindcss):\n\n```json\n{\n  \"files.associations\": {\n    \"*.css\": \"tailwindcss\"\n  },\n  \"editor.quickSuggestions\": {\n    \"strings\": \"on\"\n  }\n}\n```\n\nLastly, modify your `app\u002Fapp.vue` file to include the Nuxt UI component `\u003CUApp>`, automatically injecting global components:\n\n```vue\n\u003Ctemplate>\n  \u003CUApp>\n    \u003CNuxtPage \u002F>\n  \u003C\u002FUApp>\n\u003C\u002Ftemplate>\n```\n\n> [!NOTE]\n> Nuxt UI Pro is a paid extension offering layout components for rapid app development. It's a worthwhile investment that saves time and effort, while supporting the Nuxt team and open-source development. 💚\n\n### Tailwind CSS\n\nFor projects requiring specific designs or when collaborating with designers, I turn to [Tailwind CSS](https:\u002F\u002Ftailwindcss.com). It's a utility-first CSS framework that streamlines the design process to such an extent that working without it is unimaginable. The upcoming version, Tailwind CSS 4, includes an indispensable **Vite** plugin, eliminating the need for additional modules and simplifying the setup.\n\nInstall the latest Tailwind CSS version:\n\n```bash\npnpm add tailwindcss@next @tailwindcss\u002Fvite@next\n```\n\nCreate an `app\u002Fassets\u002Fcss\u002Fmain.css` file and import Tailwind CSS:\n\n```css\n@import \"tailwindcss\";\n```\n\nUpdate your `nuxt.config.ts` file to utilize the Vite plugin:\n\n```ts\nimport Tailwind from '@tailwindcss\u002Fvite'\n\nexport default defineNuxtConfig({\n  css: ['~\u002Fassets\u002Fcss\u002Fmain.css'],\n  vite: {\n    plugins: [\n      Tailwind()\n    ]\n  }\n})\n```\n\nEnhance your developer experience by updating your `.vscode\u002Fsettings.json` file for the [Tailwind CSS IntelliSense extension](https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=bradlc.vscode-tailwindcss):\n\n```json\n{\n  \"files.associations\": {\n    \"*.css\": \"tailwindcss\"\n  },\n  \"editor.quickSuggestions\": {\n    \"strings\": \"on\"\n  }\n}\n```\n\nThe setup is incredibly straightforward!\n\n## Icons\n\nIncorporating icons into your project is essential, albeit deceptively complex. [Anthony Fu's article](https:\u002F\u002Fnuxt.com\u002Fblog\u002Fnuxt-icon-v1-0) elaborates on finding the perfect icon solution.\n\nIf utilizing Nuxt UI, icons are already included. You can safely skip this section.\n\nFor Tailwind CSS users, two options are available:\n\n1. Use the [Nuxt Icons](https:\u002F\u002Fgithub.com\u002Fnuxt\u002Ficon) module provides access to over 200,000 icons from various icon sets:\n\n```bash\nnpx nuxi module add icon\n```\n\nThis is the simplest solution and with the latest improvements from the v1 release, it's a powerful choice. I recommend starting with this option.\n\n2. Use the Tailwind CSS plugin, [Tailwind CSS Icons](https:\u002F\u002Fgithub.com\u002Fegoist\u002Ftailwindcss-icons), offers similar icons via a different approach:\n\n```bash\nnpx @antfu\u002Fni -D @egoist\u002Ftailwindcss-icons\n```\n\nCreate a `tailwind.config.js` file and include the plugin:\n\n```js\nimport { getIconCollections, iconsPlugin } from '@egoist\u002Ftailwindcss-icons'\n\n\u002F** @type {import('tailwindcss').Config} *\u002F\nmodule.exports = {\n  plugins: [\n    iconsPlugin({\n      collections: getIconCollections([\u002F** ... *\u002F]),\n    }),\n  ],\n}\n```\n\nImport the configuration in your `app\u002Fassets\u002Fcss\u002Fmain.css` file:\n\n```css\n@import \"tailwindcss\";\n@config \"..\u002F..\u002F..\u002Ftailwind.config.js\";\n```\n\nI personally prefer the second solution due to its uniform setup across projects, including non-Nuxt ones, and at the time I made this choice, the Nuxt Icons module was suffering from many drawbacks. However, that's not the case anymore and I highly recommend you to start with [Nuxt Icons](https:\u002F\u002Fgithub.com\u002Fnuxt\u002Ficon).\n\n## Fonts\n\nFonts define your project's personality and influence user perception. **Nuxt** provides a solution: [Nuxt Fonts](https:\u002F\u002Ffonts.nuxt.com\u002F). This zero-config module automatically loads required fonts by scanning CSS files. Installation is straightforward:\n\n```bash\nnpx nuxi module add fonts\n```\n\nThis module is part of my projects unless I'm using Nuxt UI, where it's included. But I have to say that I rarely need to install it since Nuxt UI suffices for most scenarios.\n\n## CI\n\nFor personal projects, I use **GitHub** and always set up a CI to enforce linting and autofix errors. This approach ensures clean, consistent code. While linters and formatters are great, they're useless if unused.\n\nI utilize **GitHub Actions**, detailed in a `.github\u002Fworkflows\u002Fci.yml` file:\n\n```yaml\nname: CI\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n      - main\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions\u002Fcheckout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4\n      - run: corepack enable\n      - uses: actions\u002Fsetup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4\n        with:\n          node-version: 22\n          cache: pnpm\n\n      - name: Install dependencies\n        run: pnpm install\n\n      - name: Lint files\n        run: pnpm run lint\n```\n\nTo automate code formatting and commits, I use [autofix.ci](https:\u002F\u002Fautofix.ci\u002F):\n\n```yaml\nname: autofix.ci # needed to securely identify the workflow\n\non:\n  pull_request:\n  push:\n    branches: [main]\n\npermissions:\n  contents: read\n\njobs:\n  autofix:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4\n      - run: corepack enable\n      - uses: actions\u002Fsetup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4\n        with:\n          node-version: 20.5\n          cache: pnpm\n\n      - name: Install dependencies\n        run: pnpm install\n\n      - name: Lint & Fix\n        run: pnpm run lint:fix\n\n      - uses: autofix-ci\u002Faction@ff86a557419858bb967097bfc916833f5647fa8c\n```\n\n## Keep dependencies up-to-date\n\nMaintaining up-to-date dependencies is crucial. With numerous projects, this can be time-consuming. I use [Renovate](https:\u002F\u002Fdocs.renovatebot.com\u002F) in each project to automate dependency updates:\n\nCreate a `renovate.json` file with:\n\n```json\n{\n  \"extends\": [\n    \"github>nuxt\u002Frenovate-config-nuxt\"\n  ]\n}\n```\n\nThis tool is indispensable, and I find it challenging to work on projects lacking Renovate (like some work projects).\n\n## Tips, tricks, and additional considerations\n\nHere are some extra tips and tricks I find valuable, even if not directly related to the setup:\n\n### Always place scripts first\n\nOrganize `vue` files by placing the `script` section first. This offers clarity by presenting component logic before the template:\n\n```vue\n\u003Cscript lang=\"ts\">\n\u002F\u002F ...\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u002F\u002F ...\n\u003C\u002Ftemplate>\n```\n\n### Embrace TypeScript\n\nI advocate using **TypeScript** across all `vue` files and utility or composable scripts. Adding `lang=\"ts\"` even without TypeScript code enhances the developer experience:\n\n```vue\n\u003Cscript lang=\"ts\" setup>\n\u002F\u002F ...\n\u003C\u002Fscript>\n```\n\n> [!NOTE]\n> Always opt for the `setup` syntax in components.\n\n### Avoid using `process.env` in `nuxt.config.ts`\n\nRefrain from directly accessing `process.env` in `nuxt.config.ts`. For instance, assigning defaults for `runtimeConfig` shouldn't use `process.env`:\n\n```ts\nexport default defineNuxtConfig({\n  runtimeConfig: {\n    apiUrl: ''\n  }\n})\n```\n\n> [!TIP]\n> Hover over the `apiUrl` key in your IDE for environment variable hints. **Nuxt** provides complex typing, such as `NUXT_API_URL`.\n\nCreate an `.env` file at the project's root to define environment variables:\n\n```\nNUXT_API_URL=https:\u002F\u002Fapi.example.com\n```\n\nExclude the `.env` file using `.gitignore`:\n\n```bash\necho \".env\" >> .gitignore\n```\n\nProvide a `.env.example` file to guide other developers:\n\n```\nNUXT_API_URL=https:\u002F\u002Fapi.example.com\n```\n\n\u003CCalloutReadMore text=\"Runtime Config: The Common Mistakes\" href=\"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=_FYV5WfiWvs\" \u002F>\n\n### Audit before installing modules\n\nConduct an audit before adding new modules to evaluate necessity and functionality. Sometimes, it's possible to proceed without them or to choose a superior alternative. Avoid basing decisions on stars or downloads. Instead, peruse documentation, source code, issues, and PRs for a comprehensive quality assessment. The **Nuxt** ecosystem evolves rapidly, and some modules may become outdated or incompatible with newer Nuxt versions.\n\n### Choosing between `useFetch` and `$fetch`\n\nAvoid using `fetch` directly; opt for `$fetch`, an enhanced instance of [**ofetch**](https:\u002F\u002Fgithub.com\u002Funjs\u002Fofetch). Distinguish usage as follows:\n\n1. Use `$fetch` for client-side operations, such as form data submissions.\n2. Use `useFetch` where server-side rendering is feasible, like fetching API data to display on pages.\n\n## The perfect setup is yours\n\nThis guide embodies everything I do to initialize a new **Nuxt** project. This comprehensive setup takes around 10 minutes, resulting in a clean, powerful, and future-ready project that allows focusing on business logic without distractions.\n\n> [!WARNING]\n> Avoid creating a template project from this guide. The ecosystem is dynamic, and new modules swiftly emerge. Each project might necessitate nuanced adjustments. This guide is a starting point, a checklist for initial setup. However, always adapt to the specific project needs. Maintaining a template demands effort and is generally not worthwhile.\n\nI hope this guide enhances your Nuxt project setup. If you have questions or want to share your configuration, please leave a comment below.\n",null,{"title":5,"description":2439},{"loc":2442},"posts\u002Fthe-perfect-guide-to-setting-up-a-new-nuxt-project","zb7ZdLf4LjP8pVi8z-gPXJICn-OLTME18s2mz_17XDs",1790086900939]