How to implement and display a dynamic visitor count feature
When I decided to rebuild my website, I wanted to add a visitor count feature to make it feel more interactive and showcase site engagement. In this post, I’ll explain how I added the visitor count feature in my website
The visitor count is displayed on the frontend using React state and a custom fetchVisitorCount
service function. Here’s how it works:
const [visitorCount, setVisitorCount] = useState<number>(0)
const [loading, setLoading] = useState(true)
useEffect(() => {
fetchVisitorCount('profile')
.then(res => {
setVisitorCount(res.visitCount)
})
.finally(() => {
setLoading(false)
})
}, [])
return (
<div className="absolute right-4 mt-4 flex flex-row items-center gap-1">
{loading ? (
<LoadingDots color="bg-customBlue" />
) : (
<span className="text-customBlue font-bold">{visitorCount.toString()}</span>
)}
<span className="mt-[2px] text-sm text-gray-500">Visitor Count</span>
</div>
)
This component leverages a loading state to ensure the visitor count only displays after it has been fetched.
I chose to make the API call from the client component so the visitor count updates in real time without requiring a page refresh. This also allows me to easily handle cookies for tracking returning visitors, ensuring the count is accurate. While fetching the data, a simple "loading" state gives the user some feedback, making the feature feel smooth and interactive.
The fetchVisitorCount
function communicates with a custom API endpoint to retrieve the visitor count:
interface IVisitorCountResponseData {
_id: string
visitCount: number
pageName: string
}
export const fetchVisitorCount = async (pageName: string): Promise<IVisitorCountResponseData> => {
try {
const res = await fetch(`/api/visitor-count?pageName=${pageName}`, {
method: 'GET',
credentials: 'include' // Include cookies in the request
})
if (!res.ok) {
throw new Error('Failed to fetch visitor count')
}
return await res.json()
} catch (error) {
console.error('Error fetching visitor count:', error)
throw new Error('An error occurred while fetching visitor count data.')
}
}
Here’s the logic in the API endpoint:
export const GET = async (request: NextRequest) => {
try {
connectToDb()
const pageName = request.nextUrl.searchParams.get('pageName')
const cookieName = `visited_${pageName}`
const cookies = request.cookies
const hasVisited = cookies.get(cookieName)
const visitorCount = await ProfileVisitorCount.findOne({ pageName })
if (!hasVisited) {
visitorCount.visitCount += 1
await visitorCount.save()
const response = NextResponse.json(visitorCount)
response.cookies.set(cookieName, 'true', {
httpOnly: true,
maxAge: 60 * 60 * 12,
path: '/'
})
return response
} else {
return NextResponse.json(visitorCount)
}
} catch (err) {
console.log(err)
throw new Error('Failed to fetch Visitors count!')
}
}
The MongoDB schema stores visitor count data:
const profileVisitorCount = new mongoose.Schema(
{
visitCount: Number,
pageName: String
},
{ timestamps: true }
)
export const ProfileVisitorCount =
mongoose.models?.ProfileVisitorCount || mongoose.model('ProfileVisitorCount', profileVisitorCount)
By combining frontend and backend techniques with a robust database integration, we’ve created a reliable visitor count feature for your website. This feature not only provides valuable insights but also enhances user engagement by showcasing site activity.
Feel free to customize the code snippets to suit your project’s unique needs!