mirror of
https://github.com/netbirdio/docs.git
synced 2026-04-15 23:16:36 +00:00
Style Consistency Changes and Element Improvements (#541)
Co-authored-by: braginini <bangvalo@gmail.com>
This commit is contained in:
211
README.md
211
README.md
@@ -1,6 +1,6 @@
|
||||
# The NetBird documentation
|
||||
|
||||
This repository contains assets required to build the [documentation website for NetBird](https://netbird.io/docs/). It is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
|
||||
This repository contains assets required to build the [documentation website for NetBird](https://netbird.io/docs/). It is built using [Next.js](https://nextjs.org/) with MDX support, a modern React framework for building static and dynamic websites.
|
||||
|
||||
We're glad that you want to contribute!
|
||||
|
||||
@@ -38,6 +38,215 @@ Furthermore, in some cases, one of your reviewers might ask for a technical revi
|
||||
|
||||
Participation in the NetBird community is governed by the [NetBirds' Code of Conduct](https://github.com/netbirdio/netbird/blob/main/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Components and Use
|
||||
|
||||
This documentation uses several custom MDX components. Here's a guide to the most commonly used components:
|
||||
|
||||
### Alert Components
|
||||
|
||||
Use these components to highlight important information:
|
||||
|
||||
#### Note
|
||||
Displays informational content with an orange theme:
|
||||
|
||||
```mdx
|
||||
import {Note} from "@/components/mdx"
|
||||
|
||||
<Note>
|
||||
NetBird is an **[open-source](https://github.com/netbirdio/netbird)** project and can be self-hosted.
|
||||
See a comparison between the self-hosted and cloud-hosted versions [here](/selfhosted/self-hosted-vs-cloud-netbird).
|
||||
</Note>
|
||||
```
|
||||
|
||||
#### Warning
|
||||
Displays warning content with a red theme:
|
||||
|
||||
```mdx
|
||||
import {Warning} from "@/components/mdx"
|
||||
|
||||
<Warning>
|
||||
The API is still in Beta state so some errors might not be handled properly yet.
|
||||
</Warning>
|
||||
```
|
||||
|
||||
#### Success
|
||||
Displays success messages with a green theme:
|
||||
|
||||
```mdx
|
||||
import {Success} from "@/components/mdx"
|
||||
|
||||
<Success>
|
||||
Your configuration has been successfully applied.
|
||||
</Success>
|
||||
```
|
||||
|
||||
### Tiles Component
|
||||
|
||||
Displays a grid of clickable cards with hover effects. Perfect for listing related resources or guides:
|
||||
|
||||
```mdx
|
||||
import {Tiles} from "@/components/Tiles"
|
||||
|
||||
<Tiles
|
||||
title="About NetBird"
|
||||
id="about-netbird"
|
||||
items={[
|
||||
{
|
||||
href: '/about-netbird/how-netbird-works',
|
||||
name: 'How NetBird Works',
|
||||
description: 'Learn about NetBird concepts, architecture, protocols, and how it creates secure networks.',
|
||||
},
|
||||
{
|
||||
href: '/about-netbird/netbird-vs-traditional-vpn',
|
||||
name: 'NetBird vs. Traditional VPN',
|
||||
description: 'Discover how NetBird compares to traditional VPNs and understand the advantages of Zero Trust networking.',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
```
|
||||
|
||||
**Props:**
|
||||
- `title` (string, required): The heading title for the tiles section
|
||||
- `id` (string, optional): Optional id for the heading anchor
|
||||
- `items` (array, required): Array of objects with `href`, `name`, and `description`
|
||||
- `buttonText` (string, optional): Button text (defaults to "Read more" - currently unused as cards are fully clickable)
|
||||
|
||||
### YouTube Component
|
||||
|
||||
Embeds YouTube videos with customizable parameters:
|
||||
|
||||
```mdx
|
||||
import {YouTube} from "@/components/YouTube"
|
||||
|
||||
<YouTube videoId="CFa7SY4Up9k" />
|
||||
|
||||
// With custom parameters
|
||||
<YouTube
|
||||
videoId="CFa7SY4Up9k"
|
||||
title="Video Title"
|
||||
start={175}
|
||||
color="white"
|
||||
modestbranding={1}
|
||||
rel={1}
|
||||
/>
|
||||
|
||||
// Or use a URL instead of videoId
|
||||
<YouTube url="https://www.youtube.com/watch?v=CFa7SY4Up9k" />
|
||||
```
|
||||
|
||||
**Props:**
|
||||
- `videoId` (string): YouTube video ID
|
||||
- `url` (string): YouTube URL (alternative to videoId)
|
||||
- `title` (string, optional): Video title
|
||||
- `start` (number, optional): Start time in seconds
|
||||
- `color` (string, optional): Progress bar color - `'white'` or `'red'` (default: `'white'`)
|
||||
- `modestbranding` (number, optional): Reduces YouTube branding - `0` or `1` (default: `1`)
|
||||
- `controls` (number, optional): Show/hide controls - `0`, `1`, or `2` (default: `1`)
|
||||
- `rel` (number, optional): Show related videos - `0` or `1` (default: `1`)
|
||||
|
||||
### Button Component
|
||||
|
||||
Creates styled buttons with multiple variants:
|
||||
|
||||
```mdx
|
||||
import {Button} from "@/components/Button"
|
||||
|
||||
// Primary button (default)
|
||||
<Button href="https://app.netbird.io/install" arrow="right">
|
||||
Get started
|
||||
</Button>
|
||||
|
||||
// Secondary button
|
||||
<Button href="/path" variant="secondary">
|
||||
Learn more
|
||||
</Button>
|
||||
|
||||
// Outline button
|
||||
<Button href="/path" variant="outline">
|
||||
Explore
|
||||
</Button>
|
||||
|
||||
// Text button
|
||||
<Button href="/path" variant="text" arrow="right">
|
||||
Read more
|
||||
</Button>
|
||||
|
||||
// With left arrow
|
||||
<Button href="/path" arrow="left">
|
||||
Back
|
||||
</Button>
|
||||
```
|
||||
|
||||
**Props:**
|
||||
- `variant` (string, optional): Button style - `'primary'`, `'secondary'`, `'filled'`, `'outline'`, or `'text'` (default: `'primary'`)
|
||||
- `href` (string, optional): Link URL (creates a link if provided, otherwise renders as button)
|
||||
- `arrow` (string, optional): Arrow icon - `'left'` or `'right'`
|
||||
- `children` (required): Button text content
|
||||
|
||||
### Other Common Components
|
||||
|
||||
#### Row and Col
|
||||
Create two-column layouts:
|
||||
|
||||
```mdx
|
||||
import {Row, Col} from "@/components/mdx"
|
||||
|
||||
<Row>
|
||||
<Col>
|
||||
Left column content
|
||||
</Col>
|
||||
<Col sticky>
|
||||
Right column content (sticky on scroll)
|
||||
</Col>
|
||||
</Row>
|
||||
```
|
||||
|
||||
#### Properties and Property
|
||||
Define API properties or configuration options:
|
||||
|
||||
```mdx
|
||||
import {Properties, Property} from "@/components/mdx"
|
||||
|
||||
<Properties>
|
||||
<Property name="apiKey" type="string" required>
|
||||
Your API key for authentication.
|
||||
</Property>
|
||||
<Property name="timeout" type="number" min={0} max={300}>
|
||||
Request timeout in seconds (default: 30).
|
||||
</Property>
|
||||
</Properties>
|
||||
```
|
||||
|
||||
#### Badge
|
||||
Displays small status badges:
|
||||
|
||||
```mdx
|
||||
import {Badge} from "@/components/mdx"
|
||||
|
||||
<Badge>New</Badge>
|
||||
<Badge variant="secondary">Beta</Badge>
|
||||
```
|
||||
|
||||
#### Code Blocks
|
||||
Code syntax highlighting (automatically available):
|
||||
|
||||
```mdx
|
||||
\`\`\`bash
|
||||
npm install
|
||||
npm run dev
|
||||
\`\`\`
|
||||
|
||||
// Or use code groups for multiple languages
|
||||
<CodeGroup>
|
||||
```bash title="Installation"
|
||||
npm install
|
||||
```
|
||||
```yarn title="Installation"
|
||||
yarn install
|
||||
```
|
||||
</CodeGroup>
|
||||
```
|
||||
|
||||
## Thank you
|
||||
|
||||
NetBird thrives on community participation, and we appreciate your contributions to our website and our documentation!
|
||||
@@ -1,49 +0,0 @@
|
||||
import { Button } from '@/components/Button'
|
||||
import { Heading } from '@/components/Heading'
|
||||
|
||||
const aboutNetbird = [
|
||||
{
|
||||
href: '/about-netbird/how-netbird-works',
|
||||
name: 'How NetBird works',
|
||||
description: 'Concepts, architecture, protocols, and more.',
|
||||
},
|
||||
{
|
||||
href: '/about-netbird/netbird-vs-traditional-vpn',
|
||||
name: 'NetBird vs. traditional VPN',
|
||||
description:
|
||||
'Learn how NetBird compares to traditional VPNs and why it is better.',
|
||||
},
|
||||
{
|
||||
href: '/about-netbird/why-wireguard-with-netbird',
|
||||
name: 'Why WireGuard with NetBird',
|
||||
description:
|
||||
'Learn why and how NetBird uses WireGuard.',
|
||||
},
|
||||
]
|
||||
|
||||
export function AboutNetbird() {
|
||||
return (
|
||||
<div className="my-16 xl:max-w-none">
|
||||
<Heading level={2} id="howNetbirdWorks">
|
||||
About NetBird
|
||||
</Heading>
|
||||
<div className="not-prose mt-4 grid grid-cols-1 gap-8 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2 xl:grid-cols-4">
|
||||
{aboutNetbird.map((guide) => (
|
||||
<div key={guide.href}>
|
||||
<h3 className="text-sm font-semibold text-zinc-900 dark:text-white">
|
||||
{guide.name}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
{guide.description}
|
||||
</p>
|
||||
<p className="mt-4">
|
||||
<Button href={guide.href} variant="text" arrow="right">
|
||||
Read more
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -16,14 +16,14 @@ function ArrowIcon(props) {
|
||||
|
||||
const variantStyles = {
|
||||
primary:
|
||||
'rounded-full bg-zinc-900 py-1 px-3 text-white hover:bg-zinc-700 dark:bg-orange-400/10 dark:text-orange-400 dark:ring-1 dark:ring-inset dark:ring-orange-400/20 dark:hover:bg-orange-400/10 dark:hover:text-orange-300 dark:hover:ring-orange-300',
|
||||
'rounded-[5px] bg-netbird text-white border-0 border-transparent duration-300 relative overflow-hidden group',
|
||||
secondary:
|
||||
'rounded-full bg-zinc-100 py-1 px-3 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-800/40 dark:text-zinc-400 dark:ring-1 dark:ring-inset dark:ring-zinc-800 dark:hover:bg-zinc-800 dark:hover:text-zinc-300',
|
||||
filled:
|
||||
'rounded-full bg-zinc-900 py-1 px-3 text-white hover:bg-zinc-700 dark:bg-orange-500 dark:text-white dark:hover:bg-orange-400',
|
||||
'rounded-full bg-zinc-900 py-1 px-3 text-white hover:bg-zinc-700 dark:bg-netbird dark:text-white dark:hover:bg-netbird-dark',
|
||||
outline:
|
||||
'rounded-full py-1 px-3 text-zinc-700 ring-1 ring-inset ring-zinc-900/10 hover:bg-zinc-900/2.5 hover:text-zinc-900 dark:text-zinc-400 dark:ring-white/10 dark:hover:bg-white/5 dark:hover:text-white',
|
||||
text: 'text-orange-500 hover:text-orange-600 dark:text-orange-400 dark:hover:text-orange-500',
|
||||
text: 'text-netbird hover:text-netbird-dark dark:text-netbird dark:hover:text-netbird-light',
|
||||
}
|
||||
|
||||
export function Button({
|
||||
@@ -36,7 +36,7 @@ export function Button({
|
||||
let Component = props.href ? Link : 'button'
|
||||
|
||||
className = clsx(
|
||||
'inline-flex gap-0.5 justify-center overflow-hidden text-sm font-medium transition whitespace-nowrap',
|
||||
'inline-flex gap-0.5 justify-center text-[12px] md:text-xs px-3 py-2 md:px-3 md:py-2 lg:px-4 lg:py-2.5 font-medium transition whitespace-nowrap items-center',
|
||||
variantStyles[variant],
|
||||
className
|
||||
)
|
||||
@@ -52,6 +52,22 @@ export function Button({
|
||||
/>
|
||||
)
|
||||
|
||||
if (variant === 'primary') {
|
||||
return (
|
||||
<div className="relative inline-flex group transition-all" onClick={props.href ? undefined : props.onClick}>
|
||||
<span className="absolute h-full w-full left-0 top-0 blur-sm bg-netbird z-0 transition-all duration-200 transform-gpu opacity-0 group-hover:opacity-100 pointer-events-none"></span>
|
||||
<Component className={className} {...props}>
|
||||
<span className="absolute h-full w-full left-0 top-0 z-10 bg-gradient-to-br from-netbird to-netbird-dark transition-all duration-200 transform-gpu opacity-0 group-hover:opacity-100 pointer-events-none"></span>
|
||||
<span className="z-20 relative flex gap-2 items-center transition-all">
|
||||
{arrow === 'left' && arrowIcon}
|
||||
{children}
|
||||
{arrow === 'right' && arrowIcon}
|
||||
</span>
|
||||
</Component>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Component className={className} {...props}>
|
||||
{arrow === 'left' && arrowIcon}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { forwardRef } from 'react'
|
||||
import Link from 'next/link'
|
||||
import clsx from 'clsx'
|
||||
import { motion, useScroll, useTransform } from 'framer-motion'
|
||||
import { motion } from 'framer-motion'
|
||||
|
||||
import { Button } from '@/components/Button'
|
||||
import { Logo } from '@/components/Logo'
|
||||
@@ -16,10 +16,10 @@ import { useAnnouncements } from '@/components/announcement-banner/AnnouncementB
|
||||
|
||||
function TopLevelNavItem({ href, children }) {
|
||||
return (
|
||||
<li>
|
||||
<li className="block text-[12px] lg:text-[13.5px] m-0 p-0 leading-none">
|
||||
<Link
|
||||
href={href}
|
||||
className="text-sm leading-5 text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white"
|
||||
className="px-2 lg:px-3 py-1 lg:py-2 opacity-60 hover:opacity-100 hover:bg-zinc-900/5 dark:hover:bg-neutral-900/60 hover:border-zinc-900/10 dark:hover:border-neutral-800 border border-transparent rounded-md leading-none transition-all duration-200 text-zinc-900 dark:text-white inline-flex items-center"
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
@@ -32,45 +32,37 @@ export const Header = forwardRef(function Header({ className }, ref) {
|
||||
let isInsideMobileNavigation = useIsInsideMobileNavigation()
|
||||
let { bannerHeight } = useAnnouncements()
|
||||
|
||||
let { scrollY } = useScroll()
|
||||
let bgOpacityLight = useTransform(scrollY, [0, 72], [0.5, 0.9])
|
||||
let bgOpacityDark = useTransform(scrollY, [0, 72], [0.2, 0.8])
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
className,
|
||||
'fixed inset-x-0 top-0 z-40 flex h-14 items-center justify-between gap-12 px-4 transition sm:px-6 lg:left-72 lg:z-30 lg:px-8 xl:left-80',
|
||||
!isInsideMobileNavigation &&
|
||||
'backdrop-blur-sm dark:backdrop-blur lg:left-72 xl:left-80',
|
||||
isInsideMobileNavigation
|
||||
? 'bg-white dark:bg-zinc-900'
|
||||
: 'bg-white/[var(--bg-opacity-light)] dark:bg-zinc-900/[var(--bg-opacity-dark)]'
|
||||
)}
|
||||
className={clsx(
|
||||
className,
|
||||
'fixed inset-x-0 top-0 z-40 flex items-center justify-between gap-3 px-5 transition h-[64px] lg:left-72 lg:z-50 lg:px-8 xl:left-80 min-h-[64px] lg:pointer-events-auto',
|
||||
!isInsideMobileNavigation &&
|
||||
'backdrop-blur-lg bg-white/70 dark:bg-[#181A1D]/95 lg:left-72 xl:left-80',
|
||||
isInsideMobileNavigation &&
|
||||
'bg-white/70 dark:bg-[#181A1D]/95 backdrop-blur-lg'
|
||||
)}
|
||||
style={{
|
||||
'--bg-opacity-light': bgOpacityLight,
|
||||
'--bg-opacity-dark': bgOpacityDark,
|
||||
top: bannerHeight,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
'absolute inset-x-0 top-full h-px transition',
|
||||
(isInsideMobileNavigation || !mobileNavIsOpen) &&
|
||||
'bg-zinc-900/7.5 dark:bg-white/7.5'
|
||||
'absolute inset-x-0 top-full h-px transition border-b border-transparent',
|
||||
!isInsideMobileNavigation && 'border-zinc-900/10 dark:border-neutral-700/50'
|
||||
)}
|
||||
/>
|
||||
<Search />
|
||||
<div className="flex items-center gap-5 lg:hidden">
|
||||
<div className="flex items-center gap-2 lg:hidden">
|
||||
<MobileNavigation />
|
||||
<Link href="/" aria-label="Home">
|
||||
<Logo className="h-6" />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex items-center gap-5">
|
||||
<div className="flex items-center gap-3 xl:gap-2">
|
||||
<nav className="hidden md:block">
|
||||
<ul role="list" className="flex items-center gap-8">
|
||||
<ul role="list" className="flex items-center gap-3 xl:gap-2 m-0 p-0 list-none">
|
||||
<TopLevelNavItem href="https://netbird.io/">Home</TopLevelNavItem>
|
||||
<TopLevelNavItem href="/">Docs</TopLevelNavItem>
|
||||
<TopLevelNavItem href="/api">API</TopLevelNavItem>
|
||||
@@ -79,8 +71,8 @@ export const Header = forwardRef(function Header({ className }, ref) {
|
||||
<TopLevelNavItem href="/slack-url">Support</TopLevelNavItem>
|
||||
</ul>
|
||||
</nav>
|
||||
<div className="hidden md:block md:h-5 md:w-px md:bg-zinc-900/10 md:dark:bg-white/15" />
|
||||
<div className="flex gap-4">
|
||||
<div className="hidden md:block md:h-5 md:w-px md:bg-zinc-900/10 md:dark:bg-neutral-500/20" />
|
||||
<div className="flex gap-2">
|
||||
<MobileSearch />
|
||||
<ModeToggle />
|
||||
</div>
|
||||
|
||||
@@ -3,26 +3,27 @@ import { GridPattern } from '@/components/GridPattern'
|
||||
export function HeroPattern() {
|
||||
return (
|
||||
<div className="absolute inset-0 -z-10 mx-0 max-w-none overflow-hidden">
|
||||
<div className="absolute left-1/2 top-0 ml-[-38rem] h-[25rem] w-[81.25rem] dark:[mask-image:linear-gradient(white,transparent)]">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-[#FFAC1C] to-[#F28C28] opacity-40 [mask-image:radial-gradient(farthest-side_at_top,white,transparent)] dark:from-[#F28C28]/30 dark:to-[#FF7518]/30 dark:opacity-100">
|
||||
<GridPattern
|
||||
width={72}
|
||||
height={56}
|
||||
x="-12"
|
||||
y="4"
|
||||
squares={[
|
||||
[4, 3],
|
||||
[2, 1],
|
||||
[7, 3],
|
||||
[10, 6],
|
||||
]}
|
||||
className="absolute inset-x-0 inset-y-[-50%] h-[200%] w-full skew-y-[-18deg] fill-black/40 stroke-black/50 mix-blend-overlay dark:fill-white/2.5 dark:stroke-white/5"
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute inset-0 hidden dark:block z-0" style={{ backgroundColor: '#181A1D' }}>
|
||||
<GridPattern
|
||||
width={72}
|
||||
height={56}
|
||||
x="-12"
|
||||
y="4"
|
||||
squares={[
|
||||
[4, 3],
|
||||
[2, 1],
|
||||
[7, 3],
|
||||
[10, 6],
|
||||
]}
|
||||
className="absolute inset-x-0 inset-y-[-50%] h-[200%] w-full skew-y-[-18deg] fill-black/40 stroke-black/50 mix-blend-overlay dark:fill-white/2.5 dark:stroke-white/5"
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute inset-x-0 top-0 h-[25rem] dark:[mask-image:linear-gradient(white,transparent)] pointer-events-none z-10">
|
||||
<svg
|
||||
viewBox="0 0 1113 440"
|
||||
preserveAspectRatio="xMidYMin slice"
|
||||
aria-hidden="true"
|
||||
className="absolute left-1/2 top-0 ml-[-19rem] w-[69.5625rem] fill-white blur-[26px] dark:hidden"
|
||||
className="absolute left-1/2 top-0 -translate-x-1/2 w-full min-w-[69.5625rem] h-full fill-white blur-[26px] dark:hidden"
|
||||
>
|
||||
<path d="M.016 439.5s-9.5-300 434-300S882.516 20 882.516 20V0h230.004v439.5H.016Z" />
|
||||
</svg>
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
import { Button } from '@/components/Button'
|
||||
import { Heading } from '@/components/Heading'
|
||||
|
||||
const howToGuides = [
|
||||
{
|
||||
href: '/get-started',
|
||||
name: 'Quickstart guide',
|
||||
description: 'Start using NetBird in under 5 minutes.',
|
||||
},
|
||||
{
|
||||
href: '/manage/access-control/manage-network-access',
|
||||
name: 'Manage network access',
|
||||
description:
|
||||
'Learn how to use access controls to manage access to your machines.',
|
||||
},
|
||||
{
|
||||
href: '/manage/team/add-users-to-your-network',
|
||||
name: 'Add users to your network',
|
||||
description: 'Learn how to add team members to your NetBird network.',
|
||||
},
|
||||
{
|
||||
href: '/manage/network-routes/routing-traffic-to-private-networks',
|
||||
name: 'Route traffic to private networks',
|
||||
description:
|
||||
'Learn how to provide access to LANs, VPS, and corporate private networks.',
|
||||
},
|
||||
{
|
||||
href: '/manage/network-routes/configuring-default-routes-for-internet-traffic',
|
||||
name: 'Configure default routes and traffic for the Internet',
|
||||
description: 'Understand how to set up your network for accessing the internet through default routes, also known as "exit nodes".',
|
||||
},
|
||||
{
|
||||
href: '/manage/activity/traffic-events-logging',
|
||||
name: 'Log and monitor network activity',
|
||||
description:
|
||||
'Learn how to keep track of system and network activities in your account.',
|
||||
},
|
||||
{
|
||||
href: '/manage/dns',
|
||||
name: 'Manage DNS in your network',
|
||||
description:
|
||||
'Learn how to configure name servers in your private network.',
|
||||
},
|
||||
]
|
||||
|
||||
export function HowToGuides() {
|
||||
return (
|
||||
<div className="my-16 xl:max-w-none">
|
||||
<Heading level={2} id="guides">
|
||||
How-To Guides
|
||||
</Heading>
|
||||
<div className="not-prose mt-4 grid grid-cols-1 gap-8 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2 xl:grid-cols-4">
|
||||
{howToGuides.map((guide) => (
|
||||
<div key={guide.href}>
|
||||
<h3 className="text-sm font-semibold text-zinc-900 dark:text-white">
|
||||
{guide.name}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
{guide.description}
|
||||
</p>
|
||||
<p className="mt-4">
|
||||
<Button href={guide.href} variant="text" arrow="right">
|
||||
Read more
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -183,15 +183,15 @@ export function Layout({ children, title, tableOfContents }) {
|
||||
className="contents lg:pointer-events-none lg:fixed lg:inset-0 lg:z-40 lg:flex"
|
||||
style={{ top: bannerHeight }}
|
||||
>
|
||||
<div className="contents lg:pointer-events-auto lg:block lg:w-72 lg:overflow-y-auto lg:border-r lg:border-zinc-900/10 lg:px-6 lg:pb-8 lg:pt-4 lg:dark:border-white/10 xl:w-80">
|
||||
<div className="contents lg:pointer-events-auto lg:block lg:w-72 lg:overflow-y-auto lg:border-r lg:border-zinc-900/10 lg:dark:border-neutral-700/50 lg:px-6 lg:pb-8 lg:pt-4 lg:bg-white/70 lg:dark:bg-[#181A1D]/95 lg:backdrop-blur-lg xl:w-80 lg:overflow-x-visible">
|
||||
<div className="hidden lg:flex">
|
||||
<Link href="/" aria-label="Home">
|
||||
<Logo className="h-6" />
|
||||
</Link>
|
||||
</div>
|
||||
<Header />
|
||||
{router.route.startsWith("/ipa") ? <NavigationAPI className="hidden lg:mt-10 lg:block" tableOfContents={tableOfContents} /> : <NavigationDocs className="hidden lg:mt-10 lg:block" />}
|
||||
</div>
|
||||
<Header />
|
||||
</header>
|
||||
<div className="min-w-0 max-w-2xl flex-auto px-4 py-16 lg:max-w-none lg:pl-8 lg:pr-0 xl:px-5">
|
||||
<main className="py-16">
|
||||
|
||||
@@ -78,7 +78,7 @@ export function MobileNavigation() {
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 top-14 bg-zinc-400/20 backdrop-blur-sm dark:bg-black/40" />
|
||||
<div className="fixed inset-0 top-14 bg-zinc-400/20 backdrop-blur-sm dark:bg-[#181A1D]/40" />
|
||||
</Transition.Child>
|
||||
|
||||
<Dialog.Panel>
|
||||
@@ -105,7 +105,7 @@ export function MobileNavigation() {
|
||||
>
|
||||
<motion.div
|
||||
layoutScroll
|
||||
className="fixed bottom-0 left-0 top-14 w-full overflow-y-auto bg-white px-4 pb-4 pt-6 shadow-lg shadow-zinc-900/10 ring-1 ring-zinc-900/7.5 dark:bg-zinc-900 dark:ring-zinc-800 min-[416px]:max-w-sm sm:px-6 sm:pb-10"
|
||||
className="fixed bottom-0 left-0 top-14 w-full overflow-y-auto bg-white/70 dark:bg-[#181A1D]/95 backdrop-blur-lg px-4 pb-4 pt-6 shadow-lg shadow-zinc-900/10 ring-1 ring-zinc-900/7.5 dark:ring-neutral-500/10 min-[416px]:max-w-sm sm:px-6 sm:pb-10"
|
||||
>
|
||||
{router.route.startsWith("/ipa") ? <NavigationAPI tableOfContents={[]} /> :
|
||||
<NavigationDocs />}
|
||||
|
||||
90
src/components/Tiles.jsx
Normal file
90
src/components/Tiles.jsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import Link from 'next/link'
|
||||
import { motion, useMotionTemplate, useMotionValue } from 'framer-motion'
|
||||
|
||||
import { GridPattern } from '@/components/GridPattern'
|
||||
import { Heading } from '@/components/Heading'
|
||||
|
||||
function TilePattern({ mouseX, mouseY }) {
|
||||
let maskImage = useMotionTemplate`radial-gradient(180px at ${mouseX}px ${mouseY}px, white, transparent)`
|
||||
let style = { maskImage, WebkitMaskImage: maskImage }
|
||||
|
||||
return (
|
||||
<div className="pointer-events-none">
|
||||
<div className="absolute inset-0 rounded-2xl transition duration-300 [mask-image:linear-gradient(white,transparent)] group-hover:opacity-50">
|
||||
<GridPattern
|
||||
width={72}
|
||||
height={56}
|
||||
x="50%"
|
||||
className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/[0.02] stroke-black/5 dark:fill-white/1 dark:stroke-white/2.5"
|
||||
/>
|
||||
</div>
|
||||
<motion.div
|
||||
className="absolute inset-0 rounded-2xl bg-gradient-to-r from-[#FFAC1C] to-[#F28C28] opacity-0 transition duration-300 group-hover:opacity-30 dark:group-hover:opacity-60 dark:from-[#F28C28]/30 dark:to-[#FF7518]/30"
|
||||
style={style}
|
||||
/>
|
||||
<motion.div
|
||||
className="absolute inset-0 rounded-2xl opacity-0 mix-blend-overlay transition duration-300 group-hover:opacity-100"
|
||||
style={style}
|
||||
>
|
||||
<GridPattern
|
||||
width={72}
|
||||
height={56}
|
||||
x="50%"
|
||||
className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/50 stroke-black/70 dark:fill-white/2.5 dark:stroke-white/10"
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Tiles component for displaying a grid of tile items
|
||||
*
|
||||
* @param {string} title - The heading title for the tiles section
|
||||
* @param {string} [id] - Optional id for the heading anchor
|
||||
* @param {Array<{href: string, name: string, description: string}>} items - Array of tile items
|
||||
* @param {string} [buttonText='Read more'] - Optional button text (defaults to "Read more")
|
||||
*/
|
||||
export function Tiles({ title, id, items, buttonText = 'Read more' }) {
|
||||
return (
|
||||
<div className="my-16 xl:max-w-none">
|
||||
<Heading level={2} id={id} anchor={!!id}>
|
||||
{title}
|
||||
</Heading>
|
||||
<div className="not-prose mt-4 grid grid-cols-1 gap-8 border-t border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2">
|
||||
{items.map((item) => {
|
||||
let mouseX = useMotionValue(0)
|
||||
let mouseY = useMotionValue(0)
|
||||
|
||||
function onMouseMove({ currentTarget, clientX, clientY }) {
|
||||
let { left, top } = currentTarget.getBoundingClientRect()
|
||||
mouseX.set(clientX - left)
|
||||
mouseY.set(clientY - top)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
key={item.href}
|
||||
onMouseMove={onMouseMove}
|
||||
className="group relative flex rounded-2xl bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5"
|
||||
>
|
||||
<TilePattern mouseX={mouseX} mouseY={mouseY} />
|
||||
<div className="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20" />
|
||||
<div className="relative rounded-2xl px-4 pb-4 pt-4">
|
||||
<h3 className="text-sm font-semibold leading-7 text-zinc-900 dark:text-white">
|
||||
<Link href={item.href}>
|
||||
<span className="absolute inset-0 rounded-2xl" />
|
||||
{item.name}
|
||||
</Link>
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
123
src/components/YouTube.jsx
Normal file
123
src/components/YouTube.jsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import clsx from 'clsx'
|
||||
|
||||
/**
|
||||
* Extracts YouTube video ID from various YouTube URL formats
|
||||
*/
|
||||
function extractYouTubeId(url) {
|
||||
if (!url) return null
|
||||
|
||||
// If it's already just an ID, return it
|
||||
if (!url.includes('youtube.com') && !url.includes('youtu.be') && !url.includes('/')) {
|
||||
return url
|
||||
}
|
||||
|
||||
// Handle youtu.be short links
|
||||
if (url.includes('youtu.be/')) {
|
||||
const match = url.match(/youtu\.be\/([a-zA-Z0-9_-]+)/)
|
||||
return match ? match[1] : null
|
||||
}
|
||||
|
||||
// Handle youtube.com/watch?v=...
|
||||
if (url.includes('youtube.com/watch')) {
|
||||
const match = url.match(/[?&]v=([a-zA-Z0-9_-]+)/)
|
||||
return match ? match[1] : null
|
||||
}
|
||||
|
||||
// Handle youtube.com/embed/...
|
||||
if (url.includes('youtube.com/embed/')) {
|
||||
const match = url.match(/embed\/([a-zA-Z0-9_-]+)/)
|
||||
return match ? match[1] : null
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* YouTube video embed component
|
||||
*
|
||||
* Usage:
|
||||
* <YouTube videoId="CFa7SY4Up9k" />
|
||||
* <YouTube url="https://www.youtube.com/watch?v=CFa7SY4Up9k" />
|
||||
* <YouTube videoId="CFa7SY4Up9k" title="Video Title" />
|
||||
* <YouTube videoId="CFa7SY4Up9k" start={175} />
|
||||
* <YouTube videoId="CFa7SY4Up9k" color="white" modestbranding={1} />
|
||||
*/
|
||||
export function YouTube({
|
||||
videoId,
|
||||
url,
|
||||
title,
|
||||
start,
|
||||
color = 'white', // 'red' | 'white' - controls progress bar color (default: white)
|
||||
modestbranding = 1, // 0 | 1 - reduces YouTube branding (1 = minimal, default: 1 = minimal)
|
||||
controls, // 0 | 1 | 2 - show/hide player controls (0 = hide, 1 = show, 2 = delayed)
|
||||
rel = 1, // 0 | 1 - show related videos from same channel (0 = hide, 1 = show, default: 1 = show)
|
||||
className,
|
||||
...props
|
||||
}) {
|
||||
// Extract video ID from URL if provided
|
||||
const id = videoId || extractYouTubeId(url)
|
||||
|
||||
if (!id) {
|
||||
console.warn('YouTube component: No valid video ID or URL provided')
|
||||
return null
|
||||
}
|
||||
|
||||
// Extract start time from URL if present
|
||||
let startTime = start
|
||||
if (!startTime && url) {
|
||||
const startMatch = url.match(/[?&]start=(\d+)/)
|
||||
if (startMatch) {
|
||||
startTime = parseInt(startMatch[1], 10)
|
||||
}
|
||||
}
|
||||
|
||||
// Build embed URL with parameters
|
||||
let embedUrl = `https://www.youtube.com/embed/${id}`
|
||||
const params = new URLSearchParams()
|
||||
|
||||
if (startTime) {
|
||||
params.append('start', startTime.toString())
|
||||
}
|
||||
|
||||
// Add color parameter - YouTube defaults to 'red', so we need to set 'white' explicitly
|
||||
if (color === 'white') {
|
||||
params.append('color', 'white')
|
||||
}
|
||||
if (modestbranding === 1) {
|
||||
params.append('modestbranding', '1')
|
||||
}
|
||||
if (controls !== undefined && controls !== 1) {
|
||||
params.append('controls', controls.toString())
|
||||
}
|
||||
// Only add rel parameter if explicitly set to 0 to hide related videos
|
||||
// YouTube's default is 1 (show), so we don't need to add it when rel === 1
|
||||
if (rel === 0) {
|
||||
params.append('rel', '0')
|
||||
}
|
||||
|
||||
const queryString = params.toString()
|
||||
if (queryString) {
|
||||
embedUrl += `?${queryString}`
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'relative w-full overflow-hidden my-6',
|
||||
'ml-[10px] mr-auto',
|
||||
'max-w-[40rem] lg:max-w-[50rem]',
|
||||
className
|
||||
)}
|
||||
style={{ aspectRatio: '16 / 9' }}
|
||||
{...props}
|
||||
>
|
||||
<iframe
|
||||
src={embedUrl}
|
||||
title={title || 'YouTube video player'}
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowFullScreen
|
||||
className="absolute top-0 left-0 w-full h-full rounded-lg border-0"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -2,11 +2,13 @@ import Link from 'next/link'
|
||||
import clsx from 'clsx'
|
||||
|
||||
import { Heading } from '@/components/Heading'
|
||||
import { YouTube } from '@/components/YouTube'
|
||||
|
||||
export const a = Link
|
||||
export { Button } from '@/components/Button'
|
||||
export { CodeGroup, Code as code, Pre as pre } from '@/components/Code'
|
||||
export { Badge } from '@/components/Badge'
|
||||
export { YouTube }
|
||||
|
||||
export const h2 = function H2(props) {
|
||||
return <Heading level={2} {...props} />
|
||||
@@ -40,6 +42,43 @@ function InfoIcon(props) {
|
||||
)
|
||||
}
|
||||
|
||||
function WarningIcon(props) {
|
||||
return (
|
||||
<svg viewBox="0 0 16 16" aria-hidden="true" {...props}>
|
||||
<path
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
d="M8 3.5L3.5 12.5h9L8 3.5z"
|
||||
/>
|
||||
<circle cx="8" cy="9" r=".5" fill="none" />
|
||||
<path
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
d="M8 6.5v1"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
function SuccessIcon(props) {
|
||||
return (
|
||||
<svg viewBox="0 0 16 16" aria-hidden="true" {...props}>
|
||||
<circle cx="8" cy="8" r="8" strokeWidth="0" />
|
||||
<path
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="1.5"
|
||||
d="M5.5 8l2 2 3-3"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function Note({ children }) {
|
||||
return (
|
||||
<div className="my-6 flex gap-2.5 rounded-l border border-orange-500/20 bg-orange-50/50 p-4 leading-6 text-orange-900 dark:border-orange-500/30 dark:bg-orange-500/5 dark:text-orange-200 dark:[--tw-prose-links-hover:theme(colors.orange.300)] dark:[--tw-prose-links:theme(colors.white)]">
|
||||
@@ -51,6 +90,28 @@ export function Note({ children }) {
|
||||
)
|
||||
}
|
||||
|
||||
export function Warning({ children }) {
|
||||
return (
|
||||
<div className="my-6 flex gap-2.5 rounded-l border border-red-500/20 bg-red-50/50 p-4 leading-6 text-red-900 dark:border-red-500/30 dark:bg-red-500/5 dark:text-red-200 dark:[--tw-prose-links-hover:theme(colors.red.300)] dark:[--tw-prose-links:theme(colors.white)]">
|
||||
<WarningIcon className="mt-1 h-4 w-4 flex-none fill-red-500 stroke-white dark:fill-red-200/20 dark:stroke-red-200" />
|
||||
<div className="[&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function Success({ children }) {
|
||||
return (
|
||||
<div className="my-6 flex gap-2.5 rounded-l border border-green-500/20 bg-green-50/50 p-4 leading-6 text-green-900 dark:border-green-500/30 dark:bg-green-500/5 dark:text-green-200 dark:[--tw-prose-links-hover:theme(colors.green.300)] dark:[--tw-prose-links:theme(colors.white)]">
|
||||
<SuccessIcon className="mt-1 h-4 w-4 flex-none fill-green-500 stroke-white dark:fill-green-200/20 dark:stroke-green-200" />
|
||||
<div className="[&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function Row({ children }) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 items-start gap-x-16 gap-y-10 xl:max-w-none xl:grid-cols-2">
|
||||
|
||||
@@ -44,7 +44,7 @@ export default function Document() {
|
||||
<script dangerouslySetInnerHTML={{ __html: modeScript }} />
|
||||
<link rel="shortcut icon" href="/docs-static/img/favicon.ico" />
|
||||
</Head>
|
||||
<body className="bg-white antialiased dark:bg-zinc-900">
|
||||
<body className="bg-white antialiased dark:bg-[#181A1D]">
|
||||
<GoogleTageManagerBodyScript />
|
||||
<Main />
|
||||
<NextScript />
|
||||
|
||||
@@ -7,9 +7,7 @@ export const title = 'Getting Started'
|
||||
Welcome to NetBird! This guide will walk you through our new onboarding process to create your account, connect your first devices,
|
||||
and build a secure peer-to-peer overlay network in less than ten minutes.
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/dr0u-u9uD84" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="dr0u-u9uD84" />
|
||||
|
||||
## Create Your Account
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@ The NetBird client (agent) allows a peer to join a pre-existing NetBird deployme
|
||||
there are both managed and [self-hosted](https://docs.netbird.io/selfhosted/selfhosted-quickstart) options available.
|
||||
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/AK0Ct-ULFKg?start=669" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="AK0Ct-ULFKg" start={669} />
|
||||
|
||||
<Note>
|
||||
The NetBird package is officially included starting from OPNsense `25.7.3`.
|
||||
|
||||
@@ -7,9 +7,7 @@ there are both managed and [self-hosted](https://docs.netbird.io/selfhosted/self
|
||||
This installation is intended for early adopters while the pfSense package is under review and not yet available in the pfSense package manager.
|
||||
</Note>
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/Kgrcquyeohc" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="Kgrcquyeohc" />
|
||||
|
||||
## Prerequisites
|
||||
- Shell/SSH access to pfSense (via Web UI shell or remote SSH)
|
||||
|
||||
@@ -110,9 +110,7 @@ Now you should see a successful connection message and you're good to go! Now if
|
||||
|
||||
## Proxmox Setup Tutorial
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/KMNS_JoHFhg" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="KMNS_JoHFhg" />
|
||||
|
||||
## Additional Resources
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@ import {Note} from "@/components/mdx";
|
||||
|
||||
# Install NetBird on the Raspberry Pi
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/P0aAdYnex80" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="P0aAdYnex80" />
|
||||
|
||||
Start by downloading [Raspberry Pi Imager](https://www.raspberrypi.com/software/) for your operating system and inserting a microSD card with at least 8GB of capacity, though 32GB is recommended for breathing room.
|
||||
|
||||
|
||||
@@ -120,9 +120,7 @@ For a complete cleanup, you should also remove the Synology NAS as a peer from y
|
||||
|
||||
## Video Walkthrough
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/9VKOAe_T038" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="9VKOAe_T038" />
|
||||
|
||||
## Support Us
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import {Note} from "@/components/mdx"
|
||||
import {HowToGuides} from "@/components/How-To-Guides"
|
||||
import {AboutNetbird} from "@/components/AboutNetbird"
|
||||
import {Tiles} from "@/components/Tiles"
|
||||
import {YouTube} from "@/components/YouTube"
|
||||
import {Button} from "@/components/Button"
|
||||
|
||||
export const description =
|
||||
'Learn everything there is to know about NetBird.'
|
||||
|
||||
# Introduction to NetBird
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/CFa7SY4Up9k?si=FVdoVW0ClxsJgd4t" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="CFa7SY4Up9k" />
|
||||
|
||||
NetBird is an Open Source Zero Trust Networking platform that allows you to create secure private networks for your
|
||||
organization or home. We designed NetBird to be simple and fast, requiring near-zero configuration effort and leaving
|
||||
@@ -30,8 +29,85 @@ It literally takes less than 5 minutes to deploy a secure point-to-point VPN wit
|
||||
<Button href="https://github.com/netbirdio/netbird" variant="outline" children="Explore Github" />
|
||||
</div>
|
||||
|
||||
<AboutNetbird />
|
||||
<Tiles
|
||||
title="About NetBird"
|
||||
id="about-netbird"
|
||||
items={[
|
||||
{
|
||||
href: '/about-netbird/how-netbird-works',
|
||||
name: 'How NetBird Works',
|
||||
description: 'Learn about NetBird concepts, architecture, protocols, and how it creates secure networks.',
|
||||
},
|
||||
{
|
||||
href: '/about-netbird/netbird-vs-traditional-vpn',
|
||||
name: 'NetBird vs. Traditional VPN',
|
||||
description:
|
||||
'Discover how NetBird compares to traditional VPNs and understand the advantages of Zero Trust networking.',
|
||||
},
|
||||
{
|
||||
href: '/about-netbird/why-wireguard-with-netbird',
|
||||
name: 'Why WireGuard with NetBird',
|
||||
description:
|
||||
'Explore why NetBird uses WireGuard and how it provides fast, secure, and modern networking.',
|
||||
},
|
||||
{
|
||||
href: '/about-netbird/browser-client-architecture',
|
||||
name: 'Browser Client Architecture',
|
||||
description:
|
||||
'Understand how the Browser Client enables secure remote access directly from web browsers using WebAssembly.',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<HowToGuides />
|
||||
<Tiles
|
||||
title="Guides"
|
||||
id="guides"
|
||||
items={[
|
||||
{
|
||||
href: '/get-started',
|
||||
name: 'Quickstart Guide',
|
||||
description: 'Get started with NetBird in under 5 minutes. Learn the basics of installation and setup.',
|
||||
},
|
||||
{
|
||||
href: '/selfhosted/selfhosted-quickstart',
|
||||
name: 'Self-Hosted Quickstart',
|
||||
description: 'Get started with self-hosted NetBird in 5 minutes. Learn how to deploy and configure your own NetBird instance.',
|
||||
},
|
||||
{
|
||||
href: '/manage/access-control/manage-network-access',
|
||||
name: 'Manage Network Access',
|
||||
description:
|
||||
'Learn how to use access control policies to manage and secure access to your machines and resources.',
|
||||
},
|
||||
{
|
||||
href: '/manage/team/add-users-to-your-network',
|
||||
name: 'Add Users to Your Network',
|
||||
description: 'Discover how to add team members to your NetBird network and manage user access.',
|
||||
},
|
||||
{
|
||||
href: '/manage/network-routes/routing-traffic-to-private-networks',
|
||||
name: 'Route Traffic to Private Networks',
|
||||
description:
|
||||
'Learn how to provide secure access to LANs, VPS instances, and corporate private networks.',
|
||||
},
|
||||
{
|
||||
href: '/manage/network-routes/configuring-default-routes-for-internet-traffic',
|
||||
name: 'Configure Default Routes',
|
||||
description: 'Set up default routes for internet traffic and configure exit nodes for your network.',
|
||||
},
|
||||
{
|
||||
href: '/manage/activity/traffic-events-logging',
|
||||
name: 'Log and Monitor Network Activity',
|
||||
description:
|
||||
'Learn how to track and monitor system and network activities in your NetBird account.',
|
||||
},
|
||||
{
|
||||
href: '/manage/dns',
|
||||
name: 'Manage DNS in Your Network',
|
||||
description:
|
||||
'Configure custom name servers and DNS settings for your private network.',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# Allow Only Intune-Managed Devices to Access Your Network
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/W4DaE4Dj04o" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="W4DaE4Dj04o" />
|
||||
|
||||
<Note>
|
||||
TLDR: Devices marked as "Non-compliant" in Intune will automatically lose access, ensuring strict adherence to your security policies.
|
||||
|
||||
@@ -10,9 +10,7 @@ The integration of NetBird with SentinelOne provides organizations with robust s
|
||||
only IT-managed devices running SentinelOne to access the network. Additionally, the integration uses SentinelOne's threat
|
||||
detection capabilities, enabling administrators to further limit network access based on the security posture of each device.
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/QVs0RhprVYM" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="QVs0RhprVYM" />
|
||||
|
||||
SentinelOne's endpoint protection provides real-time threat detection and automated response capabilities. By integrating with
|
||||
SentinelOne Singularity, NetBird can ensure that only devices with active security monitoring and protection can access the network.
|
||||
|
||||
@@ -8,9 +8,7 @@ your environment.
|
||||
|
||||
Watch our Access Control video on YouTube:
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/WtZD_q-g_Jc" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="WtZD_q-g_Jc" />
|
||||
|
||||
<Note>
|
||||
For a visual overview of your access policies and network topology, check out the [Control Center](/manage/control-center), which provides an interactive graph view of peers, groups, and their access relationships.
|
||||
|
||||
@@ -10,9 +10,7 @@ By using these diverse checking capabilities, NetBird empowers you to create a r
|
||||
## Setting Up Posture Checks
|
||||
|
||||
Setting up posture checks in NetBird is straightforward, you can follow the example in the video below:
|
||||
<div className="videowrapperadjusted" >
|
||||
<iframe src="https://www.youtube.com/embed/-KlJUBuZrpo" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="-KlJUBuZrpo" />
|
||||
|
||||
Or follow the guide with other examples below:
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ and many other key network events.
|
||||
|
||||
To get started with event logging in NetBird, watch this introductory video:
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/UlnMo1KYXPU?si=JdzEr9v2EZHlP7lc" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
<YouTube videoId="UlnMo1KYXPU" />
|
||||
|
||||
|
||||
## Access the Audit Events Logging View
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
|
||||
# Routing Traffic to Private Networks
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/VQuPuBOAknQ" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="VQuPuBOAknQ" />
|
||||
<br/><br/>
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ an Android or iOS device, a personal laptop, a single-board computer like Raspbe
|
||||
|
||||
## Related Video Content
|
||||
For details on adding machines to your network, part of our "Getting started with NetBird" video covers this topic:
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/JRCZy4rLi-c?start=34" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
<YouTube videoId="JRCZy4rLi-c" start={34} />
|
||||
|
||||
## Use NetBird web UI to add new peers
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Administrators then can assess whether the peer is eligible to join the network.
|
||||
|
||||
For details on the peer approval feature, part of our "Getting started with NetBird" video covers this topic:
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/JRCZy4rLi-c?start=335" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
<YouTube videoId="JRCZy4rLi-c" start={335} />
|
||||
|
||||
## Enable peer approval
|
||||
To enable peer approval, navigate to [Settings » Authentication](https://app.netbird.io/settings) and enable 'Peer approval'.
|
||||
|
||||
@@ -6,7 +6,7 @@ It simply associates a machine with an account on a first run.
|
||||
|
||||
## Related Video Content
|
||||
For a comprehensive guide, part of our "Getting started with NetBird" video specifically covers setup keys:
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/JRCZy4rLi-c?start=175" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
<YouTube videoId="JRCZy4rLi-c" start={175} />
|
||||
|
||||
The setup key can be provided as a parameter to the ```netbird up``` command.
|
||||
This makes it possible to run automated deployments with infrastructure-as-code software like Ansible, Cloudformation or Terraform.
|
||||
|
||||
@@ -26,9 +26,7 @@ eliminating the need for manual grouping.
|
||||
This video guide walks you through an example integration with Microsoft Entra ID, covering both user onboarding and
|
||||
offboarding scenarios:
|
||||
|
||||
<div className="videowrapper">
|
||||
<iframe src="https://www.youtube.com/embed/RxYWTpf7cgY" allow="fullscreen;"></iframe>
|
||||
</div>
|
||||
<YouTube videoId="RxYWTpf7cgY" />
|
||||
|
||||
## Supported Identity Providers
|
||||
|
||||
|
||||
@@ -59,68 +59,6 @@
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.videowrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
overflow: hidden;
|
||||
margin-left: 10px;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.videowrapper {
|
||||
max-width: 40rem; /* matches prose max-width-2xl */
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.videowrapper {
|
||||
max-width: 50rem; /* matches prose max-width-3xl */
|
||||
}
|
||||
}
|
||||
|
||||
.videowrapper iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.videowrapperadjusted {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
overflow: hidden;
|
||||
margin-left: 10px;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.videowrapperadjusted {
|
||||
max-width: 40rem; /* matches prose max-width-2xl */
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.videowrapperadjusted {
|
||||
max-width: 50rem; /* matches prose max-width-3xl */
|
||||
}
|
||||
}
|
||||
|
||||
.videowrapperadjusted iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.spacer-sm {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user