# 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"
npm install @porsche-design-system/components-react
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()],
};
});
<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>
);
}
/cn import instead, see
/* app/app.css */
+ @import '@porsche-design-system/components-react';
lightningcss polyfill for the light-dark() CSS function since it's broken.
// 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,
+ },
+ },
};
});
:defined.hydrated:defined
pseudo-class, scope the style to specific tags instead (e.g., :is(p-button, p-accordion, …):not(:defined,[data-ssr])).
See /* app/app.css */
@import '@porsche-design-system/components-react';
+ :not(:defined,[data-ssr]) {
+ visibility: hidden;
+ }
<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>
);
}
/* app/app.css */
@import '@porsche-design-system/components-react';
+ @import 'tailwindcss';
+ @import '@porsche-design-system/components-react/tailwindcss';
<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 />
</>
);
}
