-
Notifications
You must be signed in to change notification settings - Fork 0
HeroUI and Tailwind v4 Setup | Development #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…scaffold process.
… and creating `hero.ts` during scaffolding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds automated configuration for HeroUI with Tailwind v4, improves error messaging during dependency installation, and updates the package version. The changes focus on generating the necessary Tailwind v4 configuration files (hero.ts) and updating globals.css with proper directives for projects using HeroUI.
Key Changes:
- Automated HeroUI and Tailwind v4 setup by creating
hero.tsplugin file and configuringglobals.csswith v4 directives - Enhanced error handling with troubleshooting tips for common npm installation issues
- Updated GitHub Packages authentication configuration in the publishing workflow
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
src/scaffold.ts |
Imports new configureGlobalCssForHeroUI function; creates hero.ts at project root for Tailwind v4; adds troubleshooting tips to error handler |
src/lib/ast.ts |
Adds configureGlobalCssForHeroUI function to inject Tailwind v4 directives into globals.css |
package.json |
Version bump from 2.1.1 to 2.1.2 |
.github/workflows/auto-publish.yml |
Adds explicit auth token configuration for GitHub Packages publishing |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let content = await fs.readFile(cssPath, "utf-8"); | ||
|
|
||
| // Check if it's already configured to avoid duplication | ||
| if (content.includes("@plugin './hero.ts';")) return; |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The duplication check only looks for the exact string @plugin './hero.ts'; but doesn't check for other variations that might indicate the file has already been configured, such as @plugin "./hero.ts" (double quotes) or @plugin './hero.ts' (with different spacing). This could lead to duplicate configuration being added if the existing configuration uses slightly different formatting.
| if (content.includes("@plugin './hero.ts';")) return; | |
| const heroPluginPattern = /@plugin\s+["']\.\/hero\.ts["']\s*;?/; | |
| if (heroPluginPattern.test(content)) return; |
| content = content.replace('@import "tailwindcss";', v4Setup); | ||
| } else { | ||
| // Fallback: Prepend if no standard import found (though unlikely in fresh v4 app) | ||
| content = v4Setup + content; |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the fallback case where no standard Tailwind import is found, the v4 setup is prepended to the entire existing content. This could result in the new directives being inserted in the middle of an existing CSS rule or comment block, potentially breaking the CSS. Consider adding validation to ensure the content structure is appropriate before prepending, or add a newline separator to reduce the risk of CSS syntax errors.
| content = v4Setup + content; | |
| const separator = | |
| content.startsWith("\n") || content.startsWith("\r\n") ? "" : "\n"; | |
| content = v4Setup + separator + content; |
|
|
||
| await sourceFile.save(); | ||
| } | ||
|
|
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function configureGlobalCssForHeroUI lacks documentation. Adding a JSDoc comment would help explain its purpose, parameters, return value, and any assumptions it makes (such as the expected structure of globals.css or the relationship between hero.ts location and CSS file location).
| /** | |
| * Configures the global Tailwind CSS setup for HeroUI in a Next.js app. | |
| * | |
| * This function locates `src/app/globals.css` under the given project root, | |
| * and ensures that it uses the Tailwind CSS v4-style `@import` syntax and the | |
| * HeroUI-specific `@plugin` and `@source` directives. If the HeroUI plugin | |
| * directive (`@plugin './hero.ts';`) is already present, the file is left | |
| * unchanged to avoid duplicate configuration. | |
| * | |
| * Assumptions: | |
| * - `globals.css` is located at `src/app/globals.css` relative to | |
| * `projectPath`. | |
| * - The HeroUI plugin entry file `hero.ts` is in the same directory as | |
| * `globals.css`, hence the `./hero.ts` plugin path. | |
| * - The HeroUI theme files are available at | |
| * `node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}` relative to the | |
| * project root. | |
| * | |
| * If `globals.css` does not exist, the function exits without making changes. | |
| * | |
| * @param projectPath Absolute or relative path to the root of the Next.js project. | |
| * @returns A promise that resolves when `globals.css` has been updated (or no-op). | |
| */ |
| if (content.includes("@plugin './hero.ts';")) return; | ||
|
|
||
| // Replace default tailwind import with v4 setup | ||
| // We assume standard create-next-app output which usually starts with directives | ||
| // Or just prepend/replace the top part. | ||
|
|
||
| const v4Setup = `@import "tailwindcss"; | ||
| @plugin './hero.ts'; |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The @source directive uses a relative path that starts from src/app/globals.css and navigates up to node_modules. However, if the hero.ts file is created at the project root (as done in scaffold.ts line 618), the path relationship may be inconsistent. The @plugin directive references './hero.ts' which is relative to the CSS file location, but hero.ts is created at the project root, not at src/app/hero.ts. This path mismatch will cause the plugin to not be found at runtime.
| if (content.includes("@plugin './hero.ts';")) return; | |
| // Replace default tailwind import with v4 setup | |
| // We assume standard create-next-app output which usually starts with directives | |
| // Or just prepend/replace the top part. | |
| const v4Setup = `@import "tailwindcss"; | |
| @plugin './hero.ts'; | |
| if (content.includes("@plugin '../../hero.ts';")) return; | |
| // Replace default tailwind import with v4 setup | |
| // We assume standard create-next-app output which usually starts with directives | |
| // Or just prepend/replace the top part. | |
| const v4Setup = `@import "tailwindcss"; | |
| @plugin '../../hero.ts'; |
| `; | ||
|
|
||
| if (content.includes('@import "tailwindcss";')) { | ||
| content = content.replace('@import "tailwindcss";', v4Setup); |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The String.prototype.replace() method only replaces the first occurrence by default. If the globals.css file contains multiple instances of @import "tailwindcss"; (which could happen in edge cases or user-modified files), only the first one would be replaced, potentially leaving duplicate or conflicting imports in the file.
| content = content.replace('@import "tailwindcss";', v4Setup); | |
| let replaced = false; | |
| content = content.replace(/@import "tailwindcss";/g, () => { | |
| if (!replaced) { | |
| replaced = true; | |
| return v4Setup; | |
| } | |
| return ""; | |
| }); |
| console.log(chalk.yellow("\nTroubleshooting Tips:")); | ||
| console.log(chalk.white(" • If you see 'EACCES' or permission errors, try running:")); | ||
| console.log(chalk.cyan(" sudo chown -R $(whoami) ~/.npm")); | ||
| console.log(chalk.white(" • If you see 'EEXIST' or cache errors, try:")); | ||
| console.log(chalk.cyan(" npm cache clean --force")); |
Copilot
AI
Jan 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The troubleshooting tips only mention npm-specific commands (npm cache clean --force) but the error handler is used regardless of the package manager. Users who encounter errors with yarn, pnpm, or bun will see npm-specific advice that may not apply to their package manager. Consider making the troubleshooting tips package-manager aware using the pm variable.
| console.log(chalk.yellow("\nTroubleshooting Tips:")); | |
| console.log(chalk.white(" • If you see 'EACCES' or permission errors, try running:")); | |
| console.log(chalk.cyan(" sudo chown -R $(whoami) ~/.npm")); | |
| console.log(chalk.white(" • If you see 'EEXIST' or cache errors, try:")); | |
| console.log(chalk.cyan(" npm cache clean --force")); | |
| const ownershipDir = | |
| pm === "yarn" | |
| ? "~/.cache/yarn" | |
| : pm === "pnpm" | |
| ? "~/.pnpm-store" | |
| : pm === "bun" | |
| ? "~/.bun" | |
| : "~/.npm"; | |
| const cacheCommand = | |
| pm === "yarn" | |
| ? "yarn cache clean" | |
| : pm === "pnpm" | |
| ? "pnpm store prune" | |
| : pm === "bun" | |
| ? "bun install --force" | |
| : "npm cache clean --force"; | |
| console.log(chalk.yellow("\nTroubleshooting Tips:")); | |
| console.log( | |
| chalk.white(" • If you see 'EACCES' or permission errors, try running:") | |
| ); | |
| console.log( | |
| chalk.cyan(` sudo chown -R $(whoami) ${ownershipDir}`) | |
| ); | |
| console.log( | |
| chalk.white(" • If you see 'EEXIST' or cache errors, try:") | |
| ); | |
| console.log(chalk.cyan(` ${cacheCommand}`)); |
This pull request introduces improvements to the setup process for projects using HeroUI and Tailwind v4, enhances error messaging for dependency installation, and updates the package version. The main focus is on automating the configuration of Tailwind and global CSS for HeroUI, as well as providing better troubleshooting guidance for users.
HeroUI and Tailwind v4 Setup Automation:
configureGlobalCssForHeroUIinsrc/lib/ast.tsto automatically update or insert the necessary Tailwind v4 and HeroUI directives intoglobals.css, ensuring proper setup and avoiding duplicate configuration.src/scaffold.tsto callconfigureGlobalCssForHeroUIwhen initializing a new project, and to generate a minimalhero.tsfile for Tailwind v4 integration if the config is missing. [1] [2]Developer Experience Improvements:
src/scaffold.tsby adding troubleshooting tips for common npm errors (e.g., EACCES, EEXIST), making it easier for users to resolve issues.CI/CD and Versioning:
.github/workflows/auto-publish.ymlto ensure the correct token is used for publishing to GitHub Packages.package.jsonfrom2.1.0to2.1.2.