import React, { Fragment, useEffect, useRef, useState } from 'react'; import { Helmet } from 'react-helmet-async'; import { useAccount, useBufferedFeeds, useSubplebbit } from '@plebbit/plebbit-react-hooks'; import { Link, useNavigate } from 'react-router-dom'; import { Container, Header, Logo, Page, Search, About, AboutTitle, AboutContent, Boards, BoardsTitle, BoardsContent, Footer } from '../styled/views/Home.styled'; import BoardAvatar from '../BoardAvatar'; import OfflineIndicator from '../OfflineIndicator'; import CreateBoardModal from '../modals/CreateBoardModal'; import useGeneralStore from '../../hooks/stores/useGeneralStore'; import packageJson from '../../../package.json'; import { Tooltip } from 'react-tooltip'; const { version } = packageJson; const commitRef = process?.env?.REACT_APP_COMMIT_REF ? ` ${process.env.REACT_APP_COMMIT_REF.slice(0, 7)}` : ''; const SubplebbitTitle = ({ address }) => { const subplebbitAddress = address; const subplebbit = useSubplebbit({ subplebbitAddress }); const title = subplebbit.title ?? null; return <>{title ? {title} :  }; }; const Home = () => { const { bodyStyle, setBodyStyle, defaultSubplebbits, setSelectedAddress, selectedStyle, setSelectedStyle, setSelectedTitle } = useGeneralStore((state) => state); const account = useAccount(); const navigate = useNavigate(); const inputRef = useRef(null); const prevStyle = useRef(selectedStyle); const prevBodyStyle = useRef(bodyStyle); const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false); // preload default subs and subscriptions useBufferedFeeds({ feedsOptions: [ { subplebbitAddresses: defaultSubplebbits.map((subplebbit) => subplebbit.address), sortType: 'active' }, { subplebbitAddresses: account?.subscriptions, sortType: 'active' }, ], }); // prevent dark mode useEffect(() => { const currentPrevStyle = prevStyle.current; const currentPrevBodyStyle = prevBodyStyle.current; setBodyStyle({ background: '#ffe url(assets/fade.png) top repeat-x', color: 'maroon', fontFamily: 'Helvetica, Arial, sans-serif', }); setSelectedStyle('Yotsuba'); return () => { setSelectedStyle(currentPrevStyle); setBodyStyle(currentPrevBodyStyle); }; }, [setBodyStyle, setSelectedStyle]); return ( <> setIsCreateBoardOpen(false)} /> plebchan
plebchan
{ if (event.key === 'Enter') { event.preventDefault(); const address = inputRef.current.value; if (address) { setSelectedAddress(address); navigate(`/p/${address}`); } } }} /> { const address = inputRef.current.value; if (address) { setSelectedAddress(address); navigate(`/p/${address}`); } }} />

What is plebchan?

Plebchan is the only serverless, adminless, fully decentralized 4chan alternative where you can create unlimited boards and nobody can take them down. Plebchan is a client for{' '} plebbit , a pure P2P protocol and tooling for creating decentralized forum applications. Users don't need to register an account before participating in a community; anyone can post comments, share media links, and{' '} . All the content is just text, and plebchan's speed depends on how many users are{' '} . Search for any board address above, or feel free to click on a popular board below that interests you and jump right in!{' '}


There are no global rules, each board is completely independent and its owner decides how/if it should be moderated.

{account?.subscriptions?.length > 0 ? (

Subscriptions

You have subscribed to {account?.subscriptions?.length} board{account?.subscriptions?.length > 1 ? 's' : null}

  { window.scrollTo(0, 0); }} > [view all]
{account?.subscriptions?.map((subscription, index) => ( { window.scrollTo(0, 0); }} to={`/p/${subscription}`} >
{subscription} 
))}
) : null}

Popular Boards

{defaultSubplebbits.map((subplebbit, index) => (
{subplebbit.title ?? }
{ setSelectedTitle(subplebbit.title); setSelectedAddress(subplebbit.address); window.scrollTo(0, 0); }} >
{subplebbit.address}
))}
plebchan v{version} {commitRef}. GPL-2.0
); }; export default Home;