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@3 postcss autoprefixer @tailwindcss/forms @tailwindcss/typography tailwindcss-animate embla-carousel-react class-variance-authority clsx tailwind-merge lucide-react @radix-ui/react-accordion @radix-ui/react-tabs @radix-ui/react-label

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;
    --primary-lighter-hex: theme('colors.primary.200');
    --secondary-lighter-hex: theme('colors.secondary.200');
    --primary-dark-hex: theme('colors.primary.800');
    --secondary-dark-hex: theme('colors.secondary.800');
  }

  .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%;
  }

  body {
    font-family: Arial, Helvetica, sans-serif;
  }

  *,
  ::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.