Page UI logo

Manual React.js installation guide

Learn how to install Page UI manually in your React.js app with TypeScript.


Skip the setup and use Shipixen to get a codebase with all components set up.


Step 1

Install dependencies

npm install -D tailwindcss postcss autoprefixer @tailwindcss/forms @tailwindcss/typography tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react @radix-ui/react-accordion

Step 2

Setup Tailwind CSS

npx tailwindcss init -p

Or see how to install Tailwind CSS for your framework in the Tailwind CSS documentation.


Step 3

Add Page UI components and configuration

The directory structure should look like this:

data/
  config/
    colors.js
src/
  components/
    shared/
      ui/
        accordion.tsx
        button.tsx
        glow-bg.tsx
      Image.tsx
      VideoPlayer.tsx
    landing/
      ...unzip here
  lib/
    utils.ts
tailwind.config.js

Step 4

Configure TypeScript aliases

Add the following code to the tsconfig.json file to resolve paths:

tsconfig.json
{
  "compilerOptions": {
+   "baseUrl": ".",
+   "paths": {
+     "@/*": [
+       "./src/*"
+     ]
+   },
    // ...rest of your config
  }
}

Step 5

Configure aliases for Vite or Webpack

If you are using Vite, add the following code to the vite.config.ts so your app can resolve paths without error:

npm i -D @types/node
vite.config.ts
+import path from "path"
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
+ resolve: {
+   alias: {
+     "@": path.resolve(__dirname, "./src"),
+   },
+ },
})

If you are using Webpack, you can add the following code to your webpack.config.js file:

webpack.config.js
+const path = require('path');

module.exports = {
+  resolve: {
+    alias: {
+      '@': path.resolve(__dirname, 'src/'),
+    },
+  },
// ...rest of your config
};

Step 6

Configure CSS

Add the below to your main CSS file, usually index.css, app.css, or global.css.


app/index.css
@import url('https://fonts.googleapis.com/css?family=Inter:400,500,600,700,800&display=swap');

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    --font-space-default: 'Inter';
    --font-space-display: 'Inter';
    --hard-shadow: 0px 29px 52px 0px rgba(0, 0, 0, 0.4),
      22px 25px 16px 0px rgba(0, 0, 0, 0.2);
    --hard-shadow-left: 0px 29px 52px 0px rgba(0, 0, 0, 0.4),
      -22px 25px 16px 0px rgba(0, 0, 0, 0.2);
    /* If you use Shadcn UI already, you should already have these variables defined */
    --background: 0 0% 100%;
    --foreground: 240 10% 3.9%;
    --card: 0 0% 100%;
    --card-foreground: 240 10% 3.9%;
    --popover: 0 0% 100%;
    --popover-foreground: 240 10% 3.9%;
    --primary-foreground: 355.7 100% 97.3%;
    --secondary: 240 4.8% 95.9%;
    --secondary-foreground: 240 5.9% 10%;
    --muted: 240 4.8% 95.9%;
    --muted-foreground: 240 3.8% 46.1%;
    --accent: 240 4.8% 95.9%;
    --accent-foreground: 240 5.9% 10%;
    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 0 0% 98%;
    --border: 240 5.9% 90%;
    --input: 240 5.9% 90%;
    --radius: 0.5rem;
  }

  .dark {
    /* If you use Shadcn UI already, you can skip this block. */
    --background: 20 14.3% 4.1%;
    --foreground: 0 0% 95%;
    --card: 24 9.8% 10%;
    --card-foreground: 0 0% 95%;
    --popover: 0 0% 9%;
    --popover-foreground: 0 0% 95%;
    --primary-foreground: 144.9 80.4% 10%;
    --secondary: 240 3.7% 15.9%;
    --secondary-foreground: 0 0% 98%;
    --muted: 0 0% 15%;
    --muted-foreground: 240 5% 64.9%;
    --accent: 12 6.5% 15.1%;
    --accent-foreground: 0 0% 98%;
    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 0 85.7% 97.3%;
    --border: 240 3.7% 15.9%;
    --input: 240 3.7% 15.9%;
  }

  *,
  ::before,
  ::after {
    @apply border-gray-100 dark:border-neutral-800;
  }

  * {
    @apply font-sans;
  }

  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    @apply font-semibold font-display;
  }
}

@layer utilities {
  .text-balance {
    text-wrap: balance;
  }

  /**
   * Perspective (used for images etc.)
   */
  .perspective-none {
    transform: none;
  }

  .perspective-left {
    box-shadow: var(--hard-shadow);
    transform: perspective(400em) rotateY(-15deg) rotateX(6deg)
      skew(-8deg, 4deg) translate3d(-4%, -2%, 0) scale(0.8);
  }

  .perspective-right {
    box-shadow: var(--hard-shadow-left);
    transform: perspective(400em) rotateY(15deg) rotateX(6deg) skew(8deg, -4deg)
      translate3d(4%, -2%, 0) scale(0.8);
  }

  .perspective-bottom {
    box-shadow: var(--hard-shadow);
    transform: translateY(-4%) perspective(400em) rotateX(18deg) scale(0.9);
  }

  .perspective-bottom-lg {
    box-shadow: var(--hard-shadow);
    transform: perspective(400em) translate3d(0, -6%, 0) rotateX(34deg)
      scale(0.8);
  }

  .perspective-paper {
    box-shadow: var(--hard-shadow);
    transform: rotateX(40deg) rotate(40deg) scale(0.8);
  }

  .perspective-paper-left {
    box-shadow: var(--hard-shadow-left);
    transform: rotateX(40deg) rotate(-40deg) scale(0.8);
  }

  /**
   * Custom shadows
   */
  .hard-shadow {
    box-shadow: var(--hard-shadow);
  }

  .hard-shadow-left {
    box-shadow: var(--hard-shadow-left);
  }

  /**
   * Container utilities
   */
  .container-narrow {
    @apply max-w-4xl;
  }

  .container-wide {
    @apply xl:max-w-6xl;
  }

  .container-ultrawide {
    @apply xl:max-w-7xl;
  }
}


Troubleshooting

Something not quite right? Check out the sample repository for a full working example.

Theming

Get new themes directly from the docs (open any component documentation → select a theme from the dropdown and scroll down to copy to clipboard).

You can also explore themes here.

Alternatively, you can change data/config/color.js manually.

Next steps

Start adding components to your Next.js app.
Go to the component documentation to copy and paste components into your app, or head over to templates or usage examples to see how components are used in a real-world app.