Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions apps/www/content/blog/color-theory-for-web-design.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ The table below breaks down the most common contrast requirements you'll encount

### WCAG 2.1 Contrast Ratio Requirements

| Conformance Level | Normal Text (<18pt) | Large Text (18pt or 14pt bold) | UI Components & Graphics |
| :----------------- | :------------------ | :------------------------------ | :----------------------- |
| **AA (Minimum)** | **4.5:1** | **3:1** | **3:1** |
| **AAA (Enhanced)** | **7:1** | **4.5:1** | **4.5:1** |
| Conformance Level | Normal Text (&lt;18pt) | Large Text (&ge;18pt or 14pt bold) | UI Components & Graphics |
| :----------------- | :--------------------: | :--------------------------------: | :----------------------- |
| **AA (Minimum)** | **4.5:1** | **3:1** | **3:1** |
| **AAA (Enhanced)** | **7:1** | **4.5:1** | **4.5:1** |

As you can see, the requirements are more lenient for larger text and essential graphics, but aiming for the higher AA standard for your body copy is a solid starting point for any project.

Expand Down
2 changes: 1 addition & 1 deletion apps/www/content/blog/framer-motion-react.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ Sometimes, seeing the difference laid out helps clarify why one approach is bett

### Animation Props vs Variants

| Feature | Direct Props (e.g., animate={{...}}) | Variants (e.g., variants={...}) |
| Feature | Direct Props (e.g., `animate={{...}}`) | Variants (e.g., `variants={...}`) |
| :---------------- | :-------------------------------------------- | :------------------------------------------ |
| **Readability** | Poor for complex states. JSX gets cluttered. | Excellent. Separates logic from markup. |
| **Reusability** | Low. Logic is tied directly to the component. | High. Can be imported and used anywhere. |
Expand Down
93 changes: 48 additions & 45 deletions apps/www/content/blog/installing-tailwind-css.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,16 @@ Alright, this next part is the most critical step of the entire process. Serious

Open up your `tailwind.config.js` file and find the `content` array. You need to add paths to every single file that might contain a Tailwind class—HTML files, JavaScript components, you name it.

/** @type {import('tailwindcss').Config} \*/
```js
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./public/**/_.html',
'./src/\*\*/_.{js,jsx,ts,tsx,vue}',
],
theme: {
extend: {},
},
plugins: [],
content: ["./public/**/*.html", "./src/**/*.{js,jsx,ts,tsx,vue}"],
theme: {
extend: {},
},
plugins: [],
}
```

This example uses "glob patterns" to find any `.html` files in the `public` folder and a variety of component files inside `src`. Make sure you adjust these paths to match your project's actual folder structure.

Expand Down Expand Up @@ -174,18 +173,17 @@ npx tailwindcss init -p

The real key is modifying your `tailwind.config.js`. You need to point the `content` array to your **JSX** and **TSX** files so Tailwind’s JIT compiler knows where to look for utility classes.

```js
// tailwind.config.js
/** @type {import('tailwindcss').Config} \*/
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/\*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
}
```

Lastly, create a main CSS file (something like `src/index.css`) and drop in the three core Tailwind directives. Just make sure to import this CSS file at the very top of your main entry point, which is usually `src/main.jsx`.

Expand All @@ -199,19 +197,21 @@ But if you're adding Tailwind to an _existing_ Next.js project, the process is n

The only significant difference is the `content` path in `tailwind.config.js`. You’ll want to configure it to scan the `pages`, `components`, and `app` directories commonly found in Next.js apps.

```js
// tailwind.config.js
/** @type {import('tailwindcss').Config} \*/
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/_.{js,ts,jsx,tsx,mdx}',
'./components/\*\*/_.{js,ts,jsx,tsx,mdx}',
'./app/\*_/_.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {},
},
plugins: [],
}
```

Once that's configured, just add the `@tailwind` directives to your `globals.css` file and make sure it’s imported in your `_app.js` or `layout.js` file.

Expand Down Expand Up @@ -251,22 +251,25 @@ You don't have to throw the baby out with the bathwater. The `theme.extend` obje

For instance, here’s how you might add a couple of custom brand colors and a new display font:

```js
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
'brand-primary': '#0A74DA',
'brand-secondary': '#F6C90E',
},
fontFamily: {
'sans': ['Inter', 'sans-serif'],
'display': ['Poppins', 'sans-serif'],
},
},
},
plugins: [],
theme: {
extend: {
colors: {
"brand-primary": "#0A74DA",
"brand-secondary": "#F6C90E",
},
fontFamily: {
sans: ["Inter", "sans-serif"],
display: ["Poppins", "sans-serif"],
},
},
},
plugins: [],
}
```

Just like that, you can start using classes like `bg-brand-primary` or `font-display` right in your markup. This is how you enforce consistency and stick to your design specs, which is a huge step up from a basic installation.

> The ability to extend the theme is what makes Tailwind so scalable. You can start with the defaults for rapid prototyping and then gradually introduce custom tokens as your design system matures, all without breaking your existing work.
Expand All @@ -283,13 +286,13 @@ First, you'll need to install the package:

Then, just require it inside the `plugins` array in your config file.

```js
// tailwind.config.js
module.exports = {
// ...
plugins: [
require('@tailwindcss/typography'),
],
// ...
plugins: [require("@tailwindcss/typography")],
}
```

Now, just by adding a single `prose` className to any container of raw HTML, it will be beautifully styled from top to bottom. This modular approach is great because it keeps your main configuration file clean and makes it simple to add or remove features as your project's needs change.

Expand Down
66 changes: 37 additions & 29 deletions apps/www/content/blog/next-js-getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ Before you dive in, just make sure you have **Node.js version 18.17 or later** i

To get the ball rolling, navigate in your terminal to wherever you want your new project to live. Then, run this single command:

```bash
npx create-next-app@latest
```

This kicks off an interactive setup process that will walk you through a few questions. Its a great way to customize the project to your specific needs right from the get-go.
This kicks off an interactive setup process that will walk you through a few questions. It's a great way to customize the project to your specific needs right from the get-go.

> Answering these prompts thoughtfully is your first big step. The choices you make here—like using TypeScript or setting up Tailwind CSS—will shape your development workflow from day one.

Expand Down Expand Up @@ -140,15 +142,17 @@ Let's get our hands dirty and build out two pages every website needs: a homepag

And that's literally all it takes. You've just created the `/about` route. Now, let's drop some basic React code into `app/about/page.tsx` so it actually displays something.

```tsx
// app/about/page.tsx
export default function AboutPage() {
return (

<main className="p-24">
<h1 className="text-4xl font-bold">About Us</h1>
<p className="mt-4">This is the about page for our first Next.js app!</p>
</main>
); }
return (
<main className="p-24">
<h1 className="text-4xl font-bold">About Us</h1>
<p className="mt-4">This is the about page for our first Next.js app!</p>
</main>
)
}
```

With that code in place, Next.js handles the rest. Fire up your browser and navigate to `localhost:3000/about`, and you'll see your new component rendered on the screen.

Expand All @@ -160,10 +164,11 @@ Now that you have a couple of pages, you need a way for people to get between th

To connect your homepage to the about page, you'll import `Link` from `next/link` and use it almost exactly like a regular `<a>` tag. If you want to dive deeper into building a complete navigation bar, there are some great tutorials on building a [navbar in React.js](https://magicui.design/blog/navbar-in-react-js) that you can easily adapt.

Heres a quick example of how you could add a link to your `app/page.tsx`:
Here's a quick example of how you could add a link to your `app/page.tsx`:

```tsx
// app/page.tsx
import Link from 'next/link';
import Link from "next/link"

export default function HomePage() {
return (
Expand All @@ -177,6 +182,7 @@ export default function HomePage() {
</main>
)
}
```

The `href` prop tells the `<Link>` component where to go. When a user clicks it, Next.js fetches what it needs in the background and swaps out the view without that classic white flash of a page refresh.

Expand Down Expand Up @@ -211,33 +217,35 @@ One of the coolest things about Server Components is the ability to just drop `a

Let's look at a practical example. Say you want to pull in a list of products from a public REST API and display them on a page. Here’s how you could fetch and render that data right inside a page component.

```tsx
// app/products/page.tsx
async function getProducts() {
const res = await fetch('https://dummyjson.com/products');
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data');
}
return res.json();
const res = await fetch('https://dummyjson.com/products');
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data');
}
return res.json();
}

export default async function ProductsPage() {
const data = await getProducts();

return (

<main className="p-24">
<h1 className="mb-8 text-4xl font-bold">Our Products</h1>
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
{data.products.map((product) => (
<div key={product.id} className="rounded-lg border p-4">
<h2 className="text-xl font-semibold">{product.title}</h2>
<p className="mt-2 text-gray-600">{product.description}</p>
return (
<main className="p-24">
<h1 className="mb-8 text-4xl font-bold">Our Products</h1>
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
{{"{"}}data.products.map((product) => (
<div key={product.id} className="rounded-lg border p-4">
<h2 className="text-xl font-semibold">{{"{"}}product.title{{"}"}}</h2>
<p className="mt-2 text-gray-600">{{"{"}}product.description{{"}"}}</p>
</div>
)){{"}"}}
</div>
))}
</div>
</main>
); }
</main>
);
}
```

Did you catch it? `ProductsPage` is an `async` function. That one keyword lets you `await` the `getProducts()` call right before returning your JSX. It’s an incredibly clean and direct way to handle what used to be a much more complicated task.

Expand Down
Loading
Loading