import React, { useState, useEffect } from 'react'; import Papa from 'papaparse'; import _ from 'lodash'; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts'; const KeywordAnalysis = () => { const [data, setData] = useState([]); const [topUrls, setTopUrls] = useState([]); const [topThemes, setTopThemes] = useState([]); const [activeTab, setActiveTab] = useState('top-urls'); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchData = async () => { try { const response = await window.fs.readFile('Untitled spreadsheet Sheet1 6.csv', { encoding: 'utf8' }); Papa.parse(response, { header: true, dynamicTyping: true, skipEmptyLines: true, complete: (results) => { // Filter out rows with missing URLs or keywords const validData = results.data.filter(row => row.URL && row.Keyword); setData(validData); // Process the data processData(validData); setIsLoading(false); }, error: (error) => { console.error('Error parsing CSV:', error); setIsLoading(false); } }); } catch (error) { console.error('Error reading file:', error); setIsLoading(false); } }; fetchData(); }, []); const processData = (validData) => { // Group by URL const keywordsByURL = _.groupBy(validData, 'URL'); // Extract topics from URLs const urlTopicsAndKeywords = Object.keys(keywordsByURL).map(url => { const keywords = keywordsByURL[url]; const topic = extractTopicFromURL(url); // Sort keywords by search volume const sortedKeywords = _.sortBy(keywords, k => -(k['Search Volume'] || 0)); // Calculate total traffic for this URL const totalTraffic = _.sumBy(keywords, 'Traffic') || 0; // Calculate average position const avgPosition = _.meanBy(keywords, 'Position') || 0; return { url, topic, totalTraffic, avgPosition: avgPosition.toFixed(1), keywordCount: keywords.length, topKeywords: sortedKeywords.slice(0, 5).map(k => ({ keyword: k.Keyword, volume: k['Search Volume'] || 0, position: k.Position || 0, traffic: k.Traffic || 0 })) }; }); // Sort by total traffic const sortedURLsAndTopics = _.sortBy(urlTopicsAndKeywords, item => -item.totalTraffic); setTopUrls(sortedURLsAndTopics.slice(0, 15)); // Extract common themes const topicWords = {}; sortedURLsAndTopics.slice(0, 30).forEach(item => { const words = item.topic.toLowerCase().split(' '); words.forEach(word => { if (word.length > 3 && !['with', 'your', 'what', 'from', 'have', 'this', 'that', 'does'].includes(word)) { if (!topicWords[word]) { topicWords[word] = { count: 0, totalTraffic: 0, urls: [] }; } topicWords[word].count++; topicWords[word].totalTraffic += item.totalTraffic; if (!topicWords[word].urls.includes(item.url)) { topicWords[word].urls.push(item.url); } } }); }); // Sort themes by traffic const sortedThemes = Object.entries(topicWords) .filter(([_, data]) => data.count >= 2) .sort((a, b) => b[1].totalTraffic - a[1].totalTraffic) .map(([theme, data]) => ({ theme, count: data.count, traffic: data.totalTraffic, urlCount: data.urls.length })); setTopThemes(sortedThemes.slice(0, 15)); }; const extractTopicFromURL = (url) => { try { const urlObj = new URL(url); const pathSegments = urlObj.pathname.split('/').filter(Boolean); const lastSegment = pathSegments[pathSegments.length - 1]; const cleanTitle = lastSegment .replace(/^\d+-/, '') .replace(/-/g, ' '); return cleanTitle; } catch (e) { return "Unknown topic"; } }; // Colors for charts const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', '#8884D8', '#82ca9d', '#ffc658', '#8dd1e1']; if (isLoading) { return (
Analysis of 832 keywords across {_.uniqBy(data, 'URL').length} unique URLs to identify content patterns
| Topic | Traffic | Avg. Position | Top Keywords |
|---|---|---|---|
| {item.topic} | {item.totalTraffic} | {item.avgPosition} |
{item.topKeywords.map((kw, i) => (
{kw.keyword} (vol: {kw.volume}, pos: {kw.position})
))}
|
| Theme | Traffic | Occurrence Count | URL Count |
|---|---|---|---|
| {theme.theme} | {theme.traffic} | {theme.count} | {theme.urlCount} |
Use these insights to guide content creation for klodubean.com by focusing on high-traffic themes and keyword patterns.