Leveraging shadow components with the Next.js pages directory

I am facing an issue with getting a simple shadcn button to work because I am unable to import the button. Although I am using nextjs 13, I am still utilizing the pages directory. Below is the process of how I installed shadcn.

Here is the installation command as directed on the webpage

npx shadcn-ui@latest init

The input for the command line was:

✔ Would you like to use TypeScript (recommended)? … no / yes
✔ Which style would you like to use? › Default
✔ Which color would you like to use as base color? › Slate
✔ Where is your global CSS file? … styles/globals.css
✔ Would you like to use CSS variables for colors? … no / yes
✔ Where is your tailwind.config.js located? … tailwind.config.js
✔ Configure the import alias for components: … @/components
✔ Configure the import alias for utils: … @/lib/utils
✔ Are you using React Server Components? … no / yes
✔ Write configuration to components.json. Proceed? … yes

The difficulty I encounter is that after installing the button, I cannot find the lib folder

// File path: @components/ui/button.ts
//Error: TS2307: Cannot find module '@/lib/utils' or its corresponding type declarations.
import { cn } from "@/lib/utils"
...

Below is my automatically created folder structure

.
├── src
│   └── pages
│       └── home.tsx 
├── @
│   └── components
│       └── ui
│       │    ├── alert-dialog.tsx
│       │    ├── button.tsx
│       │    └── dropdown-menu.tsx
│       │
│       └─ lib
│           └── utils.ts
├── styles
│   └── globals.css
├── next.config.js
├── package.json
├── postcss.config.js
├── tailwind.config.js
└── tsconfig.json

Note that this differs slightly from the example structure provided by shadcn. The @ was generated automatically

.
├── app
│   ├── layout.tsx
│   └── page.tsx
├── components
│   ├── ui
│   │   ├── alert-dialog.tsx
│   │   ├── button.tsx
│   │   ├── dropdown-menu.tsx
│   │   └── ...
│   ├── main-nav.tsx
│   ├── page-header.tsx
│   └── ...
├── lib
│   └── utils.ts
├── styles
│   └── globals.css
├── next.config.js
├── package.json
├── postcss.config.js
├── tailwind.config.js
└── tsconfig.json

My components.json file looks like this

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.js",
    "css": "styles/globals.css",
    "baseColor": "slate",
    "cssVariables": true
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  }
}

and here is my tailwind.config.js

/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ["class"],
  content: [
    './pages/**/*.{ts,tsx}',
    './components/**/*.{ts,tsx}',
    './app/**/*.{ts,tsx}',
    './src/**/*.{ts,tsx}',
    ],
  theme: {
    container: {
      center: true,
      padding: "2rem",
      screens: {
        "2xl": "1400px",
      },
    },
    ...
  },
  plugins: [require("tailwindcss-animate"), require("daisyui")],
}

What could be the issue here?

Answer №1

In the example provided, the @ symbol is not indicating a folder but rather a path alias.

To resolve this issue, move your components and lib directories to the src directory:

.
├── src
│   └── pages
│       └── home.tsx 
│
├── components
│   ├── ui
│   │    ├── alert-dialog.tsx
│   │    ├── button.tsx
│   │    └── dropdown-menu.tsx
│   
├─ lib
│    └── utils.ts
│  
└─ styles
     └── globals.css

Next, update your tsconfig.json file as follows:

"paths": {
  "@/*": ["./src/*"]
}

This configuration means that when you use @/components/whatever, the compiler will look for this path at ROOT => src/components/whatever. Similarly, @/lib/utils translates to <ROOT>/lib/utils.

However, with your current setup, using

import { cn } from "@/lib/utils"
would result in looking for it at
./@/components/ui/button/@/lib/utils
, which does not exist.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible for a memory leak to occur when a jQuery object is created within a function but never actually used?

As an illustration: function calculateTime(minutes) { var newTime = new Date(); newTime.setHours(0, minutes, 0, 0); return angular.element('<input type="hidden"/>').timepicker('setTime', newTime).val(); } I'm cu ...

Guide to Embedding a Docusaurus Website as a Route in a Next.js Website

Seeking advice on creating a /docs page for website documentation in a next.js app. I've explored Docusaurus but it appears to be a react app already. Is there a method to incorporate it into an existing next.js app or are there alternative solutions ...

An elusive melody that plays only when I execute the play command

I am currently working on creating a music Discord bot using the yt-search library, however, I am encountering an issue where it returns undefined when trying to play a song and joins the voice channel without actually playing anything. My approach is to u ...

What is the best way to extract the property name from the AJV output in order to effectively translate validation errors into user-friendly

I am currently utilizing the AJV library for input validation in my nodejs express api. I'm facing an issue with extracting the property name associated with each error object within the returned array. [{ instancePath: '', schemaPath: & ...

The Google APIs sheet API is throwing an error message stating "Invalid grant: account not found"

I need to retrieve data from a spreadsheet using the Sheet API. After setting up a project in Google Cloud Platform and creating a service account, I granted the account permission to edit the spreadsheet. I then downloaded the credentials in JSON format. ...

Establish a global variable within the utils.js module in a Node.js environment

Hey there, I'm currently in the process of trying to figure out how to properly define a global variable in node.js. I am aware that it's not considered best practice, but in this specific scenario, it seems like the only way to go without involv ...

Gather information from a customizable Bootstrap table and store it in an array

Currently, I have a bootstrap table configured with react-bootstrap-table-next, enabling users to edit cells and input their desired values. After completing the editing process, individuals can click on the "Submit" button to save the table values, which ...

Synchronize two div elements with JavaScript

The demonstration features two parent divs, each containing a child div! The first parent div's child div is draggable and resizable using JQueryUI. There are events for both dragEnd and resizeEnd associated with this div. The goal is to synchronize ...

The GraphQl Code Generator fails to correctly generate the graphql() function in Next.js applications

While working on my next.js project, I integrated GraphQL to generate types for queries. However, the code generator is not functioning properly and displaying an error message: "The query argument is unknown! Please regenerate the types." within the gql.t ...

Using Javascript to organize an array of objects based on a specific condition

Having an array of objects structured as follows: obj = [{'name': 'Tom', 'age': 17, 'gender': 'male', 'color':'red', 'position':3}, {'name': 'Sam', ...

Analyzing User Input and Database Information with Mongodb

Here's the HTML form I'm working with: <form id="contact-form" method="POST" action="/search"> <label for="company">Phone company</label> <input type="text" name="company" value=""> &l ...

Expanding a Material UI Accordion does not cause the surrounding content to shift or move

I'm currently designing a User Interface for a web application that allows users to have multiple projects open simultaneously. To achieve this, I decided to use an accordion as the logical component in the left navigation bar. The reason behind this ...

Troubleshooting issues with environment variables in Next.js version 12.2.2

I tried following the steps outlined in the official documentation, but I'm encountering an issue. Here is what I did: next.config.js const nextConfig = { reactStrictMode: true, swcMinify: true, env : { MORALIS_ID: 'moralisId', ...

What is the best method to position a modal in the exact center of the screen?

Is there a way to position the modal at the center of the screen? I have tried implementing this HTML and JavaScript code. Interestingly, it works fine in Chrome console but fails when I try to refresh the page. $('.modal').css('top', ...

Hide Details tag only on mobile view

How can I easily close the default opened <details> tag on mobile? I am working with Wordpress. Any suggestions on how to achieve this? <details open> <summary>Details</summary> Something small enough to go unnoticed. </ ...

submit a new entry to add a record to the database

Hey there, I recently started learning PHP and JS and I'm trying to insert a row into a WordPress database table. I need to get the information needed for insertion from another table, but I'm facing an issue with the PHP file as it's not in ...

Is it considered acceptable to retrieve the action payload in mapDispatchToProps in a React/Redux setup?

In my MediaUpload component, I have a mapDispatchToProps function that handles file uploads. When a file is added, the onChange handler triggers two actions: creating new media entries for the files and updating the form data in the state with the generate ...

What is the proper placement for index.html <head/> class helper functions within a ReactJS Component?

My custom helper functions are stored in a JavaScript file called classie.js: ( function( window ) { 'use strict'; function classReg( className ) { return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); } var hasClass, ...

issue with manipulating URLs in Express routing

Looking for assistance with Express routing. I want users to only see localhost:3000/page2 when they go to /page2, instead of localhost:3000/page2.html I have three HTML pages - page1.html, page2.html, and page3.html. I've created a server using Expr ...

What could be causing a problem with the select query in SQLite for iOS using PhoneGap

Could someone please assist me with retrieving values from a database? Here is my code: <script type="text/javascript" charset="utf-8"> // Wait for Cordova to load document.addEventListener("deviceready", onDeviceReady, false); ...