Porsche Design System
You are currently viewing an earlier release of the Porsche Design System.Switch to the latest Porsche Design System documentation.
SearchNavigate to GitHub repository of Porsche Design SystemOpen sidebar
Getting StartedDemoFormAdvancedFAQ
React Router Table of Contents Quick start To build a React Router application using the Porsche Design System, follow these steps. This guide is based on the following dependencies:
@react-router/*@7react@19tailwindcss@4@porsche-design-system/components-react@4
# Create a new application by executing: npx create-react-router@latest # Follow the installation wizard to set everything up: ✔ Where should we create your new project? "./my-app" ✔ Initialize a new git repository? "Yes" ✔ Install dependencies with npm? "Yes"
You're all set! Start building your own application now. Integration Step 1 Install the Porsche Design System within your project directory.
npm install @porsche-design-system/components-react
Step 2 Define the environment-based process.browser variable. This ensures that the correct Porsche Design System components are bundled for both client and server environments.
// vite.config.ts import { reactRouter } from '@react-router/dev/vite'; import tailwindcss from '@tailwindcss/vite'; import { defineConfig } from 'vite'; import tsconfigPaths from 'vite-tsconfig-paths'; + export default defineConfig(({ isSsrBuild }) => { return { + define: { + 'process.browser': JSON.stringify(!isSsrBuild), + }, plugins: [tailwindcss(), reactRouter(), tsconfigPaths()], }; });
Step 3 Wrap your app with the <PorscheDesignSystemProvider />.
// app/root.tsx + import { PorscheDesignSystemProvider } from '@porsche-design-system/components-react/ssr'; // ensure to import from ssr subpackage! export default function App() { return ( + <PorscheDesignSystemProvider> <Outlet /> + </PorscheDesignSystemProvider> ); }
Step 4 Add the PDS Stylesheet to your main CSS file — this single import covers all required and recommended global styles (for websites primarily targeting users in China, use the /cn import instead, see China CDN).
/* app/app.css */ + @import '@porsche-design-system/components-react';
Disable the lightningcss polyfill for the light-dark() CSS function since it's broken. Learn more
// vite.config.ts + import { Features } from 'lightningcss'; export default defineConfig(({ isSsrBuild }) => { return { + css: { + transformer: 'lightningcss', + // disables light-dark() polyfill of lightningcss which is broken https://github.com/porsche-design-system/porsche-design-system/issues/4257 + lightningcss: { + exclude: Features.LightDark, + }, + }, }; });
To prevent FOUC, hide elements until they are either registered (:defined) or fully rendered by Stencil (.hydrated). If you run into issues with the :defined pseudo-class, scope the style to specific tags instead (e.g., :is(p-button, p-accordion, …):not(:defined,[data-ssr])). See Initialization for more details.
/* app/app.css */ @import '@porsche-design-system/components-react'; + :not(:defined,[data-ssr]) { + visibility: hidden; + }
Step 5 (recommended) To improve your web application's loading performance, integrate Partials from the Porsche Design System into the <head> section of your HTML to preload fonts, icons, and component chunks.
// app/root.tsx import { Links, Meta, Scripts, ScrollRestoration, useRouteLoaderData, } from 'react-router'; + import { + getComponentChunkLinks, + getFontLinks, + getIconLinks, + getMetaTagsAndIconLinks, + } from '@porsche-design-system/components-react/partials'; + export async function loader() { + return { + headPartials: ( + <> + {/* preloads fonts */} + {getFontLinks({ format: 'jsx' })} + {/* preloads icons */} + {getIconLinks({ format: 'jsx' })} + {/* preloads components */} + {getComponentChunkLinks({ format: 'jsx' })} + {/* injects favicon, apple touch icons, android touch icons, etc. */} + {getMetaTagsAndIconLinks({ appTitle: 'Porsche', format: 'jsx' })} + </> + ), + }; + } export function Layout({ children }: { children: React.ReactNode }) { + const partials = useRouteLoaderData<typeof loader>('root'); return ( <html lang="en"> <head> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <Meta /> <Links /> + {partials?.headPartials} </head> <body> {children} <ScrollRestoration /> <Scripts /> </body> </html> ); }
Step 6 (recommended) Import Tailwind CSS and the PDS Tailwind CSS Theme — a utility-first setup that ensures seamless styling consistency with Porsche's design principles.
/* app/app.css */ @import '@porsche-design-system/components-react'; + @import 'tailwindcss'; + @import '@porsche-design-system/components-react/tailwindcss';
Step 7 Add a Porsche Design System component (e.g., <PWordmark />) with some Tailwind CSS styles. Then, run npm run dev and verify that the component and styles display correctly.
// routes/home.tsx import { PWordmark } from '@porsche-design-system/components-react/ssr'; // ensure to import from ssr subpackage! export default function Home() { return ( <> <div className="grid justify-items-center gap-fluid-md m-static-lg p-fluid-lg bg-surface rounded-lg"> <PWordmark /> <h1 className="prose-heading-4xl">Porsche Design System</h1> </div> <Welcome /> </> ); }
Global settingsColor SchemeAll color tokens use the light-dark() CSS function. Set the theme via the CSS color-scheme property: light for light mode, dark for dark mode, or light dark to follow the user's system preference.LightDarkLight DarkDirectionThe dir global attribute in HTML changes the direction of text and other content within an element. It's most often used on the <html> tag to set the entire page's direction, which is crucial for supporting languages that are written from right to left (RTL), such as Arabic and Hebrew. For example, using <html dir="rtl"> makes the entire page display from right to left, adjusting the layout and text flow accordingly.LTR (left-to-right)RTL (right-to-left)Text ZoomTo ensure accessibility and comply with WCAG 2.2 AA standards, it is mandatory for web content to support text resizing up to at least 200% without loss of content or functionality. Using relative units like rem is a best practice for achieving this, as they allow the text to scale uniformly based on the user's browser settings.100%130%150%200%