Installation
Setting up Preline UI in a Remix project using Tailwind CSS.
Please note that the plugin has been tested with the 2.16.2
version of the framework. The framework was installed using the standard npx create-remix@latest <project-name>
command.
If you are using your own project structure or a different version, pay attention to the file paths and features of your version!
Remix is a full stack React web framework. If you haven't set up Tailwind CSS yet, check out Remix Tailwind CSS installation guides.
Install Preline
using your preferred package manager.
npm install preline
Please note, Preline UI uses Tailwind CSS Forms plugin in all form components. Don't forget to install it, if you haven't done so already: npm install -D @tailwindcss/forms
Include Preline in your tailwind.css
file, e.g. projects_root_directory/app/tailwind.css
@import "tailwindcss";
@import "preline/variants.css";
@source "../node_modules/preline/dist/*.js";
/* Optional Preline UI Datepicker Plugin */
/* @import "preline/src/plugins/datepicker/styles.css"; */
/* Plugins */
/* @plugin "@tailwindcss/forms"; */
Create the global.d.ts
file in the project root directory, e.g.
projects_root_directory/app/global.d.ts
import type { IStaticMethods } from "preline/dist";
declare global {
interface Window {
// Optional third-party libraries
_;
$: typeof import("jquery");
jQuery: typeof import("jquery");
DataTable;
Dropzone;
noUiSlider;
VanillaCalendarPro;
// Preline UI
HSStaticMethods: IStaticMethods;
}
}
export {};
Add the Preline UI JavaScript loader to your app entry point, e.g. projects_root_directory/app/root.tsx
import { useEffect } from "react";
import {
...
Outlet,
useLocation,
} from "@remix-run/react";
...
import "./tailwind.css";
// Optional third-party libraries
if (typeof window !== 'undefined') {
Promise.all([
import('jquery'),
import('lodash'),
import('nouislider'),
import('datatables.net'),
import('dropzone/dist/dropzone-min.js'),
import('vanilla-calendar-pro')
]).then(([$, _, noUiSlider, , , VanillaCalendarPro]) => {
window._ = _.default;
window.$ = $.default;
window.jQuery = $.default;
window.DataTable = $.default.fn.dataTable;
window.noUiSlider = noUiSlider.default;
window.VanillaCalendarPro = VanillaCalendarPro;
}).catch(error => {
console.error('Failed to initialize dependencies:', error);
});
}
...
export function Layout({ children }: { children: React.ReactNode }) {
const location = useLocation();
// Preline UI
useEffect(() => {
let mounted = true;
const initPreline = async () => {
try {
if (typeof window !== 'undefined' && mounted) {
await import('preline/dist');
if (window.HSStaticMethods && mounted) window.HSStaticMethods.autoInit();
}
} catch (error) {
console.error('Failed to initialize Preline:', error);
}
};
initPreline();
return () => {
mounted = false;
};
}, [location.pathname]);
return (
<html lang="en">
<head>
...
</head>
<body>
...
{children}
...
</body>
</html>
);
}
export default function App() {
return <Outlet />;
}
Please note, Preline UI comes with some opinionated styles that are applied to components by default. If you want these styles in your project, you may include them into your CSS file. These styles used to come by default in Tailwind v3, so we decided to keep them in Preline UI.
/* Adds pointer cursor to buttons */
@layer base {
button:not(:disabled),
[role="button"]:not(:disabled) {
cursor: pointer;
}
}
/* Defaults hover styles on all devices */
@custom-variant hover (&:hover);
Check out this section for community-shared tips and tricks. It's a spot for finding those handy hacks and solutions that enhance your experience with Preline UI.