[{"data":1,"prerenderedAt":14310},["ShallowReactive",2],{"blog-posts-all":3},[4,873,3685,6702,9223,9948,13728],{"id":5,"title":6,"author":7,"body":8,"date":860,"description":861,"draft":862,"extension":863,"image":864,"meta":865,"navigation":866,"path":867,"seo":868,"sitemap":869,"stem":870,"tags":871,"__hash__":872},"blog\u002Fblog\u002Fintroducing-allnewsapi-mcp-server.md","Introducing AllNewsAPI MCP Server","AllNewsAPI Team",{"type":9,"value":10,"toc":828},"minimark",[11,20,25,28,31,47,51,54,86,89,93,98,101,133,137,140,144,147,151,162,166,169,173,190,194,197,305,308,312,317,331,336,341,346,354,359,364,368,371,376,384,389,395,400,406,411,417,422,428,431,435,439,444,450,455,461,465,468,474,478,481,487,490,494,497,503,507,510,536,540,543,548,559,564,575,579,585,591,597,603,607,633,637,644,682,688,692,716,720,763,767,770,776,780,783,788,804,807,810,824],[12,13,14,15,19],"p",{},"We're excited to announce the launch of the ",[16,17,18],"strong",{},"AllNewsAPI MCP Server"," – a Model Context Protocol integration that brings real-time news data directly to your AI assistants and development tools.",[21,22,24],"h2",{"id":23},"what-is-mcp","What is MCP?",[12,26,27],{},"The Model Context Protocol (MCP) is an open standard that enables AI assistants to securely connect to external data sources and tools. Think of it as a universal adapter that lets your AI assistant access real-world information beyond its training data.",[12,29,30],{},"With MCP, your AI can:",[32,33,34,38,41,44],"ul",{},[35,36,37],"li",{},"Access real-time data from APIs",[35,39,40],{},"Execute tools and functions",[35,42,43],{},"Retrieve context-specific information",[35,45,46],{},"Provide more accurate, up-to-date responses",[21,48,50],{"id":49},"why-we-built-this","Why We Built This",[12,52,53],{},"Developers using AI assistants like Claude, Cursor, and VS Code Copilot often need access to current news data for:",[32,55,56,62,68,74,80],{},[35,57,58,61],{},[16,59,60],{},"Research and analysis"," - Understanding current events and trends",[35,63,64,67],{},[16,65,66],{},"Content creation"," - Writing articles with up-to-date information",[35,69,70,73],{},[16,71,72],{},"Market intelligence"," - Tracking industry news and competitor activity",[35,75,76,79],{},[16,77,78],{},"Application development"," - Building news-powered features with AI assistance",[35,81,82,85],{},[16,83,84],{},"Data journalism"," - Analyzing news patterns and sentiment",[12,87,88],{},"Previously, you'd need to manually search for news, copy-paste articles, or write custom integrations. Now, your AI assistant can access AllNewsAPI directly through natural language queries.",[21,90,92],{"id":91},"key-features","Key Features",[94,95,97],"h3",{"id":96},"comprehensive-news-search","Comprehensive News Search",[12,99,100],{},"Access news articles with advanced filtering:",[32,102,103,109,115,121,127],{},[35,104,105,108],{},[16,106,107],{},"Date ranges"," - From the last hour to 10 years of historical data",[35,110,111,114],{},[16,112,113],{},"Languages"," - 22 languages including English, Spanish, Chinese, Arabic, and more",[35,116,117,120],{},[16,118,119],{},"Countries"," - 244 countries worldwide",[35,122,123,126],{},[16,124,125],{},"Categories"," - Technology, business, sports, entertainment, health, science, and more",[35,128,129,132],{},[16,130,131],{},"Keywords"," - Search for specific topics, companies, or events",[94,134,136],{"id":135},"real-time-headlines","Real-Time Headlines",[12,138,139],{},"Get the latest breaking news and top headlines with customizable parameters. Perfect for staying informed about rapidly developing stories.",[94,141,143],{"id":142},"llm-optimized-responses","LLM-Optimized Responses",[12,145,146],{},"Clean, formatted output designed specifically for AI consumption. The server handles all the complexity of API calls, parameter validation, and response formatting.",[94,148,150],{"id":149},"robust-error-handling","Robust Error Handling",[32,152,153,156,159],{},[35,154,155],{},"Parameter validation against official supported values",[35,157,158],{},"Graceful handling of network issues",[35,160,161],{},"Proper rate limit management",[21,163,165],{"id":164},"getting-started","Getting Started",[12,167,168],{},"Setting up the AllNewsAPI MCP server takes just a few minutes.",[94,170,172],{"id":171},"prerequisites","Prerequisites",[32,174,175,178,187],{},[35,176,177],{},"Node.js 18 or newer",[35,179,180,181,186],{},"An AllNewsAPI key (",[182,183,185],"a",{"href":184},"\u002Fsignup","get one free at allnewsapi.com",")",[35,188,189],{},"An MCP-compatible client (Claude Desktop, Cursor, VS Code, Windsurf, etc.)",[94,191,193],{"id":192},"installation","Installation",[12,195,196],{},"Add this configuration to your MCP client settings:",[198,199,204],"pre",{"className":200,"code":201,"language":202,"meta":203,"style":203},"language-json shiki shiki-themes github-light github-dark","{\n  \"mcpServers\": {\n    \"allnewsapi\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"allnewsapi-mcp@latest\",\n        \"--apikey\",\n        \"YOUR_API_KEY_HERE\"\n      ]\n    }\n  }\n}\n","json","",[205,206,207,216,226,234,250,259,267,275,281,287,293,299],"code",{"__ignoreMap":203},[208,209,212],"span",{"class":210,"line":211},"line",1,[208,213,215],{"class":214},"sVt8B","{\n",[208,217,219,223],{"class":210,"line":218},2,[208,220,222],{"class":221},"sj4cs","  \"mcpServers\"",[208,224,225],{"class":214},": {\n",[208,227,229,232],{"class":210,"line":228},3,[208,230,231],{"class":221},"    \"allnewsapi\"",[208,233,225],{"class":214},[208,235,237,240,243,247],{"class":210,"line":236},4,[208,238,239],{"class":221},"      \"command\"",[208,241,242],{"class":214},": ",[208,244,246],{"class":245},"sZZnC","\"npx\"",[208,248,249],{"class":214},",\n",[208,251,253,256],{"class":210,"line":252},5,[208,254,255],{"class":221},"      \"args\"",[208,257,258],{"class":214},": [\n",[208,260,262,265],{"class":210,"line":261},6,[208,263,264],{"class":245},"        \"allnewsapi-mcp@latest\"",[208,266,249],{"class":214},[208,268,270,273],{"class":210,"line":269},7,[208,271,272],{"class":245},"        \"--apikey\"",[208,274,249],{"class":214},[208,276,278],{"class":210,"line":277},8,[208,279,280],{"class":245},"        \"YOUR_API_KEY_HERE\"\n",[208,282,284],{"class":210,"line":283},9,[208,285,286],{"class":214},"      ]\n",[208,288,290],{"class":210,"line":289},10,[208,291,292],{"class":214},"    }\n",[208,294,296],{"class":210,"line":295},11,[208,297,298],{"class":214},"  }\n",[208,300,302],{"class":210,"line":301},12,[208,303,304],{"class":214},"}\n",[12,306,307],{},"That's it! No installation, no build steps – just add the config and start using it.",[94,309,311],{"id":310},"configuration-locations","Configuration Locations",[12,313,314],{},[16,315,316],{},"Claude Desktop:",[32,318,319,325],{},[35,320,321,322],{},"macOS: ",[205,323,324],{},"~\u002FLibrary\u002FApplication Support\u002FClaude\u002Fclaude_desktop_config.json",[35,326,327,328],{},"Windows: ",[205,329,330],{},"%APPDATA%\\Claude\\claude_desktop_config.json",[12,332,333],{},[16,334,335],{},"Cursor:",[32,337,338],{},[35,339,340],{},"Settings → MCP Servers → Add Server",[12,342,343],{},[16,344,345],{},"VS Code:",[32,347,348],{},[35,349,350,353],{},[205,351,352],{},".vscode\u002Fmcp.json"," in your workspace",[12,355,356],{},[16,357,358],{},"Windsurf:",[32,360,361],{},[35,362,363],{},"Settings → Extensions → MCP Configuration",[21,365,367],{"id":366},"example-usage","Example Usage",[12,369,370],{},"Once configured, you can ask your AI assistant natural language questions like:",[12,372,373],{},[16,374,375],{},"Technology News:",[198,377,382],{"className":378,"code":380,"language":381},[379],"language-text","\"Get me the latest technology news from the US\"\n","text",[205,383,380],{"__ignoreMap":203},[12,385,386],{},[16,387,388],{},"Climate Coverage:",[198,390,393],{"className":391,"code":392,"language":381},[379],"\"Find news articles about climate change from European sources\"\n",[205,394,392],{"__ignoreMap":203},[12,396,397],{},[16,398,399],{},"Business Headlines:",[198,401,404],{"className":402,"code":403,"language":381},[379],"\"Show me top business headlines from the past week\"\n",[205,405,403],{"__ignoreMap":203},[12,407,408],{},[16,409,410],{},"Cryptocurrency Updates:",[198,412,415],{"className":413,"code":414,"language":381},[379],"\"Search for cryptocurrency news in English from the last month\"\n",[205,416,414],{"__ignoreMap":203},[12,418,419],{},[16,420,421],{},"Sports from Multiple Countries:",[198,423,426],{"className":424,"code":425,"language":381},[379],"\"Get sports headlines from Canada and Australia\"\n",[205,427,425],{"__ignoreMap":203},[12,429,430],{},"The AI assistant will use the MCP server to fetch relevant articles and provide you with formatted, up-to-date information.",[21,432,434],{"id":433},"real-world-use-cases","Real-World Use Cases",[94,436,438],{"id":437},"_1-content-research","1. Content Research",[12,440,441],{},[16,442,443],{},"Before:",[198,445,448],{"className":446,"code":447,"language":381},[379],"You: \"I need to write an article about AI regulation\"\nAI: \"Based on my training data from 2023...\"\n",[205,449,447],{"__ignoreMap":203},[12,451,452],{},[16,453,454],{},"After:",[198,456,459],{"className":457,"code":458,"language":381},[379],"You: \"Find recent news about AI regulation in the EU\"\nAI: *Uses MCP to fetch latest articles*\n\"Here are the most recent developments in EU AI regulation:\n1. New AI Act provisions announced last week...\n2. Tech companies respond to compliance requirements...\n[with actual current data]\"\n",[205,460,458],{"__ignoreMap":203},[94,462,464],{"id":463},"_2-market-intelligence","2. Market Intelligence",[12,466,467],{},"Track competitor news, industry trends, and market movements in real-time:",[198,469,472],{"className":470,"code":471,"language":381},[379],"\"Monitor news about electric vehicle manufacturers in the past 24 hours\"\n",[205,473,471],{"__ignoreMap":203},[94,475,477],{"id":476},"_3-development-assistance","3. Development Assistance",[12,479,480],{},"Build news-powered features with AI help:",[198,482,485],{"className":483,"code":484,"language":381},[379],"\"Help me write a function that fetches technology news \nfrom Asian countries and filters by sentiment\"\n",[205,486,484],{"__ignoreMap":203},[12,488,489],{},"The AI can now access real data to provide working code examples.",[94,491,493],{"id":492},"_4-research-and-analysis","4. Research and Analysis",[12,495,496],{},"Analyze news patterns and trends:",[198,498,501],{"className":499,"code":500,"language":381},[379],"\"Compare coverage of renewable energy across US, \nEuropean, and Asian news sources this month\"\n",[205,502,500],{"__ignoreMap":203},[21,504,506],{"id":505},"technical-details","Technical Details",[12,508,509],{},"The AllNewsAPI MCP server is built with:",[32,511,512,518,524,530],{},[35,513,514,517],{},[16,515,516],{},"TypeScript"," - Type-safe implementation",[35,519,520,523],{},[16,521,522],{},"Model Context Protocol SDK"," - Official MCP implementation",[35,525,526,529],{},[16,527,528],{},"ES Modules"," - Modern JavaScript with top-level await",[35,531,532,535],{},[16,533,534],{},"Comprehensive validation"," - All parameters validated against official API specs",[94,537,539],{"id":538},"available-tools","Available Tools",[12,541,542],{},"The server exposes two main tools:",[12,544,545],{},[16,546,547],{},"1. search_news",[32,549,550,553,556],{},[35,551,552],{},"Search for news articles with advanced filtering",[35,554,555],{},"Parameters: query, language, country, category, date ranges, and more",[35,557,558],{},"Returns: Formatted list of articles with titles, descriptions, URLs, and metadata",[12,560,561],{},[16,562,563],{},"2. get_headlines",[32,565,566,569,572],{},[35,567,568],{},"Get top headlines from specific countries or categories",[35,570,571],{},"Parameters: country, category, language",[35,573,574],{},"Returns: Latest breaking news and top stories",[94,576,578],{"id":577},"supported-parameters","Supported Parameters",[12,580,581,584],{},[16,582,583],{},"Languages:"," Arabic, Chinese, Dutch, English, French, German, Greek, Hebrew, Hindi, Italian, Japanese, Korean, Norwegian, Polish, Portuguese, Romanian, Russian, Spanish, Swedish, Turkish, Ukrainian, Vietnamese (22 languages total)",[12,586,587,590],{},[16,588,589],{},"Categories:"," General, Technology, Business, Sports, Entertainment, Health, Science",[12,592,593,596],{},[16,594,595],{},"Countries:"," 244 countries including US, UK, Canada, Australia, Germany, France, Japan, India, Brazil, and more",[12,598,599,602],{},[16,600,601],{},"Regions:"," North America, Europe, Asia, Middle East, Africa, Latin America, Oceania",[21,604,606],{"id":605},"security-and-privacy","Security and Privacy",[32,608,609,615,621,627],{},[35,610,611,614],{},[16,612,613],{},"API keys are never exposed"," - Keys are configured locally and never sent to third parties",[35,616,617,620],{},[16,618,619],{},"Direct API communication"," - The MCP server communicates directly with AllNewsAPI",[35,622,623,626],{},[16,624,625],{},"No data storage"," - No caching or storage of your queries or results",[35,628,629,632],{},[16,630,631],{},"Rate limit compliance"," - Respects your API plan limits",[21,634,636],{"id":635},"pricing","Pricing",[12,638,639,640,643],{},"The MCP server itself is ",[16,641,642],{},"completely free and open source",". You only pay for your AllNewsAPI usage:",[32,645,646,652,658,664,670,676],{},[35,647,648,651],{},[16,649,650],{},"Free Plan"," - 20 requests\u002Fday (perfect for testing)",[35,653,654,657],{},[16,655,656],{},"Starter Plan"," - 5,000 requests\u002Fday at $20\u002Fmonth",[35,659,660,663],{},[16,661,662],{},"Pro Plan"," - 25,000 requests\u002Fday at $80\u002Fmonth",[35,665,666,669],{},[16,667,668],{},"Business Plan"," - 50,000 requests\u002Fday at $200\u002Fmonth",[35,671,672,675],{},[16,673,674],{},"Enterprise Plan"," - 200,000 requests\u002Fday at $500\u002Fmonth",[35,677,678,681],{},[16,679,680],{},"Custom Plans"," - For projects with custom requirements",[12,683,684],{},[182,685,687],{"href":686},"\u002Fpricing","View full pricing details",[21,689,691],{"id":690},"get-started-today","Get Started Today",[693,694,695,704,710],"ol",{},[35,696,697,700,701],{},[16,698,699],{},"Get your API key"," - ",[182,702,703],{"href":184},"Sign up for free",[35,705,706,709],{},[16,707,708],{},"Install the MCP server"," - Add the config to your AI assistant",[35,711,712,715],{},[16,713,714],{},"Start querying"," - Ask for news in natural language",[21,717,719],{"id":718},"resources","Resources",[32,721,722,734,743,753],{},[35,723,724,727,728],{},[16,725,726],{},"GitHub Repository:"," ",[182,729,733],{"href":730,"rel":731},"https:\u002F\u002Fgithub.com\u002FAllNewsAPI\u002Fmcp-server",[732],"nofollow","github.com\u002FAllNewsAPI\u002Fmcp-server",[35,735,736,727,739],{},[16,737,738],{},"API Documentation:",[182,740,742],{"href":741},"\u002Fdocs","allnewsapi.com\u002Fdocs",[35,744,745,727,748],{},[16,746,747],{},"MCP Protocol:",[182,749,752],{"href":750,"rel":751},"https:\u002F\u002Fmodelcontextprotocol.io",[732],"modelcontextprotocol.io",[35,754,755,758,759],{},[16,756,757],{},"Support:"," Contact us at ",[182,760,762],{"href":761},"mailto:support@allnewsapi.com","support@allnewsapi.com",[21,764,766],{"id":765},"example-building-a-news-briefing-bot","Example: Building a News Briefing Bot",[12,768,769],{},"Here's a quick example of what you can build with the MCP server:",[198,771,774],{"className":772,"code":773,"language":381},[379],"You: \"Create a morning briefing with top headlines from \ntechnology, business, and world news\"\n\nAI: *Uses MCP to fetch from multiple categories*\n\n\"Good morning! Here's your briefing for December 8, 2024:\n\n📱 TECHNOLOGY\n- Major AI breakthrough announced by research team\n- New smartphone features revealed at tech conference\n- Cybersecurity alert issued for popular software\n\n💼 BUSINESS  \n- Stock markets react to economic data\n- Tech giant announces quarterly earnings\n- Merger talks confirmed between industry leaders\n\n🌍 WORLD NEWS\n- International summit concludes with new agreements\n- Climate initiative gains momentum\n- Breaking: Major development in ongoing situation\n\nWould you like more details on any of these stories?\"\n",[205,775,773],{"__ignoreMap":203},[21,777,779],{"id":778},"conclusion","Conclusion",[12,781,782],{},"The AllNewsAPI MCP Server bridges the gap between AI assistants and real-time news data. Whether you're a developer building news-powered applications, a researcher analyzing current events, or a content creator staying informed, the MCP server makes accessing news data as simple as asking a question.",[12,784,785],{},[16,786,787],{},"Get started today:",[693,789,790,795,801],{},[35,791,792],{},[182,793,794],{"href":184},"Sign up for AllNewsAPI",[35,796,797,798],{},"Install the MCP server with ",[205,799,800],{},"npx allnewsapi-mcp@latest",[35,802,803],{},"Start asking your AI assistant about current events",[12,805,806],{},"We can't wait to see what you build!",[808,809],"hr",{},[12,811,812],{},[813,814,815,816,818,819,823],"em",{},"Have questions or feedback? Reach out to us at ",[182,817,762],{"href":761}," or open an issue on ",[182,820,822],{"href":730,"rel":821},[732],"GitHub",".",[825,826,827],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":203,"searchDepth":218,"depth":218,"links":829},[830,831,832,838,843,844,850,854,855,856,857,858,859],{"id":23,"depth":218,"text":24},{"id":49,"depth":218,"text":50},{"id":91,"depth":218,"text":92,"children":833},[834,835,836,837],{"id":96,"depth":228,"text":97},{"id":135,"depth":228,"text":136},{"id":142,"depth":228,"text":143},{"id":149,"depth":228,"text":150},{"id":164,"depth":218,"text":165,"children":839},[840,841,842],{"id":171,"depth":228,"text":172},{"id":192,"depth":228,"text":193},{"id":310,"depth":228,"text":311},{"id":366,"depth":218,"text":367},{"id":433,"depth":218,"text":434,"children":845},[846,847,848,849],{"id":437,"depth":228,"text":438},{"id":463,"depth":228,"text":464},{"id":476,"depth":228,"text":477},{"id":492,"depth":228,"text":493},{"id":505,"depth":218,"text":506,"children":851},[852,853],{"id":538,"depth":228,"text":539},{"id":577,"depth":228,"text":578},{"id":605,"depth":218,"text":606},{"id":635,"depth":218,"text":636},{"id":690,"depth":218,"text":691},{"id":718,"depth":218,"text":719},{"id":765,"depth":218,"text":766},{"id":778,"depth":218,"text":779},"2025-12-08","Connect your AI assistant to real-time news data with our new Model Context Protocol server",false,"md","\u002Fblog\u002Fintroducing-allnewsapi-mcp-server.webp",{},true,"\u002Fblog\u002Fintroducing-allnewsapi-mcp-server",{"title":6,"description":861},{"loc":867},"blog\u002Fintroducing-allnewsapi-mcp-server","announcement","ACfNs01Ysur9emrMjQ3WbhbFOnYprQ4dHvqjXc4Nx1M",{"id":874,"title":875,"author":7,"body":876,"date":3675,"description":3676,"draft":862,"extension":863,"image":3677,"meta":3678,"navigation":866,"path":3679,"seo":3680,"sitemap":3681,"stem":3682,"tags":3683,"__hash__":3684},"blog\u002Fblog\u002Fmulti-language-news-apps.md","Building Multi-Language News Applications",{"type":9,"value":877,"toc":3658},[878,881,885,888,902,906,909,977,981,984,1004,1008,1011,1099,1103,1106,1172,1176,1179,1950,1954,1961,1982,1985,2262,2265,2656,2660,2663,2806,2809,2839,2843,2846,2923,2927,2930,3222,3226,3229,3418,3422,3466,3470,3473,3621,3623,3626,3633,3635,3655],[12,879,880],{},"Serving news content in multiple languages isn't just nice to have—it's essential. This guide will show you how to build a truly international news application using AllNewsAPI.",[21,882,884],{"id":883},"why-multi-language-matters","Why Multi-Language Matters",[12,886,887],{},"Consider these statistics:",[32,889,890,893,896,899],{},[35,891,892],{},"Only 25% of internet users speak English as their first language",[35,894,895],{},"75% of consumers prefer to buy products in their native language",[35,897,898],{},"Multi-language apps see 2-3x higher engagement rates",[35,900,901],{},"Global reach opens up new markets and audiences",[21,903,905],{"id":904},"allnewsapi-language-support","AllNewsAPI Language Support",[12,907,908],{},"AllNewsAPI supports news in 22 languages across 244 countries:",[32,910,911,914,917,920,923,926,929,932,935,938,941,944,947,950,953,956,959,962,965,968,971,974],{},[35,912,913],{},"Arabic (ar)",[35,915,916],{},"Chinese (zh)",[35,918,919],{},"Dutch (nl)",[35,921,922],{},"English (en)",[35,924,925],{},"French (fr)",[35,927,928],{},"German (de)",[35,930,931],{},"Greek (el)",[35,933,934],{},"Hebrew (he)",[35,936,937],{},"Hindi (hi)",[35,939,940],{},"Italian (it)",[35,942,943],{},"Japanese (ja)",[35,945,946],{},"Korean (ko)",[35,948,949],{},"Norwegian (no)",[35,951,952],{},"Polish (pl)",[35,954,955],{},"Portuguese (pt)",[35,957,958],{},"Romanian (ro)",[35,960,961],{},"Russian (ru)",[35,963,964],{},"Spanish (es)",[35,966,967],{},"Swedish (sv)",[35,969,970],{},"Turkish (tr)",[35,972,973],{},"Ukrainian (uk)",[35,975,976],{},"Vietnamese (vi)",[21,978,980],{"id":979},"architecture-overview","Architecture Overview",[12,982,983],{},"A well-designed multi-language news app has three key components:",[693,985,986,992,998],{},[35,987,988,991],{},[16,989,990],{},"Content Layer",": News articles in various languages",[35,993,994,997],{},[16,995,996],{},"UI Layer",": Interface text and labels",[35,999,1000,1003],{},[16,1001,1002],{},"User Preferences",": Language selection and persistence",[21,1005,1007],{"id":1006},"step-1-setting-up-language-detection","Step 1: Setting Up Language Detection",[12,1009,1010],{},"First, detect the user's preferred language:",[198,1012,1016],{"className":1013,"code":1014,"language":1015,"meta":203,"style":203},"language-javascript shiki shiki-themes github-light github-dark","function detectUserLanguage() {\n  \u002F\u002F Check localStorage for saved preference\n  const saved = localStorage.getItem('preferredLanguage');\n  if (saved) return saved;\n  \n  \u002F\u002F Check browser language\n  const browserLang = navigator.language.split('-')[0];\n  \n  \u002F\u002F Supported languages\n  const supported = ['ar', 'zh', 'nl', 'en', 'fr', 'de', 'el', 'he', 'hi', 'it', 'ja', 'ko', 'no', 'pl', 'pt', 'ro', 'ru', 'es', 'sv', 'tr', 'uk', 'vi'];\n  \n  \u002F\u002F Return browser language if supported, otherwise default to English\n  return supported.includes(browserLang) ? browserLang : 'en';\n}\n\nconst userLanguage = detectUserLanguage();\n","javascript",[205,1017,1018,1023,1028,1033,1038,1043,1048,1053,1057,1062,1067,1071,1076,1082,1087,1093],{"__ignoreMap":203},[208,1019,1020],{"class":210,"line":211},[208,1021,1022],{},"function detectUserLanguage() {\n",[208,1024,1025],{"class":210,"line":218},[208,1026,1027],{},"  \u002F\u002F Check localStorage for saved preference\n",[208,1029,1030],{"class":210,"line":228},[208,1031,1032],{},"  const saved = localStorage.getItem('preferredLanguage');\n",[208,1034,1035],{"class":210,"line":236},[208,1036,1037],{},"  if (saved) return saved;\n",[208,1039,1040],{"class":210,"line":252},[208,1041,1042],{},"  \n",[208,1044,1045],{"class":210,"line":261},[208,1046,1047],{},"  \u002F\u002F Check browser language\n",[208,1049,1050],{"class":210,"line":269},[208,1051,1052],{},"  const browserLang = navigator.language.split('-')[0];\n",[208,1054,1055],{"class":210,"line":277},[208,1056,1042],{},[208,1058,1059],{"class":210,"line":283},[208,1060,1061],{},"  \u002F\u002F Supported languages\n",[208,1063,1064],{"class":210,"line":289},[208,1065,1066],{},"  const supported = ['ar', 'zh', 'nl', 'en', 'fr', 'de', 'el', 'he', 'hi', 'it', 'ja', 'ko', 'no', 'pl', 'pt', 'ro', 'ru', 'es', 'sv', 'tr', 'uk', 'vi'];\n",[208,1068,1069],{"class":210,"line":295},[208,1070,1042],{},[208,1072,1073],{"class":210,"line":301},[208,1074,1075],{},"  \u002F\u002F Return browser language if supported, otherwise default to English\n",[208,1077,1079],{"class":210,"line":1078},13,[208,1080,1081],{},"  return supported.includes(browserLang) ? browserLang : 'en';\n",[208,1083,1085],{"class":210,"line":1084},14,[208,1086,304],{},[208,1088,1090],{"class":210,"line":1089},15,[208,1091,1092],{"emptyLinePlaceholder":866},"\n",[208,1094,1096],{"class":210,"line":1095},16,[208,1097,1098],{},"const userLanguage = detectUserLanguage();\n",[21,1100,1102],{"id":1101},"step-2-fetching-language-specific-news","Step 2: Fetching Language-Specific News",[12,1104,1105],{},"Use AllNewsAPI to fetch news in the user's language:",[198,1107,1109],{"className":1013,"code":1108,"language":1015,"meta":203,"style":203},"async function getNewsInLanguage(language, country) {\n  const response = await fetch(\n    `https:\u002F\u002Fapi.allnewsapi.com\u002Fheadlines?apikey=${API_KEY}&lang=${language}&country=${country}`\n  );\n  \n  return await response.json();\n}\n\n\u002F\u002F Example: Get Spanish news from Spain\nconst spanishNews = await getNewsInLanguage('es', 'es');\n\n\u002F\u002F Example: Get French news from France\nconst frenchNews = await getNewsInLanguage('fr', 'fr');\n",[205,1110,1111,1116,1121,1126,1131,1135,1140,1144,1148,1153,1158,1162,1167],{"__ignoreMap":203},[208,1112,1113],{"class":210,"line":211},[208,1114,1115],{},"async function getNewsInLanguage(language, country) {\n",[208,1117,1118],{"class":210,"line":218},[208,1119,1120],{},"  const response = await fetch(\n",[208,1122,1123],{"class":210,"line":228},[208,1124,1125],{},"    `https:\u002F\u002Fapi.allnewsapi.com\u002Fheadlines?apikey=${API_KEY}&lang=${language}&country=${country}`\n",[208,1127,1128],{"class":210,"line":236},[208,1129,1130],{},"  );\n",[208,1132,1133],{"class":210,"line":252},[208,1134,1042],{},[208,1136,1137],{"class":210,"line":261},[208,1138,1139],{},"  return await response.json();\n",[208,1141,1142],{"class":210,"line":269},[208,1143,304],{},[208,1145,1146],{"class":210,"line":277},[208,1147,1092],{"emptyLinePlaceholder":866},[208,1149,1150],{"class":210,"line":283},[208,1151,1152],{},"\u002F\u002F Example: Get Spanish news from Spain\n",[208,1154,1155],{"class":210,"line":289},[208,1156,1157],{},"const spanishNews = await getNewsInLanguage('es', 'es');\n",[208,1159,1160],{"class":210,"line":295},[208,1161,1092],{"emptyLinePlaceholder":866},[208,1163,1164],{"class":210,"line":301},[208,1165,1166],{},"\u002F\u002F Example: Get French news from France\n",[208,1168,1169],{"class":210,"line":1078},[208,1170,1171],{},"const frenchNews = await getNewsInLanguage('fr', 'fr');\n",[21,1173,1175],{"id":1174},"step-3-implementing-language-switching","Step 3: Implementing Language Switching",[12,1177,1178],{},"Create a language selector component:",[198,1180,1184],{"className":1181,"code":1182,"language":1183,"meta":203,"style":203},"language-jsx shiki shiki-themes github-light github-dark","import { useState, useEffect } from 'react';\n\nfunction LanguageSelector({ currentLanguage, onLanguageChange }) {\n  const languages = [\n    { code: 'en', name: 'English', flag: '🇬🇧' },\n    { code: 'es', name: 'Español', flag: '🇪🇸' },\n    { code: 'fr', name: 'Français', flag: '🇫🇷' },\n    { code: 'de', name: 'Deutsch', flag: '🇩🇪' },\n    { code: 'it', name: 'Italiano', flag: '🇮🇹' },\n    { code: 'pt', name: 'Português', flag: '🇵🇹' },\n    { code: 'ru', name: 'Русский', flag: '🇷🇺' },\n    { code: 'ar', name: 'العربية', flag: '🇸🇦' },\n    { code: 'zh', name: '中文', flag: '🇨🇳' },\n    { code: 'ja', name: '日本語', flag: '🇯🇵' },\n    { code: 'ko', name: '한국어', flag: '🇰🇷' },\n    { code: 'hi', name: 'हिन्दी', flag: '🇮🇳' },\n    { code: 'nl', name: 'Nederlands', flag: '🇳🇱' },\n    { code: 'sv', name: 'Svenska', flag: '🇸🇪' },\n    { code: 'no', name: 'Norsk', flag: '🇳🇴' },\n    { code: 'el', name: 'Ελληνικά', flag: '🇬🇷' },\n    { code: 'he', name: 'עברית', flag: '🇮🇱' },\n    { code: 'pl', name: 'Polski', flag: '🇵🇱' },\n    { code: 'ro', name: 'Română', flag: '🇷🇴' },\n    { code: 'tr', name: 'Türkçe', flag: '🇹🇷' },\n    { code: 'uk', name: 'Українська', flag: '🇺🇦' },\n    { code: 'vi', name: 'Tiếng Việt', flag: '🇻🇳' }\n  ];\n\n  const handleChange = (langCode) => {\n    localStorage.setItem('preferredLanguage', langCode);\n    onLanguageChange(langCode);\n  };\n\n  return (\n    \u003Cdiv className=\"language-selector\">\n      \u003Cselect \n        value={currentLanguage} \n        onChange={(e) => handleChange(e.target.value)}\n      >\n        {languages.map(lang => (\n          \u003Coption key={lang.code} value={lang.code}>\n            {lang.flag} {lang.name}\n          \u003C\u002Foption>\n        ))}\n      \u003C\u002Fselect>\n    \u003C\u002Fdiv>\n  );\n}\n\nexport default LanguageSelector;\n","jsx",[205,1185,1186,1204,1208,1233,1247,1270,1289,1308,1327,1346,1365,1384,1403,1422,1441,1460,1479,1499,1519,1539,1559,1579,1599,1619,1639,1659,1680,1686,1691,1716,1734,1743,1749,1754,1763,1785,1797,1808,1831,1837,1856,1881,1887,1897,1903,1913,1923,1928,1933,1938],{"__ignoreMap":203},[208,1187,1188,1192,1195,1198,1201],{"class":210,"line":211},[208,1189,1191],{"class":1190},"szBVR","import",[208,1193,1194],{"class":214}," { useState, useEffect } ",[208,1196,1197],{"class":1190},"from",[208,1199,1200],{"class":245}," 'react'",[208,1202,1203],{"class":214},";\n",[208,1205,1206],{"class":210,"line":218},[208,1207,1092],{"emptyLinePlaceholder":866},[208,1209,1210,1213,1217,1220,1224,1227,1230],{"class":210,"line":228},[208,1211,1212],{"class":1190},"function",[208,1214,1216],{"class":1215},"sScJk"," LanguageSelector",[208,1218,1219],{"class":214},"({ ",[208,1221,1223],{"class":1222},"s4XuR","currentLanguage",[208,1225,1226],{"class":214},", ",[208,1228,1229],{"class":1222},"onLanguageChange",[208,1231,1232],{"class":214}," }) {\n",[208,1234,1235,1238,1241,1244],{"class":210,"line":236},[208,1236,1237],{"class":1190},"  const",[208,1239,1240],{"class":221}," languages",[208,1242,1243],{"class":1190}," =",[208,1245,1246],{"class":214}," [\n",[208,1248,1249,1252,1255,1258,1261,1264,1267],{"class":210,"line":252},[208,1250,1251],{"class":214},"    { code: ",[208,1253,1254],{"class":245},"'en'",[208,1256,1257],{"class":214},", name: ",[208,1259,1260],{"class":245},"'English'",[208,1262,1263],{"class":214},", flag: ",[208,1265,1266],{"class":245},"'🇬🇧'",[208,1268,1269],{"class":214}," },\n",[208,1271,1272,1274,1277,1279,1282,1284,1287],{"class":210,"line":261},[208,1273,1251],{"class":214},[208,1275,1276],{"class":245},"'es'",[208,1278,1257],{"class":214},[208,1280,1281],{"class":245},"'Español'",[208,1283,1263],{"class":214},[208,1285,1286],{"class":245},"'🇪🇸'",[208,1288,1269],{"class":214},[208,1290,1291,1293,1296,1298,1301,1303,1306],{"class":210,"line":269},[208,1292,1251],{"class":214},[208,1294,1295],{"class":245},"'fr'",[208,1297,1257],{"class":214},[208,1299,1300],{"class":245},"'Français'",[208,1302,1263],{"class":214},[208,1304,1305],{"class":245},"'🇫🇷'",[208,1307,1269],{"class":214},[208,1309,1310,1312,1315,1317,1320,1322,1325],{"class":210,"line":277},[208,1311,1251],{"class":214},[208,1313,1314],{"class":245},"'de'",[208,1316,1257],{"class":214},[208,1318,1319],{"class":245},"'Deutsch'",[208,1321,1263],{"class":214},[208,1323,1324],{"class":245},"'🇩🇪'",[208,1326,1269],{"class":214},[208,1328,1329,1331,1334,1336,1339,1341,1344],{"class":210,"line":283},[208,1330,1251],{"class":214},[208,1332,1333],{"class":245},"'it'",[208,1335,1257],{"class":214},[208,1337,1338],{"class":245},"'Italiano'",[208,1340,1263],{"class":214},[208,1342,1343],{"class":245},"'🇮🇹'",[208,1345,1269],{"class":214},[208,1347,1348,1350,1353,1355,1358,1360,1363],{"class":210,"line":289},[208,1349,1251],{"class":214},[208,1351,1352],{"class":245},"'pt'",[208,1354,1257],{"class":214},[208,1356,1357],{"class":245},"'Português'",[208,1359,1263],{"class":214},[208,1361,1362],{"class":245},"'🇵🇹'",[208,1364,1269],{"class":214},[208,1366,1367,1369,1372,1374,1377,1379,1382],{"class":210,"line":295},[208,1368,1251],{"class":214},[208,1370,1371],{"class":245},"'ru'",[208,1373,1257],{"class":214},[208,1375,1376],{"class":245},"'Русский'",[208,1378,1263],{"class":214},[208,1380,1381],{"class":245},"'🇷🇺'",[208,1383,1269],{"class":214},[208,1385,1386,1388,1391,1393,1396,1398,1401],{"class":210,"line":301},[208,1387,1251],{"class":214},[208,1389,1390],{"class":245},"'ar'",[208,1392,1257],{"class":214},[208,1394,1395],{"class":245},"'العربية'",[208,1397,1263],{"class":214},[208,1399,1400],{"class":245},"'🇸🇦'",[208,1402,1269],{"class":214},[208,1404,1405,1407,1410,1412,1415,1417,1420],{"class":210,"line":1078},[208,1406,1251],{"class":214},[208,1408,1409],{"class":245},"'zh'",[208,1411,1257],{"class":214},[208,1413,1414],{"class":245},"'中文'",[208,1416,1263],{"class":214},[208,1418,1419],{"class":245},"'🇨🇳'",[208,1421,1269],{"class":214},[208,1423,1424,1426,1429,1431,1434,1436,1439],{"class":210,"line":1084},[208,1425,1251],{"class":214},[208,1427,1428],{"class":245},"'ja'",[208,1430,1257],{"class":214},[208,1432,1433],{"class":245},"'日本語'",[208,1435,1263],{"class":214},[208,1437,1438],{"class":245},"'🇯🇵'",[208,1440,1269],{"class":214},[208,1442,1443,1445,1448,1450,1453,1455,1458],{"class":210,"line":1089},[208,1444,1251],{"class":214},[208,1446,1447],{"class":245},"'ko'",[208,1449,1257],{"class":214},[208,1451,1452],{"class":245},"'한국어'",[208,1454,1263],{"class":214},[208,1456,1457],{"class":245},"'🇰🇷'",[208,1459,1269],{"class":214},[208,1461,1462,1464,1467,1469,1472,1474,1477],{"class":210,"line":1095},[208,1463,1251],{"class":214},[208,1465,1466],{"class":245},"'hi'",[208,1468,1257],{"class":214},[208,1470,1471],{"class":245},"'हिन्दी'",[208,1473,1263],{"class":214},[208,1475,1476],{"class":245},"'🇮🇳'",[208,1478,1269],{"class":214},[208,1480,1482,1484,1487,1489,1492,1494,1497],{"class":210,"line":1481},17,[208,1483,1251],{"class":214},[208,1485,1486],{"class":245},"'nl'",[208,1488,1257],{"class":214},[208,1490,1491],{"class":245},"'Nederlands'",[208,1493,1263],{"class":214},[208,1495,1496],{"class":245},"'🇳🇱'",[208,1498,1269],{"class":214},[208,1500,1502,1504,1507,1509,1512,1514,1517],{"class":210,"line":1501},18,[208,1503,1251],{"class":214},[208,1505,1506],{"class":245},"'sv'",[208,1508,1257],{"class":214},[208,1510,1511],{"class":245},"'Svenska'",[208,1513,1263],{"class":214},[208,1515,1516],{"class":245},"'🇸🇪'",[208,1518,1269],{"class":214},[208,1520,1522,1524,1527,1529,1532,1534,1537],{"class":210,"line":1521},19,[208,1523,1251],{"class":214},[208,1525,1526],{"class":245},"'no'",[208,1528,1257],{"class":214},[208,1530,1531],{"class":245},"'Norsk'",[208,1533,1263],{"class":214},[208,1535,1536],{"class":245},"'🇳🇴'",[208,1538,1269],{"class":214},[208,1540,1542,1544,1547,1549,1552,1554,1557],{"class":210,"line":1541},20,[208,1543,1251],{"class":214},[208,1545,1546],{"class":245},"'el'",[208,1548,1257],{"class":214},[208,1550,1551],{"class":245},"'Ελληνικά'",[208,1553,1263],{"class":214},[208,1555,1556],{"class":245},"'🇬🇷'",[208,1558,1269],{"class":214},[208,1560,1562,1564,1567,1569,1572,1574,1577],{"class":210,"line":1561},21,[208,1563,1251],{"class":214},[208,1565,1566],{"class":245},"'he'",[208,1568,1257],{"class":214},[208,1570,1571],{"class":245},"'עברית'",[208,1573,1263],{"class":214},[208,1575,1576],{"class":245},"'🇮🇱'",[208,1578,1269],{"class":214},[208,1580,1582,1584,1587,1589,1592,1594,1597],{"class":210,"line":1581},22,[208,1583,1251],{"class":214},[208,1585,1586],{"class":245},"'pl'",[208,1588,1257],{"class":214},[208,1590,1591],{"class":245},"'Polski'",[208,1593,1263],{"class":214},[208,1595,1596],{"class":245},"'🇵🇱'",[208,1598,1269],{"class":214},[208,1600,1602,1604,1607,1609,1612,1614,1617],{"class":210,"line":1601},23,[208,1603,1251],{"class":214},[208,1605,1606],{"class":245},"'ro'",[208,1608,1257],{"class":214},[208,1610,1611],{"class":245},"'Română'",[208,1613,1263],{"class":214},[208,1615,1616],{"class":245},"'🇷🇴'",[208,1618,1269],{"class":214},[208,1620,1622,1624,1627,1629,1632,1634,1637],{"class":210,"line":1621},24,[208,1623,1251],{"class":214},[208,1625,1626],{"class":245},"'tr'",[208,1628,1257],{"class":214},[208,1630,1631],{"class":245},"'Türkçe'",[208,1633,1263],{"class":214},[208,1635,1636],{"class":245},"'🇹🇷'",[208,1638,1269],{"class":214},[208,1640,1642,1644,1647,1649,1652,1654,1657],{"class":210,"line":1641},25,[208,1643,1251],{"class":214},[208,1645,1646],{"class":245},"'uk'",[208,1648,1257],{"class":214},[208,1650,1651],{"class":245},"'Українська'",[208,1653,1263],{"class":214},[208,1655,1656],{"class":245},"'🇺🇦'",[208,1658,1269],{"class":214},[208,1660,1662,1664,1667,1669,1672,1674,1677],{"class":210,"line":1661},26,[208,1663,1251],{"class":214},[208,1665,1666],{"class":245},"'vi'",[208,1668,1257],{"class":214},[208,1670,1671],{"class":245},"'Tiếng Việt'",[208,1673,1263],{"class":214},[208,1675,1676],{"class":245},"'🇻🇳'",[208,1678,1679],{"class":214}," }\n",[208,1681,1683],{"class":210,"line":1682},27,[208,1684,1685],{"class":214},"  ];\n",[208,1687,1689],{"class":210,"line":1688},28,[208,1690,1092],{"emptyLinePlaceholder":866},[208,1692,1694,1696,1699,1701,1704,1707,1710,1713],{"class":210,"line":1693},29,[208,1695,1237],{"class":1190},[208,1697,1698],{"class":1215}," handleChange",[208,1700,1243],{"class":1190},[208,1702,1703],{"class":214}," (",[208,1705,1706],{"class":1222},"langCode",[208,1708,1709],{"class":214},") ",[208,1711,1712],{"class":1190},"=>",[208,1714,1715],{"class":214}," {\n",[208,1717,1719,1722,1725,1728,1731],{"class":210,"line":1718},30,[208,1720,1721],{"class":214},"    localStorage.",[208,1723,1724],{"class":1215},"setItem",[208,1726,1727],{"class":214},"(",[208,1729,1730],{"class":245},"'preferredLanguage'",[208,1732,1733],{"class":214},", langCode);\n",[208,1735,1737,1740],{"class":210,"line":1736},31,[208,1738,1739],{"class":1215},"    onLanguageChange",[208,1741,1742],{"class":214},"(langCode);\n",[208,1744,1746],{"class":210,"line":1745},32,[208,1747,1748],{"class":214},"  };\n",[208,1750,1752],{"class":210,"line":1751},33,[208,1753,1092],{"emptyLinePlaceholder":866},[208,1755,1757,1760],{"class":210,"line":1756},34,[208,1758,1759],{"class":1190},"  return",[208,1761,1762],{"class":214}," (\n",[208,1764,1766,1769,1773,1776,1779,1782],{"class":210,"line":1765},35,[208,1767,1768],{"class":214},"    \u003C",[208,1770,1772],{"class":1771},"s9eBZ","div",[208,1774,1775],{"class":1215}," className",[208,1777,1778],{"class":1190},"=",[208,1780,1781],{"class":245},"\"language-selector\"",[208,1783,1784],{"class":214},">\n",[208,1786,1788,1791,1794],{"class":210,"line":1787},36,[208,1789,1790],{"class":214},"      \u003C",[208,1792,1793],{"class":1771},"select",[208,1795,1796],{"class":214}," \n",[208,1798,1800,1803,1805],{"class":210,"line":1799},37,[208,1801,1802],{"class":1215},"        value",[208,1804,1778],{"class":1190},[208,1806,1807],{"class":214},"{currentLanguage} \n",[208,1809,1811,1814,1816,1819,1822,1824,1826,1828],{"class":210,"line":1810},38,[208,1812,1813],{"class":1215},"        onChange",[208,1815,1778],{"class":1190},[208,1817,1818],{"class":214},"{(",[208,1820,1821],{"class":1222},"e",[208,1823,1709],{"class":214},[208,1825,1712],{"class":1190},[208,1827,1698],{"class":1215},[208,1829,1830],{"class":214},"(e.target.value)}\n",[208,1832,1834],{"class":210,"line":1833},39,[208,1835,1836],{"class":214},"      >\n",[208,1838,1840,1843,1846,1848,1851,1854],{"class":210,"line":1839},40,[208,1841,1842],{"class":214},"        {languages.",[208,1844,1845],{"class":1215},"map",[208,1847,1727],{"class":214},[208,1849,1850],{"class":1222},"lang",[208,1852,1853],{"class":1190}," =>",[208,1855,1762],{"class":214},[208,1857,1859,1862,1865,1868,1870,1873,1876,1878],{"class":210,"line":1858},41,[208,1860,1861],{"class":214},"          \u003C",[208,1863,1864],{"class":1771},"option",[208,1866,1867],{"class":1215}," key",[208,1869,1778],{"class":1190},[208,1871,1872],{"class":214},"{lang.code} ",[208,1874,1875],{"class":1215},"value",[208,1877,1778],{"class":1190},[208,1879,1880],{"class":214},"{lang.code}>\n",[208,1882,1884],{"class":210,"line":1883},42,[208,1885,1886],{"class":214},"            {lang.flag} {lang.name}\n",[208,1888,1890,1893,1895],{"class":210,"line":1889},43,[208,1891,1892],{"class":214},"          \u003C\u002F",[208,1894,1864],{"class":1771},[208,1896,1784],{"class":214},[208,1898,1900],{"class":210,"line":1899},44,[208,1901,1902],{"class":214},"        ))}\n",[208,1904,1906,1909,1911],{"class":210,"line":1905},45,[208,1907,1908],{"class":214},"      \u003C\u002F",[208,1910,1793],{"class":1771},[208,1912,1784],{"class":214},[208,1914,1916,1919,1921],{"class":210,"line":1915},46,[208,1917,1918],{"class":214},"    \u003C\u002F",[208,1920,1772],{"class":1771},[208,1922,1784],{"class":214},[208,1924,1926],{"class":210,"line":1925},47,[208,1927,1130],{"class":214},[208,1929,1931],{"class":210,"line":1930},48,[208,1932,304],{"class":214},[208,1934,1936],{"class":210,"line":1935},49,[208,1937,1092],{"emptyLinePlaceholder":866},[208,1939,1941,1944,1947],{"class":210,"line":1940},50,[208,1942,1943],{"class":1190},"export",[208,1945,1946],{"class":1190}," default",[208,1948,1949],{"class":214}," LanguageSelector;\n",[21,1951,1953],{"id":1952},"step-4-internationalizing-your-ui","Step 4: Internationalizing Your UI",[12,1955,1956,1957,1960],{},"Use a library like ",[205,1958,1959],{},"react-i18next"," for UI translations:",[198,1962,1966],{"className":1963,"code":1964,"language":1965,"meta":203,"style":203},"language-bash shiki shiki-themes github-light github-dark","npm install react-i18next i18next\n","bash",[205,1967,1968],{"__ignoreMap":203},[208,1969,1970,1973,1976,1979],{"class":210,"line":211},[208,1971,1972],{"class":1215},"npm",[208,1974,1975],{"class":245}," install",[208,1977,1978],{"class":245}," react-i18next",[208,1980,1981],{"class":245}," i18next\n",[12,1983,1984],{},"Set up your translations:",[198,1986,1988],{"className":1013,"code":1987,"language":1015,"meta":203,"style":203},"\u002F\u002F i18n.js\nimport i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\n\nconst resources = {\n  en: {\n    translation: {\n      \"headlines\": \"Headlines\",\n      \"search\": \"Search\",\n      \"readMore\": \"Read More\",\n      \"loading\": \"Loading...\",\n      \"noResults\": \"No articles found\"\n    }\n  },\n  es: {\n    translation: {\n      \"headlines\": \"Titulares\",\n      \"search\": \"Buscar\",\n      \"readMore\": \"Leer Más\",\n      \"loading\": \"Cargando...\",\n      \"noResults\": \"No se encontraron artículos\"\n    }\n  },\n  fr: {\n    translation: {\n      \"headlines\": \"Titres\",\n      \"search\": \"Rechercher\",\n      \"readMore\": \"Lire Plus\",\n      \"loading\": \"Chargement...\",\n      \"noResults\": \"Aucun article trouvé\"\n    }\n  },\n  de: {\n    translation: {\n      \"headlines\": \"Schlagzeilen\",\n      \"search\": \"Suchen\",\n      \"readMore\": \"Mehr Lesen\",\n      \"loading\": \"Laden...\",\n      \"noResults\": \"Keine Artikel gefunden\"\n    }\n  }\n  \u002F\u002F Add more languages as needed\n};\n\ni18n\n  .use(initReactI18next)\n  .init({\n    resources,\n    lng: detectUserLanguage(),\n    fallbackLng: 'en',\n    interpolation: {\n      escapeValue: false\n    }\n  });\n\nexport default i18n;\n",[205,1989,1990,1995,2000,2005,2009,2014,2019,2024,2029,2034,2039,2044,2049,2053,2058,2063,2067,2072,2077,2082,2087,2092,2096,2100,2105,2109,2114,2119,2124,2129,2134,2138,2142,2147,2151,2156,2161,2166,2171,2176,2180,2184,2189,2194,2198,2203,2208,2213,2218,2223,2228,2234,2240,2245,2251,2256],{"__ignoreMap":203},[208,1991,1992],{"class":210,"line":211},[208,1993,1994],{},"\u002F\u002F i18n.js\n",[208,1996,1997],{"class":210,"line":218},[208,1998,1999],{},"import i18n from 'i18next';\n",[208,2001,2002],{"class":210,"line":228},[208,2003,2004],{},"import { initReactI18next } from 'react-i18next';\n",[208,2006,2007],{"class":210,"line":236},[208,2008,1092],{"emptyLinePlaceholder":866},[208,2010,2011],{"class":210,"line":252},[208,2012,2013],{},"const resources = {\n",[208,2015,2016],{"class":210,"line":261},[208,2017,2018],{},"  en: {\n",[208,2020,2021],{"class":210,"line":269},[208,2022,2023],{},"    translation: {\n",[208,2025,2026],{"class":210,"line":277},[208,2027,2028],{},"      \"headlines\": \"Headlines\",\n",[208,2030,2031],{"class":210,"line":283},[208,2032,2033],{},"      \"search\": \"Search\",\n",[208,2035,2036],{"class":210,"line":289},[208,2037,2038],{},"      \"readMore\": \"Read More\",\n",[208,2040,2041],{"class":210,"line":295},[208,2042,2043],{},"      \"loading\": \"Loading...\",\n",[208,2045,2046],{"class":210,"line":301},[208,2047,2048],{},"      \"noResults\": \"No articles found\"\n",[208,2050,2051],{"class":210,"line":1078},[208,2052,292],{},[208,2054,2055],{"class":210,"line":1084},[208,2056,2057],{},"  },\n",[208,2059,2060],{"class":210,"line":1089},[208,2061,2062],{},"  es: {\n",[208,2064,2065],{"class":210,"line":1095},[208,2066,2023],{},[208,2068,2069],{"class":210,"line":1481},[208,2070,2071],{},"      \"headlines\": \"Titulares\",\n",[208,2073,2074],{"class":210,"line":1501},[208,2075,2076],{},"      \"search\": \"Buscar\",\n",[208,2078,2079],{"class":210,"line":1521},[208,2080,2081],{},"      \"readMore\": \"Leer Más\",\n",[208,2083,2084],{"class":210,"line":1541},[208,2085,2086],{},"      \"loading\": \"Cargando...\",\n",[208,2088,2089],{"class":210,"line":1561},[208,2090,2091],{},"      \"noResults\": \"No se encontraron artículos\"\n",[208,2093,2094],{"class":210,"line":1581},[208,2095,292],{},[208,2097,2098],{"class":210,"line":1601},[208,2099,2057],{},[208,2101,2102],{"class":210,"line":1621},[208,2103,2104],{},"  fr: {\n",[208,2106,2107],{"class":210,"line":1641},[208,2108,2023],{},[208,2110,2111],{"class":210,"line":1661},[208,2112,2113],{},"      \"headlines\": \"Titres\",\n",[208,2115,2116],{"class":210,"line":1682},[208,2117,2118],{},"      \"search\": \"Rechercher\",\n",[208,2120,2121],{"class":210,"line":1688},[208,2122,2123],{},"      \"readMore\": \"Lire Plus\",\n",[208,2125,2126],{"class":210,"line":1693},[208,2127,2128],{},"      \"loading\": \"Chargement...\",\n",[208,2130,2131],{"class":210,"line":1718},[208,2132,2133],{},"      \"noResults\": \"Aucun article trouvé\"\n",[208,2135,2136],{"class":210,"line":1736},[208,2137,292],{},[208,2139,2140],{"class":210,"line":1745},[208,2141,2057],{},[208,2143,2144],{"class":210,"line":1751},[208,2145,2146],{},"  de: {\n",[208,2148,2149],{"class":210,"line":1756},[208,2150,2023],{},[208,2152,2153],{"class":210,"line":1765},[208,2154,2155],{},"      \"headlines\": \"Schlagzeilen\",\n",[208,2157,2158],{"class":210,"line":1787},[208,2159,2160],{},"      \"search\": \"Suchen\",\n",[208,2162,2163],{"class":210,"line":1799},[208,2164,2165],{},"      \"readMore\": \"Mehr Lesen\",\n",[208,2167,2168],{"class":210,"line":1810},[208,2169,2170],{},"      \"loading\": \"Laden...\",\n",[208,2172,2173],{"class":210,"line":1833},[208,2174,2175],{},"      \"noResults\": \"Keine Artikel gefunden\"\n",[208,2177,2178],{"class":210,"line":1839},[208,2179,292],{},[208,2181,2182],{"class":210,"line":1858},[208,2183,298],{},[208,2185,2186],{"class":210,"line":1883},[208,2187,2188],{},"  \u002F\u002F Add more languages as needed\n",[208,2190,2191],{"class":210,"line":1889},[208,2192,2193],{},"};\n",[208,2195,2196],{"class":210,"line":1899},[208,2197,1092],{"emptyLinePlaceholder":866},[208,2199,2200],{"class":210,"line":1905},[208,2201,2202],{},"i18n\n",[208,2204,2205],{"class":210,"line":1915},[208,2206,2207],{},"  .use(initReactI18next)\n",[208,2209,2210],{"class":210,"line":1925},[208,2211,2212],{},"  .init({\n",[208,2214,2215],{"class":210,"line":1930},[208,2216,2217],{},"    resources,\n",[208,2219,2220],{"class":210,"line":1935},[208,2221,2222],{},"    lng: detectUserLanguage(),\n",[208,2224,2225],{"class":210,"line":1940},[208,2226,2227],{},"    fallbackLng: 'en',\n",[208,2229,2231],{"class":210,"line":2230},51,[208,2232,2233],{},"    interpolation: {\n",[208,2235,2237],{"class":210,"line":2236},52,[208,2238,2239],{},"      escapeValue: false\n",[208,2241,2243],{"class":210,"line":2242},53,[208,2244,292],{},[208,2246,2248],{"class":210,"line":2247},54,[208,2249,2250],{},"  });\n",[208,2252,2254],{"class":210,"line":2253},55,[208,2255,1092],{"emptyLinePlaceholder":866},[208,2257,2259],{"class":210,"line":2258},56,[208,2260,2261],{},"export default i18n;\n",[12,2263,2264],{},"Use translations in your components:",[198,2266,2268],{"className":1181,"code":2267,"language":1183,"meta":203,"style":203},"import { useTranslation } from 'react-i18next';\n\nfunction NewsApp() {\n  const { t, i18n } = useTranslation();\n  const [articles, setArticles] = useState([]);\n  const [loading, setLoading] = useState(true);\n\n  const changeLanguage = async (lang) => {\n    i18n.changeLanguage(lang);\n    \u002F\u002F Fetch news in new language\n    const news = await getNewsInLanguage(lang, getCountryForLanguage(lang));\n    setArticles(news.articles);\n  };\n\n  return (\n    \u003Cdiv>\n      \u003Ch1>{t('headlines')}\u003C\u002Fh1>\n      \u003CLanguageSelector \n        currentLanguage={i18n.language}\n        onLanguageChange={changeLanguage}\n      \u002F>\n      {loading ? (\n        \u003Cp>{t('loading')}\u003C\u002Fp>\n      ) : articles.length === 0 ? (\n        \u003Cp>{t('noResults')}\u003C\u002Fp>\n      ) : (\n        \u003CArticleList articles={articles} \u002F>\n      )}\n    \u003C\u002Fdiv>\n  );\n}\n",[205,2269,2270,2284,2288,2298,2324,2350,2378,2382,2404,2415,2421,2446,2454,2458,2462,2468,2476,2500,2509,2519,2529,2534,2544,2566,2591,2612,2620,2635,2640,2648,2652],{"__ignoreMap":203},[208,2271,2272,2274,2277,2279,2282],{"class":210,"line":211},[208,2273,1191],{"class":1190},[208,2275,2276],{"class":214}," { useTranslation } ",[208,2278,1197],{"class":1190},[208,2280,2281],{"class":245}," 'react-i18next'",[208,2283,1203],{"class":214},[208,2285,2286],{"class":210,"line":218},[208,2287,1092],{"emptyLinePlaceholder":866},[208,2289,2290,2292,2295],{"class":210,"line":228},[208,2291,1212],{"class":1190},[208,2293,2294],{"class":1215}," NewsApp",[208,2296,2297],{"class":214},"() {\n",[208,2299,2300,2302,2305,2308,2310,2313,2316,2318,2321],{"class":210,"line":236},[208,2301,1237],{"class":1190},[208,2303,2304],{"class":214}," { ",[208,2306,2307],{"class":221},"t",[208,2309,1226],{"class":214},[208,2311,2312],{"class":221},"i18n",[208,2314,2315],{"class":214}," } ",[208,2317,1778],{"class":1190},[208,2319,2320],{"class":1215}," useTranslation",[208,2322,2323],{"class":214},"();\n",[208,2325,2326,2328,2331,2334,2336,2339,2342,2344,2347],{"class":210,"line":252},[208,2327,1237],{"class":1190},[208,2329,2330],{"class":214}," [",[208,2332,2333],{"class":221},"articles",[208,2335,1226],{"class":214},[208,2337,2338],{"class":221},"setArticles",[208,2340,2341],{"class":214},"] ",[208,2343,1778],{"class":1190},[208,2345,2346],{"class":1215}," useState",[208,2348,2349],{"class":214},"([]);\n",[208,2351,2352,2354,2356,2359,2361,2364,2366,2368,2370,2372,2375],{"class":210,"line":261},[208,2353,1237],{"class":1190},[208,2355,2330],{"class":214},[208,2357,2358],{"class":221},"loading",[208,2360,1226],{"class":214},[208,2362,2363],{"class":221},"setLoading",[208,2365,2341],{"class":214},[208,2367,1778],{"class":1190},[208,2369,2346],{"class":1215},[208,2371,1727],{"class":214},[208,2373,2374],{"class":221},"true",[208,2376,2377],{"class":214},");\n",[208,2379,2380],{"class":210,"line":269},[208,2381,1092],{"emptyLinePlaceholder":866},[208,2383,2384,2386,2389,2391,2394,2396,2398,2400,2402],{"class":210,"line":277},[208,2385,1237],{"class":1190},[208,2387,2388],{"class":1215}," changeLanguage",[208,2390,1243],{"class":1190},[208,2392,2393],{"class":1190}," async",[208,2395,1703],{"class":214},[208,2397,1850],{"class":1222},[208,2399,1709],{"class":214},[208,2401,1712],{"class":1190},[208,2403,1715],{"class":214},[208,2405,2406,2409,2412],{"class":210,"line":283},[208,2407,2408],{"class":214},"    i18n.",[208,2410,2411],{"class":1215},"changeLanguage",[208,2413,2414],{"class":214},"(lang);\n",[208,2416,2417],{"class":210,"line":289},[208,2418,2420],{"class":2419},"sJ8bj","    \u002F\u002F Fetch news in new language\n",[208,2422,2423,2426,2429,2431,2434,2437,2440,2443],{"class":210,"line":295},[208,2424,2425],{"class":1190},"    const",[208,2427,2428],{"class":221}," news",[208,2430,1243],{"class":1190},[208,2432,2433],{"class":1190}," await",[208,2435,2436],{"class":1215}," getNewsInLanguage",[208,2438,2439],{"class":214},"(lang, ",[208,2441,2442],{"class":1215},"getCountryForLanguage",[208,2444,2445],{"class":214},"(lang));\n",[208,2447,2448,2451],{"class":210,"line":301},[208,2449,2450],{"class":1215},"    setArticles",[208,2452,2453],{"class":214},"(news.articles);\n",[208,2455,2456],{"class":210,"line":1078},[208,2457,1748],{"class":214},[208,2459,2460],{"class":210,"line":1084},[208,2461,1092],{"emptyLinePlaceholder":866},[208,2463,2464,2466],{"class":210,"line":1089},[208,2465,1759],{"class":1190},[208,2467,1762],{"class":214},[208,2469,2470,2472,2474],{"class":210,"line":1095},[208,2471,1768],{"class":214},[208,2473,1772],{"class":1771},[208,2475,1784],{"class":214},[208,2477,2478,2480,2483,2486,2488,2490,2493,2496,2498],{"class":210,"line":1481},[208,2479,1790],{"class":214},[208,2481,2482],{"class":1771},"h1",[208,2484,2485],{"class":214},">{",[208,2487,2307],{"class":1215},[208,2489,1727],{"class":214},[208,2491,2492],{"class":245},"'headlines'",[208,2494,2495],{"class":214},")}\u003C\u002F",[208,2497,2482],{"class":1771},[208,2499,1784],{"class":214},[208,2501,2502,2504,2507],{"class":210,"line":1501},[208,2503,1790],{"class":214},[208,2505,2506],{"class":221},"LanguageSelector",[208,2508,1796],{"class":214},[208,2510,2511,2514,2516],{"class":210,"line":1521},[208,2512,2513],{"class":1215},"        currentLanguage",[208,2515,1778],{"class":1190},[208,2517,2518],{"class":214},"{i18n.language}\n",[208,2520,2521,2524,2526],{"class":210,"line":1541},[208,2522,2523],{"class":1215},"        onLanguageChange",[208,2525,1778],{"class":1190},[208,2527,2528],{"class":214},"{changeLanguage}\n",[208,2530,2531],{"class":210,"line":1561},[208,2532,2533],{"class":214},"      \u002F>\n",[208,2535,2536,2539,2542],{"class":210,"line":1581},[208,2537,2538],{"class":214},"      {loading ",[208,2540,2541],{"class":1190},"?",[208,2543,1762],{"class":214},[208,2545,2546,2549,2551,2553,2555,2557,2560,2562,2564],{"class":210,"line":1601},[208,2547,2548],{"class":214},"        \u003C",[208,2550,12],{"class":1771},[208,2552,2485],{"class":214},[208,2554,2307],{"class":1215},[208,2556,1727],{"class":214},[208,2558,2559],{"class":245},"'loading'",[208,2561,2495],{"class":214},[208,2563,12],{"class":1771},[208,2565,1784],{"class":214},[208,2567,2568,2571,2574,2577,2580,2583,2586,2589],{"class":210,"line":1621},[208,2569,2570],{"class":214},"      ) ",[208,2572,2573],{"class":1190},":",[208,2575,2576],{"class":214}," articles.",[208,2578,2579],{"class":221},"length",[208,2581,2582],{"class":1190}," ===",[208,2584,2585],{"class":221}," 0",[208,2587,2588],{"class":1190}," ?",[208,2590,1762],{"class":214},[208,2592,2593,2595,2597,2599,2601,2603,2606,2608,2610],{"class":210,"line":1641},[208,2594,2548],{"class":214},[208,2596,12],{"class":1771},[208,2598,2485],{"class":214},[208,2600,2307],{"class":1215},[208,2602,1727],{"class":214},[208,2604,2605],{"class":245},"'noResults'",[208,2607,2495],{"class":214},[208,2609,12],{"class":1771},[208,2611,1784],{"class":214},[208,2613,2614,2616,2618],{"class":210,"line":1661},[208,2615,2570],{"class":214},[208,2617,2573],{"class":1190},[208,2619,1762],{"class":214},[208,2621,2622,2624,2627,2630,2632],{"class":210,"line":1682},[208,2623,2548],{"class":214},[208,2625,2626],{"class":221},"ArticleList",[208,2628,2629],{"class":1215}," articles",[208,2631,1778],{"class":1190},[208,2633,2634],{"class":214},"{articles} \u002F>\n",[208,2636,2637],{"class":210,"line":1688},[208,2638,2639],{"class":214},"      )}\n",[208,2641,2642,2644,2646],{"class":210,"line":1693},[208,2643,1918],{"class":214},[208,2645,1772],{"class":1771},[208,2647,1784],{"class":214},[208,2649,2650],{"class":210,"line":1718},[208,2651,1130],{"class":214},[208,2653,2654],{"class":210,"line":1736},[208,2655,304],{"class":214},[21,2657,2659],{"id":2658},"step-5-handling-right-to-left-languages","Step 5: Handling Right-to-Left Languages",[12,2661,2662],{},"For languages like Arabic and Hebrew, implement RTL support:",[198,2664,2668],{"className":2665,"code":2666,"language":2667,"meta":203,"style":203},"language-css shiki shiki-themes github-light github-dark","\u002F* Add to your CSS *\u002F\n[dir=\"rtl\"] {\n  direction: rtl;\n  text-align: right;\n}\n\n[dir=\"rtl\"] .article-card {\n  text-align: right;\n}\n\n[dir=\"rtl\"] .button {\n  margin-left: 0;\n  margin-right: 10px;\n}\n","css",[205,2669,2670,2675,2691,2703,2715,2719,2723,2740,2750,2754,2758,2775,2787,2802],{"__ignoreMap":203},[208,2671,2672],{"class":210,"line":211},[208,2673,2674],{"class":2419},"\u002F* Add to your CSS *\u002F\n",[208,2676,2677,2680,2683,2685,2688],{"class":210,"line":218},[208,2678,2679],{"class":214},"[",[208,2681,2682],{"class":1215},"dir",[208,2684,1778],{"class":1190},[208,2686,2687],{"class":245},"\"rtl\"",[208,2689,2690],{"class":214},"] {\n",[208,2692,2693,2696,2698,2701],{"class":210,"line":228},[208,2694,2695],{"class":221},"  direction",[208,2697,242],{"class":214},[208,2699,2700],{"class":221},"rtl",[208,2702,1203],{"class":214},[208,2704,2705,2708,2710,2713],{"class":210,"line":236},[208,2706,2707],{"class":221},"  text-align",[208,2709,242],{"class":214},[208,2711,2712],{"class":221},"right",[208,2714,1203],{"class":214},[208,2716,2717],{"class":210,"line":252},[208,2718,304],{"class":214},[208,2720,2721],{"class":210,"line":261},[208,2722,1092],{"emptyLinePlaceholder":866},[208,2724,2725,2727,2729,2731,2733,2735,2738],{"class":210,"line":269},[208,2726,2679],{"class":214},[208,2728,2682],{"class":1215},[208,2730,1778],{"class":1190},[208,2732,2687],{"class":245},[208,2734,2341],{"class":214},[208,2736,2737],{"class":1215},".article-card",[208,2739,1715],{"class":214},[208,2741,2742,2744,2746,2748],{"class":210,"line":277},[208,2743,2707],{"class":221},[208,2745,242],{"class":214},[208,2747,2712],{"class":221},[208,2749,1203],{"class":214},[208,2751,2752],{"class":210,"line":283},[208,2753,304],{"class":214},[208,2755,2756],{"class":210,"line":289},[208,2757,1092],{"emptyLinePlaceholder":866},[208,2759,2760,2762,2764,2766,2768,2770,2773],{"class":210,"line":295},[208,2761,2679],{"class":214},[208,2763,2682],{"class":1215},[208,2765,1778],{"class":1190},[208,2767,2687],{"class":245},[208,2769,2341],{"class":214},[208,2771,2772],{"class":1215},".button",[208,2774,1715],{"class":214},[208,2776,2777,2780,2782,2785],{"class":210,"line":301},[208,2778,2779],{"class":221},"  margin-left",[208,2781,242],{"class":214},[208,2783,2784],{"class":221},"0",[208,2786,1203],{"class":214},[208,2788,2789,2792,2794,2797,2800],{"class":210,"line":1078},[208,2790,2791],{"class":221},"  margin-right",[208,2793,242],{"class":214},[208,2795,2796],{"class":221},"10",[208,2798,2799],{"class":1190},"px",[208,2801,1203],{"class":214},[208,2803,2804],{"class":210,"line":1084},[208,2805,304],{"class":214},[12,2807,2808],{},"Update the HTML direction dynamically:",[198,2810,2812],{"className":1013,"code":2811,"language":1015,"meta":203,"style":203},"useEffect(() => {\n  const rtlLanguages = ['ar', 'he'];\n  const direction = rtlLanguages.includes(i18n.language) ? 'rtl' : 'ltr';\n  document.documentElement.setAttribute('dir', direction);\n}, [i18n.language]);\n",[205,2813,2814,2819,2824,2829,2834],{"__ignoreMap":203},[208,2815,2816],{"class":210,"line":211},[208,2817,2818],{},"useEffect(() => {\n",[208,2820,2821],{"class":210,"line":218},[208,2822,2823],{},"  const rtlLanguages = ['ar', 'he'];\n",[208,2825,2826],{"class":210,"line":228},[208,2827,2828],{},"  const direction = rtlLanguages.includes(i18n.language) ? 'rtl' : 'ltr';\n",[208,2830,2831],{"class":210,"line":236},[208,2832,2833],{},"  document.documentElement.setAttribute('dir', direction);\n",[208,2835,2836],{"class":210,"line":252},[208,2837,2838],{},"}, [i18n.language]);\n",[21,2840,2842],{"id":2841},"step-6-date-and-time-localization","Step 6: Date and Time Localization",[12,2844,2845],{},"Format dates according to the user's locale:",[198,2847,2849],{"className":1013,"code":2848,"language":1015,"meta":203,"style":203},"function formatDate(dateString, language) {\n  const date = new Date(dateString);\n  \n  return new Intl.DateTimeFormat(language, {\n    year: 'numeric',\n    month: 'long',\n    day: 'numeric',\n    hour: '2-digit',\n    minute: '2-digit'\n  }).format(date);\n}\n\n\u002F\u002F Usage\nconst formattedDate = formatDate('2024-11-05T10:30:00Z', 'es');\n\u002F\u002F Output: \"5 de noviembre de 2024, 10:30\"\n",[205,2850,2851,2856,2861,2865,2870,2875,2880,2885,2890,2895,2900,2904,2908,2913,2918],{"__ignoreMap":203},[208,2852,2853],{"class":210,"line":211},[208,2854,2855],{},"function formatDate(dateString, language) {\n",[208,2857,2858],{"class":210,"line":218},[208,2859,2860],{},"  const date = new Date(dateString);\n",[208,2862,2863],{"class":210,"line":228},[208,2864,1042],{},[208,2866,2867],{"class":210,"line":236},[208,2868,2869],{},"  return new Intl.DateTimeFormat(language, {\n",[208,2871,2872],{"class":210,"line":252},[208,2873,2874],{},"    year: 'numeric',\n",[208,2876,2877],{"class":210,"line":261},[208,2878,2879],{},"    month: 'long',\n",[208,2881,2882],{"class":210,"line":269},[208,2883,2884],{},"    day: 'numeric',\n",[208,2886,2887],{"class":210,"line":277},[208,2888,2889],{},"    hour: '2-digit',\n",[208,2891,2892],{"class":210,"line":283},[208,2893,2894],{},"    minute: '2-digit'\n",[208,2896,2897],{"class":210,"line":289},[208,2898,2899],{},"  }).format(date);\n",[208,2901,2902],{"class":210,"line":295},[208,2903,304],{},[208,2905,2906],{"class":210,"line":301},[208,2907,1092],{"emptyLinePlaceholder":866},[208,2909,2910],{"class":210,"line":1078},[208,2911,2912],{},"\u002F\u002F Usage\n",[208,2914,2915],{"class":210,"line":1084},[208,2916,2917],{},"const formattedDate = formatDate('2024-11-05T10:30:00Z', 'es');\n",[208,2919,2920],{"class":210,"line":1089},[208,2921,2922],{},"\u002F\u002F Output: \"5 de noviembre de 2024, 10:30\"\n",[21,2924,2926],{"id":2925},"step-7-country-language-mapping","Step 7: Country-Language Mapping",[12,2928,2929],{},"Create intelligent defaults for country-language combinations:",[198,2931,2933],{"className":1013,"code":2932,"language":1015,"meta":203,"style":203},"const countryLanguageMap = {\n  'us': 'en',\n  'gb': 'en',\n  'es': 'es',\n  'mx': 'es',\n  'ar': 'es',\n  'fr': 'fr',\n  'de': 'de',\n  'it': 'it',\n  'pt': 'pt',\n  'br': 'pt',\n  'ru': 'ru',\n  'sa': 'ar',\n  'ae': 'ar',\n  'cn': 'zh',\n  'jp': 'ja',\n  'kr': 'ko',\n  'in': 'hi',\n  'nl': 'nl',\n  'se': 'sv',\n  'no': 'no',\n  'gr': 'el',\n  'il': 'he',\n  'ua': 'uk',\n  'ro': 'ro',\n  'pl': 'pl',\n  'tr': 'tr',\n  'vn': 'vi'\n};\n\nfunction getCountryForLanguage(language) {\n  const languageCountryMap = {\n    'en': 'us',\n    'es': 'es',\n    'fr': 'fr',\n    'de': 'de',\n    'it': 'it',\n    'pt': 'pt',\n    'ru': 'ru',\n    'ar': 'sa',\n    'zh': 'cn',\n    'ja': 'jp',\n    'ko': 'kr',\n    'hi': 'in',\n    'nl': 'nl',\n    'sv': 'se',\n    'no': 'no',\n    'el': 'gr',\n    'he': 'il',\n    'uk': 'ua',\n    'ro': 'ro',\n    'pl': 'pl',\n    'tr': 'tr',\n    'vi': 'vn'\n  };\n  \n  return languageCountryMap[language] || 'us';\n}\n",[205,2934,2935,2940,2945,2950,2955,2960,2965,2970,2975,2980,2985,2990,2995,3000,3005,3010,3015,3020,3025,3030,3035,3040,3045,3050,3055,3060,3065,3070,3075,3079,3083,3088,3093,3098,3103,3108,3113,3118,3123,3128,3133,3138,3143,3148,3153,3158,3163,3168,3173,3178,3183,3188,3193,3198,3203,3207,3211,3217],{"__ignoreMap":203},[208,2936,2937],{"class":210,"line":211},[208,2938,2939],{},"const countryLanguageMap = {\n",[208,2941,2942],{"class":210,"line":218},[208,2943,2944],{},"  'us': 'en',\n",[208,2946,2947],{"class":210,"line":228},[208,2948,2949],{},"  'gb': 'en',\n",[208,2951,2952],{"class":210,"line":236},[208,2953,2954],{},"  'es': 'es',\n",[208,2956,2957],{"class":210,"line":252},[208,2958,2959],{},"  'mx': 'es',\n",[208,2961,2962],{"class":210,"line":261},[208,2963,2964],{},"  'ar': 'es',\n",[208,2966,2967],{"class":210,"line":269},[208,2968,2969],{},"  'fr': 'fr',\n",[208,2971,2972],{"class":210,"line":277},[208,2973,2974],{},"  'de': 'de',\n",[208,2976,2977],{"class":210,"line":283},[208,2978,2979],{},"  'it': 'it',\n",[208,2981,2982],{"class":210,"line":289},[208,2983,2984],{},"  'pt': 'pt',\n",[208,2986,2987],{"class":210,"line":295},[208,2988,2989],{},"  'br': 'pt',\n",[208,2991,2992],{"class":210,"line":301},[208,2993,2994],{},"  'ru': 'ru',\n",[208,2996,2997],{"class":210,"line":1078},[208,2998,2999],{},"  'sa': 'ar',\n",[208,3001,3002],{"class":210,"line":1084},[208,3003,3004],{},"  'ae': 'ar',\n",[208,3006,3007],{"class":210,"line":1089},[208,3008,3009],{},"  'cn': 'zh',\n",[208,3011,3012],{"class":210,"line":1095},[208,3013,3014],{},"  'jp': 'ja',\n",[208,3016,3017],{"class":210,"line":1481},[208,3018,3019],{},"  'kr': 'ko',\n",[208,3021,3022],{"class":210,"line":1501},[208,3023,3024],{},"  'in': 'hi',\n",[208,3026,3027],{"class":210,"line":1521},[208,3028,3029],{},"  'nl': 'nl',\n",[208,3031,3032],{"class":210,"line":1541},[208,3033,3034],{},"  'se': 'sv',\n",[208,3036,3037],{"class":210,"line":1561},[208,3038,3039],{},"  'no': 'no',\n",[208,3041,3042],{"class":210,"line":1581},[208,3043,3044],{},"  'gr': 'el',\n",[208,3046,3047],{"class":210,"line":1601},[208,3048,3049],{},"  'il': 'he',\n",[208,3051,3052],{"class":210,"line":1621},[208,3053,3054],{},"  'ua': 'uk',\n",[208,3056,3057],{"class":210,"line":1641},[208,3058,3059],{},"  'ro': 'ro',\n",[208,3061,3062],{"class":210,"line":1661},[208,3063,3064],{},"  'pl': 'pl',\n",[208,3066,3067],{"class":210,"line":1682},[208,3068,3069],{},"  'tr': 'tr',\n",[208,3071,3072],{"class":210,"line":1688},[208,3073,3074],{},"  'vn': 'vi'\n",[208,3076,3077],{"class":210,"line":1693},[208,3078,2193],{},[208,3080,3081],{"class":210,"line":1718},[208,3082,1092],{"emptyLinePlaceholder":866},[208,3084,3085],{"class":210,"line":1736},[208,3086,3087],{},"function getCountryForLanguage(language) {\n",[208,3089,3090],{"class":210,"line":1745},[208,3091,3092],{},"  const languageCountryMap = {\n",[208,3094,3095],{"class":210,"line":1751},[208,3096,3097],{},"    'en': 'us',\n",[208,3099,3100],{"class":210,"line":1756},[208,3101,3102],{},"    'es': 'es',\n",[208,3104,3105],{"class":210,"line":1765},[208,3106,3107],{},"    'fr': 'fr',\n",[208,3109,3110],{"class":210,"line":1787},[208,3111,3112],{},"    'de': 'de',\n",[208,3114,3115],{"class":210,"line":1799},[208,3116,3117],{},"    'it': 'it',\n",[208,3119,3120],{"class":210,"line":1810},[208,3121,3122],{},"    'pt': 'pt',\n",[208,3124,3125],{"class":210,"line":1833},[208,3126,3127],{},"    'ru': 'ru',\n",[208,3129,3130],{"class":210,"line":1839},[208,3131,3132],{},"    'ar': 'sa',\n",[208,3134,3135],{"class":210,"line":1858},[208,3136,3137],{},"    'zh': 'cn',\n",[208,3139,3140],{"class":210,"line":1883},[208,3141,3142],{},"    'ja': 'jp',\n",[208,3144,3145],{"class":210,"line":1889},[208,3146,3147],{},"    'ko': 'kr',\n",[208,3149,3150],{"class":210,"line":1899},[208,3151,3152],{},"    'hi': 'in',\n",[208,3154,3155],{"class":210,"line":1905},[208,3156,3157],{},"    'nl': 'nl',\n",[208,3159,3160],{"class":210,"line":1915},[208,3161,3162],{},"    'sv': 'se',\n",[208,3164,3165],{"class":210,"line":1925},[208,3166,3167],{},"    'no': 'no',\n",[208,3169,3170],{"class":210,"line":1930},[208,3171,3172],{},"    'el': 'gr',\n",[208,3174,3175],{"class":210,"line":1935},[208,3176,3177],{},"    'he': 'il',\n",[208,3179,3180],{"class":210,"line":1940},[208,3181,3182],{},"    'uk': 'ua',\n",[208,3184,3185],{"class":210,"line":2230},[208,3186,3187],{},"    'ro': 'ro',\n",[208,3189,3190],{"class":210,"line":2236},[208,3191,3192],{},"    'pl': 'pl',\n",[208,3194,3195],{"class":210,"line":2242},[208,3196,3197],{},"    'tr': 'tr',\n",[208,3199,3200],{"class":210,"line":2247},[208,3201,3202],{},"    'vi': 'vn'\n",[208,3204,3205],{"class":210,"line":2253},[208,3206,1748],{},[208,3208,3209],{"class":210,"line":2258},[208,3210,1042],{},[208,3212,3214],{"class":210,"line":3213},57,[208,3215,3216],{},"  return languageCountryMap[language] || 'us';\n",[208,3218,3220],{"class":210,"line":3219},58,[208,3221,304],{},[21,3223,3225],{"id":3224},"step-8-seo-for-multi-language-content","Step 8: SEO for Multi-Language Content",[12,3227,3228],{},"Implement proper SEO tags for each language:",[198,3230,3232],{"className":1181,"code":3231,"language":1183,"meta":203,"style":203},"function NewsPage({ language, articles }) {\n  return (\n    \u003C>\n      \u003CHead>\n        \u003Chtml lang={language} \u002F>\n        \u003Clink rel=\"alternate\" hrefLang=\"en\" href=\"https:\u002F\u002Fyourapp.com\u002Fen\" \u002F>\n        \u003Clink rel=\"alternate\" hrefLang=\"es\" href=\"https:\u002F\u002Fyourapp.com\u002Fes\" \u002F>\n        \u003Clink rel=\"alternate\" hrefLang=\"fr\" href=\"https:\u002F\u002Fyourapp.com\u002Ffr\" \u002F>\n        {\u002F* Add more language alternates *\u002F}\n      \u003C\u002FHead>\n      {\u002F* Your content *\u002F}\n    \u003C\u002F>\n  );\n}\n",[205,3233,3234,3252,3258,3263,3272,3287,3321,3349,3377,3387,3395,3405,3410,3414],{"__ignoreMap":203},[208,3235,3236,3238,3241,3243,3246,3248,3250],{"class":210,"line":211},[208,3237,1212],{"class":1190},[208,3239,3240],{"class":1215}," NewsPage",[208,3242,1219],{"class":214},[208,3244,3245],{"class":1222},"language",[208,3247,1226],{"class":214},[208,3249,2333],{"class":1222},[208,3251,1232],{"class":214},[208,3253,3254,3256],{"class":210,"line":218},[208,3255,1759],{"class":1190},[208,3257,1762],{"class":214},[208,3259,3260],{"class":210,"line":228},[208,3261,3262],{"class":214},"    \u003C>\n",[208,3264,3265,3267,3270],{"class":210,"line":236},[208,3266,1790],{"class":214},[208,3268,3269],{"class":221},"Head",[208,3271,1784],{"class":214},[208,3273,3274,3276,3279,3282,3284],{"class":210,"line":252},[208,3275,2548],{"class":214},[208,3277,3278],{"class":1771},"html",[208,3280,3281],{"class":1215}," lang",[208,3283,1778],{"class":1190},[208,3285,3286],{"class":214},"{language} \u002F>\n",[208,3288,3289,3291,3294,3297,3299,3302,3305,3307,3310,3313,3315,3318],{"class":210,"line":261},[208,3290,2548],{"class":214},[208,3292,3293],{"class":1771},"link",[208,3295,3296],{"class":1215}," rel",[208,3298,1778],{"class":1190},[208,3300,3301],{"class":245},"\"alternate\"",[208,3303,3304],{"class":1215}," hrefLang",[208,3306,1778],{"class":1190},[208,3308,3309],{"class":245},"\"en\"",[208,3311,3312],{"class":1215}," href",[208,3314,1778],{"class":1190},[208,3316,3317],{"class":245},"\"https:\u002F\u002Fyourapp.com\u002Fen\"",[208,3319,3320],{"class":214}," \u002F>\n",[208,3322,3323,3325,3327,3329,3331,3333,3335,3337,3340,3342,3344,3347],{"class":210,"line":269},[208,3324,2548],{"class":214},[208,3326,3293],{"class":1771},[208,3328,3296],{"class":1215},[208,3330,1778],{"class":1190},[208,3332,3301],{"class":245},[208,3334,3304],{"class":1215},[208,3336,1778],{"class":1190},[208,3338,3339],{"class":245},"\"es\"",[208,3341,3312],{"class":1215},[208,3343,1778],{"class":1190},[208,3345,3346],{"class":245},"\"https:\u002F\u002Fyourapp.com\u002Fes\"",[208,3348,3320],{"class":214},[208,3350,3351,3353,3355,3357,3359,3361,3363,3365,3368,3370,3372,3375],{"class":210,"line":277},[208,3352,2548],{"class":214},[208,3354,3293],{"class":1771},[208,3356,3296],{"class":1215},[208,3358,1778],{"class":1190},[208,3360,3301],{"class":245},[208,3362,3304],{"class":1215},[208,3364,1778],{"class":1190},[208,3366,3367],{"class":245},"\"fr\"",[208,3369,3312],{"class":1215},[208,3371,1778],{"class":1190},[208,3373,3374],{"class":245},"\"https:\u002F\u002Fyourapp.com\u002Ffr\"",[208,3376,3320],{"class":214},[208,3378,3379,3382,3385],{"class":210,"line":283},[208,3380,3381],{"class":214},"        {",[208,3383,3384],{"class":2419},"\u002F* Add more language alternates *\u002F",[208,3386,304],{"class":214},[208,3388,3389,3391,3393],{"class":210,"line":289},[208,3390,1908],{"class":214},[208,3392,3269],{"class":221},[208,3394,1784],{"class":214},[208,3396,3397,3400,3403],{"class":210,"line":295},[208,3398,3399],{"class":214},"      {",[208,3401,3402],{"class":2419},"\u002F* Your content *\u002F",[208,3404,304],{"class":214},[208,3406,3407],{"class":210,"line":301},[208,3408,3409],{"class":214},"    \u003C\u002F>\n",[208,3411,3412],{"class":210,"line":1078},[208,3413,1130],{"class":214},[208,3415,3416],{"class":210,"line":1084},[208,3417,304],{"class":214},[21,3419,3421],{"id":3420},"best-practices","Best Practices",[693,3423,3424,3430,3436,3442,3448,3454,3460],{},[35,3425,3426,3429],{},[16,3427,3428],{},"Always provide a language selector"," - Don't force users into a language",[35,3431,3432,3435],{},[16,3433,3434],{},"Remember user preferences"," - Store language choice in localStorage or user profile",[35,3437,3438,3441],{},[16,3439,3440],{},"Use native language names"," - Display \"Español\" not \"Spanish\"",[35,3443,3444,3447],{},[16,3445,3446],{},"Test with native speakers"," - Automated translation isn't enough",[35,3449,3450,3453],{},[16,3451,3452],{},"Consider cultural differences"," - Images and colors have different meanings",[35,3455,3456,3459],{},[16,3457,3458],{},"Optimize for performance"," - Lazy load language resources",[35,3461,3462,3465],{},[16,3463,3464],{},"Handle fallbacks gracefully"," - Always have a default language",[21,3467,3469],{"id":3468},"performance-optimization","Performance Optimization",[12,3471,3472],{},"Cache news by language to reduce API calls:",[198,3474,3476],{"className":1013,"code":3475,"language":1015,"meta":203,"style":203},"class MultiLanguageNewsCache {\n  constructor() {\n    this.cache = new Map();\n    this.cacheDuration = 5 * 60 * 1000; \u002F\u002F 5 minutes\n  }\n  \n  getCacheKey(language, country, category) {\n    return `${language}-${country}-${category || 'all'}`;\n  }\n  \n  get(language, country, category) {\n    const key = this.getCacheKey(language, country, category);\n    const cached = this.cache.get(key);\n    \n    if (cached && Date.now() - cached.timestamp \u003C this.cacheDuration) {\n      return cached.data;\n    }\n    \n    return null;\n  }\n  \n  set(language, country, category, data) {\n    const key = this.getCacheKey(language, country, category);\n    this.cache.set(key, {\n      data,\n      timestamp: Date.now()\n    });\n  }\n}\n\nconst newsCache = new MultiLanguageNewsCache();\n",[205,3477,3478,3483,3488,3493,3498,3502,3506,3511,3516,3520,3524,3529,3534,3539,3544,3549,3554,3558,3562,3567,3571,3575,3580,3584,3589,3594,3599,3604,3608,3612,3616],{"__ignoreMap":203},[208,3479,3480],{"class":210,"line":211},[208,3481,3482],{},"class MultiLanguageNewsCache {\n",[208,3484,3485],{"class":210,"line":218},[208,3486,3487],{},"  constructor() {\n",[208,3489,3490],{"class":210,"line":228},[208,3491,3492],{},"    this.cache = new Map();\n",[208,3494,3495],{"class":210,"line":236},[208,3496,3497],{},"    this.cacheDuration = 5 * 60 * 1000; \u002F\u002F 5 minutes\n",[208,3499,3500],{"class":210,"line":252},[208,3501,298],{},[208,3503,3504],{"class":210,"line":261},[208,3505,1042],{},[208,3507,3508],{"class":210,"line":269},[208,3509,3510],{},"  getCacheKey(language, country, category) {\n",[208,3512,3513],{"class":210,"line":277},[208,3514,3515],{},"    return `${language}-${country}-${category || 'all'}`;\n",[208,3517,3518],{"class":210,"line":283},[208,3519,298],{},[208,3521,3522],{"class":210,"line":289},[208,3523,1042],{},[208,3525,3526],{"class":210,"line":295},[208,3527,3528],{},"  get(language, country, category) {\n",[208,3530,3531],{"class":210,"line":301},[208,3532,3533],{},"    const key = this.getCacheKey(language, country, category);\n",[208,3535,3536],{"class":210,"line":1078},[208,3537,3538],{},"    const cached = this.cache.get(key);\n",[208,3540,3541],{"class":210,"line":1084},[208,3542,3543],{},"    \n",[208,3545,3546],{"class":210,"line":1089},[208,3547,3548],{},"    if (cached && Date.now() - cached.timestamp \u003C this.cacheDuration) {\n",[208,3550,3551],{"class":210,"line":1095},[208,3552,3553],{},"      return cached.data;\n",[208,3555,3556],{"class":210,"line":1481},[208,3557,292],{},[208,3559,3560],{"class":210,"line":1501},[208,3561,3543],{},[208,3563,3564],{"class":210,"line":1521},[208,3565,3566],{},"    return null;\n",[208,3568,3569],{"class":210,"line":1541},[208,3570,298],{},[208,3572,3573],{"class":210,"line":1561},[208,3574,1042],{},[208,3576,3577],{"class":210,"line":1581},[208,3578,3579],{},"  set(language, country, category, data) {\n",[208,3581,3582],{"class":210,"line":1601},[208,3583,3533],{},[208,3585,3586],{"class":210,"line":1621},[208,3587,3588],{},"    this.cache.set(key, {\n",[208,3590,3591],{"class":210,"line":1641},[208,3592,3593],{},"      data,\n",[208,3595,3596],{"class":210,"line":1661},[208,3597,3598],{},"      timestamp: Date.now()\n",[208,3600,3601],{"class":210,"line":1682},[208,3602,3603],{},"    });\n",[208,3605,3606],{"class":210,"line":1688},[208,3607,298],{},[208,3609,3610],{"class":210,"line":1693},[208,3611,304],{},[208,3613,3614],{"class":210,"line":1718},[208,3615,1092],{"emptyLinePlaceholder":866},[208,3617,3618],{"class":210,"line":1736},[208,3619,3620],{},"const newsCache = new MultiLanguageNewsCache();\n",[21,3622,779],{"id":778},[12,3624,3625],{},"Building a multi-language news application opens your product to a global audience. With AllNewsAPI's comprehensive language support and the techniques outlined in this guide, you can create an engaging experience for users worldwide.",[12,3627,3628,3629,3632],{},"Ready to go global? ",[182,3630,3631],{"href":184},"Start building with AllNewsAPI"," today!",[21,3634,719],{"id":718},[32,3636,3637,3642,3648],{},[35,3638,3639],{},[182,3640,3641],{"href":741},"AllNewsAPI Documentation",[35,3643,3644],{},[182,3645,3647],{"href":3646},"\u002Fcountries","Supported Languages and Countries",[35,3649,3650],{},[182,3651,3654],{"href":3652,"rel":3653},"https:\u002F\u002Fwww.i18next.com\u002F",[732],"i18next Documentation",[825,3656,3657],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":203,"searchDepth":218,"depth":218,"links":3659},[3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674],{"id":883,"depth":218,"text":884},{"id":904,"depth":218,"text":905},{"id":979,"depth":218,"text":980},{"id":1006,"depth":218,"text":1007},{"id":1101,"depth":218,"text":1102},{"id":1174,"depth":218,"text":1175},{"id":1952,"depth":218,"text":1953},{"id":2658,"depth":218,"text":2659},{"id":2841,"depth":218,"text":2842},{"id":2925,"depth":218,"text":2926},{"id":3224,"depth":218,"text":3225},{"id":3420,"depth":218,"text":3421},{"id":3468,"depth":218,"text":3469},{"id":778,"depth":218,"text":779},{"id":718,"depth":218,"text":719},"2025-11-05","Learn how to create news applications that serve content in multiple languages and regions using AllNewsAPI","\u002Fblog\u002Fbuilding-multi-language-news-applications.webp",{},"\u002Fblog\u002Fmulti-language-news-apps",{"title":875,"description":3676},{"loc":3679},"blog\u002Fmulti-language-news-apps","tutorial","wd-NEQiHy9myXlHH3vF_yhAcIQZt_oziwPu3Q8qYpsI",{"id":3686,"title":3687,"author":7,"body":3688,"date":6693,"description":6694,"draft":862,"extension":863,"image":6695,"meta":6696,"navigation":866,"path":6697,"seo":6698,"sitemap":6699,"stem":6700,"tags":3683,"__hash__":6701},"blog\u002Fblog\u002Fbuilding-news-aggregator-app.md","Building a News Aggregator App with AllNewsAPI",{"type":9,"value":3689,"toc":6679},[3690,3693,3697,3700,3717,3719,3722,3733,3737,3740,3782,3785,3802,3806,3812,3991,3995,4001,4367,4371,4376,5042,5046,5052,6260,6264,6270,6597,6601,6608,6614,6618,6633,6640,6644,6647,6664,6666,6669,6676],[12,3691,3692],{},"In this tutorial, we'll build a complete news aggregator application using AllNewsAPI and React. By the end, you'll have a fully functional app that displays news from multiple countries and categories.",[21,3694,3696],{"id":3695},"what-well-build","What We'll Build",[12,3698,3699],{},"Our news aggregator will feature:",[32,3701,3702,3705,3708,3711,3714],{},[35,3703,3704],{},"Country-based news filtering (244 countries supported)",[35,3706,3707],{},"Category selection (business, technology, sports, entertainment, and more)",[35,3709,3710],{},"Search functionality",[35,3712,3713],{},"Responsive design",[35,3715,3716],{},"Real-time updates",[21,3718,172],{"id":171},[12,3720,3721],{},"Before we start, make sure you have:",[32,3723,3724,3727,3730],{},[35,3725,3726],{},"Node.js installed (v16 or higher)",[35,3728,3729],{},"An AllNewsAPI account and API key",[35,3731,3732],{},"Basic knowledge of React and JavaScript",[21,3734,3736],{"id":3735},"step-1-project-setup","Step 1: Project Setup",[12,3738,3739],{},"Create a new React app using Vite:",[198,3741,3743],{"className":1963,"code":3742,"language":1965,"meta":203,"style":203},"npm create vite@latest news-aggregator -- --template react\ncd news-aggregator\nnpm install\n",[205,3744,3745,3767,3775],{"__ignoreMap":203},[208,3746,3747,3749,3752,3755,3758,3761,3764],{"class":210,"line":211},[208,3748,1972],{"class":1215},[208,3750,3751],{"class":245}," create",[208,3753,3754],{"class":245}," vite@latest",[208,3756,3757],{"class":245}," news-aggregator",[208,3759,3760],{"class":221}," --",[208,3762,3763],{"class":221}," --template",[208,3765,3766],{"class":245}," react\n",[208,3768,3769,3772],{"class":210,"line":218},[208,3770,3771],{"class":221},"cd",[208,3773,3774],{"class":245}," news-aggregator\n",[208,3776,3777,3779],{"class":210,"line":228},[208,3778,1972],{"class":1215},[208,3780,3781],{"class":245}," install\n",[12,3783,3784],{},"Install additional dependencies:",[198,3786,3788],{"className":1963,"code":3787,"language":1965,"meta":203,"style":203},"npm install axios date-fns\n",[205,3789,3790],{"__ignoreMap":203},[208,3791,3792,3794,3796,3799],{"class":210,"line":211},[208,3793,1972],{"class":1215},[208,3795,1975],{"class":245},[208,3797,3798],{"class":245}," axios",[208,3800,3801],{"class":245}," date-fns\n",[21,3803,3805],{"id":3804},"step-2-create-the-api-service","Step 2: Create the API Service",[12,3807,3808,3809,2573],{},"Create a file ",[205,3810,3811],{},"src\u002Fservices\u002FnewsApi.js",[198,3813,3815],{"className":1013,"code":3814,"language":1015,"meta":203,"style":203},"import axios from 'axios';\n\nconst API_KEY = import.meta.env.VITE_NEWS_API_KEY;\nconst BASE_URL = 'https:\u002F\u002Fapi.allnewsapi.com';\n\nconst newsApi = axios.create({\n  baseURL: BASE_URL,\n  params: {\n    apikey: API_KEY\n  }\n});\n\nexport const getHeadlines = async (country = 'us', category = null) => {\n  try {\n    const params = { country };\n    if (category) params.category = category;\n    \n    const response = await newsApi.get('\u002Fheadlines', { params });\n    return response.data;\n  } catch (error) {\n    console.error('Error fetching headlines:', error);\n    throw error;\n  }\n};\n\nexport const searchNews = async (query, country = 'us') => {\n  try {\n    const response = await newsApi.get('\u002Fheadlines', {\n      params: { q: query, country }\n    });\n    return response.data;\n  } catch (error) {\n    console.error('Error searching news:', error);\n    throw error;\n  }\n};\n\nexport default newsApi;\n",[205,3816,3817,3822,3826,3831,3836,3840,3845,3850,3855,3860,3864,3869,3873,3878,3883,3888,3893,3897,3902,3907,3912,3917,3922,3926,3930,3934,3939,3943,3948,3953,3957,3961,3965,3970,3974,3978,3982,3986],{"__ignoreMap":203},[208,3818,3819],{"class":210,"line":211},[208,3820,3821],{},"import axios from 'axios';\n",[208,3823,3824],{"class":210,"line":218},[208,3825,1092],{"emptyLinePlaceholder":866},[208,3827,3828],{"class":210,"line":228},[208,3829,3830],{},"const API_KEY = import.meta.env.VITE_NEWS_API_KEY;\n",[208,3832,3833],{"class":210,"line":236},[208,3834,3835],{},"const BASE_URL = 'https:\u002F\u002Fapi.allnewsapi.com';\n",[208,3837,3838],{"class":210,"line":252},[208,3839,1092],{"emptyLinePlaceholder":866},[208,3841,3842],{"class":210,"line":261},[208,3843,3844],{},"const newsApi = axios.create({\n",[208,3846,3847],{"class":210,"line":269},[208,3848,3849],{},"  baseURL: BASE_URL,\n",[208,3851,3852],{"class":210,"line":277},[208,3853,3854],{},"  params: {\n",[208,3856,3857],{"class":210,"line":283},[208,3858,3859],{},"    apikey: API_KEY\n",[208,3861,3862],{"class":210,"line":289},[208,3863,298],{},[208,3865,3866],{"class":210,"line":295},[208,3867,3868],{},"});\n",[208,3870,3871],{"class":210,"line":301},[208,3872,1092],{"emptyLinePlaceholder":866},[208,3874,3875],{"class":210,"line":1078},[208,3876,3877],{},"export const getHeadlines = async (country = 'us', category = null) => {\n",[208,3879,3880],{"class":210,"line":1084},[208,3881,3882],{},"  try {\n",[208,3884,3885],{"class":210,"line":1089},[208,3886,3887],{},"    const params = { country };\n",[208,3889,3890],{"class":210,"line":1095},[208,3891,3892],{},"    if (category) params.category = category;\n",[208,3894,3895],{"class":210,"line":1481},[208,3896,3543],{},[208,3898,3899],{"class":210,"line":1501},[208,3900,3901],{},"    const response = await newsApi.get('\u002Fheadlines', { params });\n",[208,3903,3904],{"class":210,"line":1521},[208,3905,3906],{},"    return response.data;\n",[208,3908,3909],{"class":210,"line":1541},[208,3910,3911],{},"  } catch (error) {\n",[208,3913,3914],{"class":210,"line":1561},[208,3915,3916],{},"    console.error('Error fetching headlines:', error);\n",[208,3918,3919],{"class":210,"line":1581},[208,3920,3921],{},"    throw error;\n",[208,3923,3924],{"class":210,"line":1601},[208,3925,298],{},[208,3927,3928],{"class":210,"line":1621},[208,3929,2193],{},[208,3931,3932],{"class":210,"line":1641},[208,3933,1092],{"emptyLinePlaceholder":866},[208,3935,3936],{"class":210,"line":1661},[208,3937,3938],{},"export const searchNews = async (query, country = 'us') => {\n",[208,3940,3941],{"class":210,"line":1682},[208,3942,3882],{},[208,3944,3945],{"class":210,"line":1688},[208,3946,3947],{},"    const response = await newsApi.get('\u002Fheadlines', {\n",[208,3949,3950],{"class":210,"line":1693},[208,3951,3952],{},"      params: { q: query, country }\n",[208,3954,3955],{"class":210,"line":1718},[208,3956,3603],{},[208,3958,3959],{"class":210,"line":1736},[208,3960,3906],{},[208,3962,3963],{"class":210,"line":1745},[208,3964,3911],{},[208,3966,3967],{"class":210,"line":1751},[208,3968,3969],{},"    console.error('Error searching news:', error);\n",[208,3971,3972],{"class":210,"line":1756},[208,3973,3921],{},[208,3975,3976],{"class":210,"line":1765},[208,3977,298],{},[208,3979,3980],{"class":210,"line":1787},[208,3981,2193],{},[208,3983,3984],{"class":210,"line":1799},[208,3985,1092],{"emptyLinePlaceholder":866},[208,3987,3988],{"class":210,"line":1810},[208,3989,3990],{},"export default newsApi;\n",[21,3992,3994],{"id":3993},"step-3-create-the-news-card-component","Step 3: Create the News Card Component",[12,3996,3997,3998,2573],{},"Create ",[205,3999,4000],{},"src\u002Fcomponents\u002FNewsCard.jsx",[198,4002,4004],{"className":1181,"code":4003,"language":1183,"meta":203,"style":203},"import { formatDistanceToNow } from 'date-fns';\n\nfunction NewsCard({ article }) {\n  return (\n    \u003Cdiv className=\"news-card\">\n      {article.image && (\n        \u003Cimg \n          src={article.image} \n          alt={article.title}\n          className=\"news-card__image\"\n        \u002F>\n      )}\n      \u003Cdiv className=\"news-card__content\">\n        \u003Ch3 className=\"news-card__title\">{article.title}\u003C\u002Fh3>\n        \u003Cp className=\"news-card__description\">{article.description}\u003C\u002Fp>\n        \u003Cdiv className=\"news-card__meta\">\n          \u003Cspan className=\"news-card__source\">{article.source.name}\u003C\u002Fspan>\n          \u003Cspan className=\"news-card__time\">\n            {formatDistanceToNow(new Date(article.publishedAt), { addSuffix: true })}\n          \u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Ca \n          href={article.url} \n          target=\"_blank\" \n          rel=\"noopener noreferrer\"\n          className=\"news-card__link\"\n        >\n          Read More →\n        \u003C\u002Fa>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  );\n}\n\nexport default NewsCard;\n",[205,4005,4006,4020,4024,4038,4044,4059,4069,4078,4088,4098,4108,4113,4117,4132,4152,4172,4187,4207,4222,4246,4254,4263,4271,4281,4293,4303,4312,4317,4322,4330,4338,4346,4350,4354,4358],{"__ignoreMap":203},[208,4007,4008,4010,4013,4015,4018],{"class":210,"line":211},[208,4009,1191],{"class":1190},[208,4011,4012],{"class":214}," { formatDistanceToNow } ",[208,4014,1197],{"class":1190},[208,4016,4017],{"class":245}," 'date-fns'",[208,4019,1203],{"class":214},[208,4021,4022],{"class":210,"line":218},[208,4023,1092],{"emptyLinePlaceholder":866},[208,4025,4026,4028,4031,4033,4036],{"class":210,"line":228},[208,4027,1212],{"class":1190},[208,4029,4030],{"class":1215}," NewsCard",[208,4032,1219],{"class":214},[208,4034,4035],{"class":1222},"article",[208,4037,1232],{"class":214},[208,4039,4040,4042],{"class":210,"line":236},[208,4041,1759],{"class":1190},[208,4043,1762],{"class":214},[208,4045,4046,4048,4050,4052,4054,4057],{"class":210,"line":252},[208,4047,1768],{"class":214},[208,4049,1772],{"class":1771},[208,4051,1775],{"class":1215},[208,4053,1778],{"class":1190},[208,4055,4056],{"class":245},"\"news-card\"",[208,4058,1784],{"class":214},[208,4060,4061,4064,4067],{"class":210,"line":261},[208,4062,4063],{"class":214},"      {article.image ",[208,4065,4066],{"class":1190},"&&",[208,4068,1762],{"class":214},[208,4070,4071,4073,4076],{"class":210,"line":269},[208,4072,2548],{"class":214},[208,4074,4075],{"class":1771},"img",[208,4077,1796],{"class":214},[208,4079,4080,4083,4085],{"class":210,"line":277},[208,4081,4082],{"class":1215},"          src",[208,4084,1778],{"class":1190},[208,4086,4087],{"class":214},"{article.image} \n",[208,4089,4090,4093,4095],{"class":210,"line":283},[208,4091,4092],{"class":1215},"          alt",[208,4094,1778],{"class":1190},[208,4096,4097],{"class":214},"{article.title}\n",[208,4099,4100,4103,4105],{"class":210,"line":289},[208,4101,4102],{"class":1215},"          className",[208,4104,1778],{"class":1190},[208,4106,4107],{"class":245},"\"news-card__image\"\n",[208,4109,4110],{"class":210,"line":295},[208,4111,4112],{"class":214},"        \u002F>\n",[208,4114,4115],{"class":210,"line":301},[208,4116,2639],{"class":214},[208,4118,4119,4121,4123,4125,4127,4130],{"class":210,"line":1078},[208,4120,1790],{"class":214},[208,4122,1772],{"class":1771},[208,4124,1775],{"class":1215},[208,4126,1778],{"class":1190},[208,4128,4129],{"class":245},"\"news-card__content\"",[208,4131,1784],{"class":214},[208,4133,4134,4136,4138,4140,4142,4145,4148,4150],{"class":210,"line":1084},[208,4135,2548],{"class":214},[208,4137,94],{"class":1771},[208,4139,1775],{"class":1215},[208,4141,1778],{"class":1190},[208,4143,4144],{"class":245},"\"news-card__title\"",[208,4146,4147],{"class":214},">{article.title}\u003C\u002F",[208,4149,94],{"class":1771},[208,4151,1784],{"class":214},[208,4153,4154,4156,4158,4160,4162,4165,4168,4170],{"class":210,"line":1089},[208,4155,2548],{"class":214},[208,4157,12],{"class":1771},[208,4159,1775],{"class":1215},[208,4161,1778],{"class":1190},[208,4163,4164],{"class":245},"\"news-card__description\"",[208,4166,4167],{"class":214},">{article.description}\u003C\u002F",[208,4169,12],{"class":1771},[208,4171,1784],{"class":214},[208,4173,4174,4176,4178,4180,4182,4185],{"class":210,"line":1095},[208,4175,2548],{"class":214},[208,4177,1772],{"class":1771},[208,4179,1775],{"class":1215},[208,4181,1778],{"class":1190},[208,4183,4184],{"class":245},"\"news-card__meta\"",[208,4186,1784],{"class":214},[208,4188,4189,4191,4193,4195,4197,4200,4203,4205],{"class":210,"line":1481},[208,4190,1861],{"class":214},[208,4192,208],{"class":1771},[208,4194,1775],{"class":1215},[208,4196,1778],{"class":1190},[208,4198,4199],{"class":245},"\"news-card__source\"",[208,4201,4202],{"class":214},">{article.source.name}\u003C\u002F",[208,4204,208],{"class":1771},[208,4206,1784],{"class":214},[208,4208,4209,4211,4213,4215,4217,4220],{"class":210,"line":1501},[208,4210,1861],{"class":214},[208,4212,208],{"class":1771},[208,4214,1775],{"class":1215},[208,4216,1778],{"class":1190},[208,4218,4219],{"class":245},"\"news-card__time\"",[208,4221,1784],{"class":214},[208,4223,4224,4227,4230,4232,4235,4238,4241,4243],{"class":210,"line":1521},[208,4225,4226],{"class":214},"            {",[208,4228,4229],{"class":1215},"formatDistanceToNow",[208,4231,1727],{"class":214},[208,4233,4234],{"class":1190},"new",[208,4236,4237],{"class":1215}," Date",[208,4239,4240],{"class":214},"(article.publishedAt), { addSuffix: ",[208,4242,2374],{"class":221},[208,4244,4245],{"class":214}," })}\n",[208,4247,4248,4250,4252],{"class":210,"line":1541},[208,4249,1892],{"class":214},[208,4251,208],{"class":1771},[208,4253,1784],{"class":214},[208,4255,4256,4259,4261],{"class":210,"line":1561},[208,4257,4258],{"class":214},"        \u003C\u002F",[208,4260,1772],{"class":1771},[208,4262,1784],{"class":214},[208,4264,4265,4267,4269],{"class":210,"line":1581},[208,4266,2548],{"class":214},[208,4268,182],{"class":1771},[208,4270,1796],{"class":214},[208,4272,4273,4276,4278],{"class":210,"line":1601},[208,4274,4275],{"class":1215},"          href",[208,4277,1778],{"class":1190},[208,4279,4280],{"class":214},"{article.url} \n",[208,4282,4283,4286,4288,4291],{"class":210,"line":1621},[208,4284,4285],{"class":1215},"          target",[208,4287,1778],{"class":1190},[208,4289,4290],{"class":245},"\"_blank\"",[208,4292,1796],{"class":214},[208,4294,4295,4298,4300],{"class":210,"line":1641},[208,4296,4297],{"class":1215},"          rel",[208,4299,1778],{"class":1190},[208,4301,4302],{"class":245},"\"noopener noreferrer\"\n",[208,4304,4305,4307,4309],{"class":210,"line":1661},[208,4306,4102],{"class":1215},[208,4308,1778],{"class":1190},[208,4310,4311],{"class":245},"\"news-card__link\"\n",[208,4313,4314],{"class":210,"line":1682},[208,4315,4316],{"class":214},"        >\n",[208,4318,4319],{"class":210,"line":1688},[208,4320,4321],{"class":214},"          Read More →\n",[208,4323,4324,4326,4328],{"class":210,"line":1693},[208,4325,4258],{"class":214},[208,4327,182],{"class":1771},[208,4329,1784],{"class":214},[208,4331,4332,4334,4336],{"class":210,"line":1718},[208,4333,1908],{"class":214},[208,4335,1772],{"class":1771},[208,4337,1784],{"class":214},[208,4339,4340,4342,4344],{"class":210,"line":1736},[208,4341,1918],{"class":214},[208,4343,1772],{"class":1771},[208,4345,1784],{"class":214},[208,4347,4348],{"class":210,"line":1745},[208,4349,1130],{"class":214},[208,4351,4352],{"class":210,"line":1751},[208,4353,304],{"class":214},[208,4355,4356],{"class":210,"line":1756},[208,4357,1092],{"emptyLinePlaceholder":866},[208,4359,4360,4362,4364],{"class":210,"line":1765},[208,4361,1943],{"class":1190},[208,4363,1946],{"class":1190},[208,4365,4366],{"class":214}," NewsCard;\n",[21,4368,4370],{"id":4369},"step-4-create-the-filter-component","Step 4: Create the Filter Component",[12,4372,3997,4373,2573],{},[205,4374,4375],{},"src\u002Fcomponents\u002FFilters.jsx",[198,4377,4379],{"className":1181,"code":4378,"language":1183,"meta":203,"style":203},"function Filters({ country, category, onCountryChange, onCategoryChange }) {\n  const countries = [\n    { code: 'us', name: 'United States' },\n    { code: 'gb', name: 'United Kingdom' },\n    { code: 'ca', name: 'Canada' },\n    { code: 'au', name: 'Australia' },\n    { code: 'de', name: 'Germany' },\n    { code: 'fr', name: 'France' },\n    { code: 'jp', name: 'Japan' }\n  ];\n\n  const categories = [\n    'business',\n    'entertainment',\n    'finance',\n    'food',\n    'health',\n    'politics',\n    'science',\n    'sports',\n    'technology',\n    'world'\n  ];\n\n  return (\n    \u003Cdiv className=\"filters\">\n      \u003Cdiv className=\"filter-group\">\n        \u003Clabel htmlFor=\"country\">Country:\u003C\u002Flabel>\n        \u003Cselect \n          id=\"country\"\n          value={country} \n          onChange={(e) => onCountryChange(e.target.value)}\n        >\n          {countries.map(c => (\n            \u003Coption key={c.code} value={c.code}>{c.name}\u003C\u002Foption>\n          ))}\n        \u003C\u002Fselect>\n      \u003C\u002Fdiv>\n\n      \u003Cdiv className=\"filter-group\">\n        \u003Clabel htmlFor=\"category\">Category:\u003C\u002Flabel>\n        \u003Cselect \n          id=\"category\"\n          value={category || ''} \n          onChange={(e) => onCategoryChange(e.target.value || null)}\n        >\n          \u003Coption value=\"\">All Categories\u003C\u002Foption>\n          {categories.map(cat => (\n            \u003Coption key={cat} value={cat}>\n              {cat.charAt(0).toUpperCase() + cat.slice(1)}\n            \u003C\u002Foption>\n          ))}\n        \u003C\u002Fselect>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  );\n}\n\nexport default Filters;\n",[205,4380,4381,4410,4421,4435,4449,4463,4477,4490,4503,4517,4521,4525,4536,4543,4550,4557,4564,4571,4578,4585,4592,4599,4604,4608,4612,4618,4633,4648,4670,4678,4688,4698,4718,4722,4738,4763,4768,4776,4784,4788,4802,4822,4830,4839,4857,4885,4889,4910,4926,4946,4983,4992,4996,5004,5012,5020,5024,5028,5032],{"__ignoreMap":203},[208,4382,4383,4385,4388,4390,4393,4395,4398,4400,4403,4405,4408],{"class":210,"line":211},[208,4384,1212],{"class":1190},[208,4386,4387],{"class":1215}," Filters",[208,4389,1219],{"class":214},[208,4391,4392],{"class":1222},"country",[208,4394,1226],{"class":214},[208,4396,4397],{"class":1222},"category",[208,4399,1226],{"class":214},[208,4401,4402],{"class":1222},"onCountryChange",[208,4404,1226],{"class":214},[208,4406,4407],{"class":1222},"onCategoryChange",[208,4409,1232],{"class":214},[208,4411,4412,4414,4417,4419],{"class":210,"line":218},[208,4413,1237],{"class":1190},[208,4415,4416],{"class":221}," countries",[208,4418,1243],{"class":1190},[208,4420,1246],{"class":214},[208,4422,4423,4425,4428,4430,4433],{"class":210,"line":228},[208,4424,1251],{"class":214},[208,4426,4427],{"class":245},"'us'",[208,4429,1257],{"class":214},[208,4431,4432],{"class":245},"'United States'",[208,4434,1269],{"class":214},[208,4436,4437,4439,4442,4444,4447],{"class":210,"line":236},[208,4438,1251],{"class":214},[208,4440,4441],{"class":245},"'gb'",[208,4443,1257],{"class":214},[208,4445,4446],{"class":245},"'United Kingdom'",[208,4448,1269],{"class":214},[208,4450,4451,4453,4456,4458,4461],{"class":210,"line":252},[208,4452,1251],{"class":214},[208,4454,4455],{"class":245},"'ca'",[208,4457,1257],{"class":214},[208,4459,4460],{"class":245},"'Canada'",[208,4462,1269],{"class":214},[208,4464,4465,4467,4470,4472,4475],{"class":210,"line":261},[208,4466,1251],{"class":214},[208,4468,4469],{"class":245},"'au'",[208,4471,1257],{"class":214},[208,4473,4474],{"class":245},"'Australia'",[208,4476,1269],{"class":214},[208,4478,4479,4481,4483,4485,4488],{"class":210,"line":269},[208,4480,1251],{"class":214},[208,4482,1314],{"class":245},[208,4484,1257],{"class":214},[208,4486,4487],{"class":245},"'Germany'",[208,4489,1269],{"class":214},[208,4491,4492,4494,4496,4498,4501],{"class":210,"line":277},[208,4493,1251],{"class":214},[208,4495,1295],{"class":245},[208,4497,1257],{"class":214},[208,4499,4500],{"class":245},"'France'",[208,4502,1269],{"class":214},[208,4504,4505,4507,4510,4512,4515],{"class":210,"line":283},[208,4506,1251],{"class":214},[208,4508,4509],{"class":245},"'jp'",[208,4511,1257],{"class":214},[208,4513,4514],{"class":245},"'Japan'",[208,4516,1679],{"class":214},[208,4518,4519],{"class":210,"line":289},[208,4520,1685],{"class":214},[208,4522,4523],{"class":210,"line":295},[208,4524,1092],{"emptyLinePlaceholder":866},[208,4526,4527,4529,4532,4534],{"class":210,"line":301},[208,4528,1237],{"class":1190},[208,4530,4531],{"class":221}," categories",[208,4533,1243],{"class":1190},[208,4535,1246],{"class":214},[208,4537,4538,4541],{"class":210,"line":1078},[208,4539,4540],{"class":245},"    'business'",[208,4542,249],{"class":214},[208,4544,4545,4548],{"class":210,"line":1084},[208,4546,4547],{"class":245},"    'entertainment'",[208,4549,249],{"class":214},[208,4551,4552,4555],{"class":210,"line":1089},[208,4553,4554],{"class":245},"    'finance'",[208,4556,249],{"class":214},[208,4558,4559,4562],{"class":210,"line":1095},[208,4560,4561],{"class":245},"    'food'",[208,4563,249],{"class":214},[208,4565,4566,4569],{"class":210,"line":1481},[208,4567,4568],{"class":245},"    'health'",[208,4570,249],{"class":214},[208,4572,4573,4576],{"class":210,"line":1501},[208,4574,4575],{"class":245},"    'politics'",[208,4577,249],{"class":214},[208,4579,4580,4583],{"class":210,"line":1521},[208,4581,4582],{"class":245},"    'science'",[208,4584,249],{"class":214},[208,4586,4587,4590],{"class":210,"line":1541},[208,4588,4589],{"class":245},"    'sports'",[208,4591,249],{"class":214},[208,4593,4594,4597],{"class":210,"line":1561},[208,4595,4596],{"class":245},"    'technology'",[208,4598,249],{"class":214},[208,4600,4601],{"class":210,"line":1581},[208,4602,4603],{"class":245},"    'world'\n",[208,4605,4606],{"class":210,"line":1601},[208,4607,1685],{"class":214},[208,4609,4610],{"class":210,"line":1621},[208,4611,1092],{"emptyLinePlaceholder":866},[208,4613,4614,4616],{"class":210,"line":1641},[208,4615,1759],{"class":1190},[208,4617,1762],{"class":214},[208,4619,4620,4622,4624,4626,4628,4631],{"class":210,"line":1661},[208,4621,1768],{"class":214},[208,4623,1772],{"class":1771},[208,4625,1775],{"class":1215},[208,4627,1778],{"class":1190},[208,4629,4630],{"class":245},"\"filters\"",[208,4632,1784],{"class":214},[208,4634,4635,4637,4639,4641,4643,4646],{"class":210,"line":1682},[208,4636,1790],{"class":214},[208,4638,1772],{"class":1771},[208,4640,1775],{"class":1215},[208,4642,1778],{"class":1190},[208,4644,4645],{"class":245},"\"filter-group\"",[208,4647,1784],{"class":214},[208,4649,4650,4652,4655,4658,4660,4663,4666,4668],{"class":210,"line":1688},[208,4651,2548],{"class":214},[208,4653,4654],{"class":1771},"label",[208,4656,4657],{"class":1215}," htmlFor",[208,4659,1778],{"class":1190},[208,4661,4662],{"class":245},"\"country\"",[208,4664,4665],{"class":214},">Country:\u003C\u002F",[208,4667,4654],{"class":1771},[208,4669,1784],{"class":214},[208,4671,4672,4674,4676],{"class":210,"line":1693},[208,4673,2548],{"class":214},[208,4675,1793],{"class":1771},[208,4677,1796],{"class":214},[208,4679,4680,4683,4685],{"class":210,"line":1718},[208,4681,4682],{"class":1215},"          id",[208,4684,1778],{"class":1190},[208,4686,4687],{"class":245},"\"country\"\n",[208,4689,4690,4693,4695],{"class":210,"line":1736},[208,4691,4692],{"class":1215},"          value",[208,4694,1778],{"class":1190},[208,4696,4697],{"class":214},"{country} \n",[208,4699,4700,4703,4705,4707,4709,4711,4713,4716],{"class":210,"line":1745},[208,4701,4702],{"class":1215},"          onChange",[208,4704,1778],{"class":1190},[208,4706,1818],{"class":214},[208,4708,1821],{"class":1222},[208,4710,1709],{"class":214},[208,4712,1712],{"class":1190},[208,4714,4715],{"class":1215}," onCountryChange",[208,4717,1830],{"class":214},[208,4719,4720],{"class":210,"line":1751},[208,4721,4316],{"class":214},[208,4723,4724,4727,4729,4731,4734,4736],{"class":210,"line":1756},[208,4725,4726],{"class":214},"          {countries.",[208,4728,1845],{"class":1215},[208,4730,1727],{"class":214},[208,4732,4733],{"class":1222},"c",[208,4735,1853],{"class":1190},[208,4737,1762],{"class":214},[208,4739,4740,4743,4745,4747,4749,4752,4754,4756,4759,4761],{"class":210,"line":1765},[208,4741,4742],{"class":214},"            \u003C",[208,4744,1864],{"class":1771},[208,4746,1867],{"class":1215},[208,4748,1778],{"class":1190},[208,4750,4751],{"class":214},"{c.code} ",[208,4753,1875],{"class":1215},[208,4755,1778],{"class":1190},[208,4757,4758],{"class":214},"{c.code}>{c.name}\u003C\u002F",[208,4760,1864],{"class":1771},[208,4762,1784],{"class":214},[208,4764,4765],{"class":210,"line":1787},[208,4766,4767],{"class":214},"          ))}\n",[208,4769,4770,4772,4774],{"class":210,"line":1799},[208,4771,4258],{"class":214},[208,4773,1793],{"class":1771},[208,4775,1784],{"class":214},[208,4777,4778,4780,4782],{"class":210,"line":1810},[208,4779,1908],{"class":214},[208,4781,1772],{"class":1771},[208,4783,1784],{"class":214},[208,4785,4786],{"class":210,"line":1833},[208,4787,1092],{"emptyLinePlaceholder":866},[208,4789,4790,4792,4794,4796,4798,4800],{"class":210,"line":1839},[208,4791,1790],{"class":214},[208,4793,1772],{"class":1771},[208,4795,1775],{"class":1215},[208,4797,1778],{"class":1190},[208,4799,4645],{"class":245},[208,4801,1784],{"class":214},[208,4803,4804,4806,4808,4810,4812,4815,4818,4820],{"class":210,"line":1858},[208,4805,2548],{"class":214},[208,4807,4654],{"class":1771},[208,4809,4657],{"class":1215},[208,4811,1778],{"class":1190},[208,4813,4814],{"class":245},"\"category\"",[208,4816,4817],{"class":214},">Category:\u003C\u002F",[208,4819,4654],{"class":1771},[208,4821,1784],{"class":214},[208,4823,4824,4826,4828],{"class":210,"line":1883},[208,4825,2548],{"class":214},[208,4827,1793],{"class":1771},[208,4829,1796],{"class":214},[208,4831,4832,4834,4836],{"class":210,"line":1889},[208,4833,4682],{"class":1215},[208,4835,1778],{"class":1190},[208,4837,4838],{"class":245},"\"category\"\n",[208,4840,4841,4843,4845,4848,4851,4854],{"class":210,"line":1899},[208,4842,4692],{"class":1215},[208,4844,1778],{"class":1190},[208,4846,4847],{"class":214},"{category ",[208,4849,4850],{"class":1190},"||",[208,4852,4853],{"class":245}," ''",[208,4855,4856],{"class":214},"} \n",[208,4858,4859,4861,4863,4865,4867,4869,4871,4874,4877,4879,4882],{"class":210,"line":1905},[208,4860,4702],{"class":1215},[208,4862,1778],{"class":1190},[208,4864,1818],{"class":214},[208,4866,1821],{"class":1222},[208,4868,1709],{"class":214},[208,4870,1712],{"class":1190},[208,4872,4873],{"class":1215}," onCategoryChange",[208,4875,4876],{"class":214},"(e.target.value ",[208,4878,4850],{"class":1190},[208,4880,4881],{"class":221}," null",[208,4883,4884],{"class":214},")}\n",[208,4886,4887],{"class":210,"line":1915},[208,4888,4316],{"class":214},[208,4890,4891,4893,4895,4898,4900,4903,4906,4908],{"class":210,"line":1925},[208,4892,1861],{"class":214},[208,4894,1864],{"class":1771},[208,4896,4897],{"class":1215}," value",[208,4899,1778],{"class":1190},[208,4901,4902],{"class":245},"\"\"",[208,4904,4905],{"class":214},">All Categories\u003C\u002F",[208,4907,1864],{"class":1771},[208,4909,1784],{"class":214},[208,4911,4912,4915,4917,4919,4922,4924],{"class":210,"line":1930},[208,4913,4914],{"class":214},"          {categories.",[208,4916,1845],{"class":1215},[208,4918,1727],{"class":214},[208,4920,4921],{"class":1222},"cat",[208,4923,1853],{"class":1190},[208,4925,1762],{"class":214},[208,4927,4928,4930,4932,4934,4936,4939,4941,4943],{"class":210,"line":1935},[208,4929,4742],{"class":214},[208,4931,1864],{"class":1771},[208,4933,1867],{"class":1215},[208,4935,1778],{"class":1190},[208,4937,4938],{"class":214},"{cat} ",[208,4940,1875],{"class":1215},[208,4942,1778],{"class":1190},[208,4944,4945],{"class":214},"{cat}>\n",[208,4947,4948,4951,4954,4956,4958,4961,4964,4967,4970,4973,4976,4978,4981],{"class":210,"line":1940},[208,4949,4950],{"class":214},"              {cat.",[208,4952,4953],{"class":1215},"charAt",[208,4955,1727],{"class":214},[208,4957,2784],{"class":221},[208,4959,4960],{"class":214},").",[208,4962,4963],{"class":1215},"toUpperCase",[208,4965,4966],{"class":214},"() ",[208,4968,4969],{"class":1190},"+",[208,4971,4972],{"class":214}," cat.",[208,4974,4975],{"class":1215},"slice",[208,4977,1727],{"class":214},[208,4979,4980],{"class":221},"1",[208,4982,4884],{"class":214},[208,4984,4985,4988,4990],{"class":210,"line":2230},[208,4986,4987],{"class":214},"            \u003C\u002F",[208,4989,1864],{"class":1771},[208,4991,1784],{"class":214},[208,4993,4994],{"class":210,"line":2236},[208,4995,4767],{"class":214},[208,4997,4998,5000,5002],{"class":210,"line":2242},[208,4999,4258],{"class":214},[208,5001,1793],{"class":1771},[208,5003,1784],{"class":214},[208,5005,5006,5008,5010],{"class":210,"line":2247},[208,5007,1908],{"class":214},[208,5009,1772],{"class":1771},[208,5011,1784],{"class":214},[208,5013,5014,5016,5018],{"class":210,"line":2253},[208,5015,1918],{"class":214},[208,5017,1772],{"class":1771},[208,5019,1784],{"class":214},[208,5021,5022],{"class":210,"line":2258},[208,5023,1130],{"class":214},[208,5025,5026],{"class":210,"line":3213},[208,5027,304],{"class":214},[208,5029,5030],{"class":210,"line":3219},[208,5031,1092],{"emptyLinePlaceholder":866},[208,5033,5035,5037,5039],{"class":210,"line":5034},59,[208,5036,1943],{"class":1190},[208,5038,1946],{"class":1190},[208,5040,5041],{"class":214}," Filters;\n",[21,5043,5045],{"id":5044},"step-5-create-the-main-app-component","Step 5: Create the Main App Component",[12,5047,5048,5049,2573],{},"Update ",[205,5050,5051],{},"src\u002FApp.jsx",[198,5053,5055],{"className":1181,"code":5054,"language":1183,"meta":203,"style":203},"import { useState, useEffect } from 'react';\nimport { getHeadlines, searchNews } from '.\u002Fservices\u002FnewsApi';\nimport NewsCard from '.\u002Fcomponents\u002FNewsCard';\nimport Filters from '.\u002Fcomponents\u002FFilters';\nimport '.\u002FApp.css';\n\nfunction App() {\n  const [articles, setArticles] = useState([]);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState(null);\n  const [country, setCountry] = useState('us');\n  const [category, setCategory] = useState(null);\n  const [searchQuery, setSearchQuery] = useState('');\n\n  useEffect(() => {\n    fetchNews();\n  }, [country, category]);\n\n  const fetchNews = async () => {\n    try {\n      setLoading(true);\n      setError(null);\n      const data = await getHeadlines(country, category);\n      setArticles(data.articles || []);\n    } catch (err) {\n      setError('Failed to fetch news. Please try again later.');\n      console.error(err);\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  const handleSearch = async (e) => {\n    e.preventDefault();\n    if (!searchQuery.trim()) {\n      fetchNews();\n      return;\n    }\n\n    try {\n      setLoading(true);\n      setError(null);\n      const data = await searchNews(searchQuery, country);\n      setArticles(data.articles || []);\n    } catch (err) {\n      setError('Search failed. Please try again.');\n      console.error(err);\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  return (\n    \u003Cdiv className=\"app\">\n      \u003Cheader className=\"app-header\">\n        \u003Ch1>News Aggregator\u003C\u002Fh1>\n        \u003Cp>Powered by AllNewsAPI\u003C\u002Fp>\n      \u003C\u002Fheader>\n\n      \u003Cdiv className=\"app-controls\">\n        \u003CFilters\n          country={country}\n          category={category}\n          onCountryChange={setCountry}\n          onCategoryChange={setCategory}\n        \u002F>\n\n        \u003Cform onSubmit={handleSearch} className=\"search-form\">\n          \u003Cinput\n            type=\"text\"\n            placeholder=\"Search news...\"\n            value={searchQuery}\n            onChange={(e) => setSearchQuery(e.target.value)}\n            className=\"search-input\"\n          \u002F>\n          \u003Cbutton type=\"submit\" className=\"search-button\">\n            Search\n          \u003C\u002Fbutton>\n        \u003C\u002Fform>\n      \u003C\u002Fdiv>\n\n      \u003Cmain className=\"app-content\">\n        {loading && \u003Cdiv className=\"loading\">Loading news...\u003C\u002Fdiv>}\n        \n        {error && \u003Cdiv className=\"error\">{error}\u003C\u002Fdiv>}\n        \n        {!loading && !error && articles.length === 0 && (\n          \u003Cdiv className=\"no-results\">No articles found\u003C\u002Fdiv>\n        )}\n        \n        {!loading && !error && articles.length > 0 && (\n          \u003Cdiv className=\"news-grid\">\n            {articles.map((article, index) => (\n              \u003CNewsCard key={index} article={article} \u002F>\n            ))}\n          \u003C\u002Fdiv>\n        )}\n      \u003C\u002Fmain>\n    \u003C\u002Fdiv>\n  );\n}\n\nexport default App;\n",[205,5056,5057,5069,5083,5097,5111,5120,5124,5133,5153,5177,5204,5229,5254,5281,5285,5297,5304,5309,5313,5331,5338,5349,5360,5378,5391,5402,5413,5423,5432,5443,5447,5451,5455,5476,5486,5505,5512,5519,5523,5527,5533,5543,5553,5569,5579,5587,5598,5606,5614,5624,5628,5632,5636,5642,5657,5673,5686,5699,5707,5711,5727,5735,5746,5757,5768,5779,5784,5789,5815,5823,5834,5845,5856,5877,5888,5894,5919,5925,5934,5943,5952,5957,5974,6002,6008,6034,6039,6072,6093,6099,6104,6134,6150,6174,6197,6203,6212,6217,6226,6235,6240,6245,6250],{"__ignoreMap":203},[208,5058,5059,5061,5063,5065,5067],{"class":210,"line":211},[208,5060,1191],{"class":1190},[208,5062,1194],{"class":214},[208,5064,1197],{"class":1190},[208,5066,1200],{"class":245},[208,5068,1203],{"class":214},[208,5070,5071,5073,5076,5078,5081],{"class":210,"line":218},[208,5072,1191],{"class":1190},[208,5074,5075],{"class":214}," { getHeadlines, searchNews } ",[208,5077,1197],{"class":1190},[208,5079,5080],{"class":245}," '.\u002Fservices\u002FnewsApi'",[208,5082,1203],{"class":214},[208,5084,5085,5087,5090,5092,5095],{"class":210,"line":228},[208,5086,1191],{"class":1190},[208,5088,5089],{"class":214}," NewsCard ",[208,5091,1197],{"class":1190},[208,5093,5094],{"class":245}," '.\u002Fcomponents\u002FNewsCard'",[208,5096,1203],{"class":214},[208,5098,5099,5101,5104,5106,5109],{"class":210,"line":236},[208,5100,1191],{"class":1190},[208,5102,5103],{"class":214}," Filters ",[208,5105,1197],{"class":1190},[208,5107,5108],{"class":245}," '.\u002Fcomponents\u002FFilters'",[208,5110,1203],{"class":214},[208,5112,5113,5115,5118],{"class":210,"line":252},[208,5114,1191],{"class":1190},[208,5116,5117],{"class":245}," '.\u002FApp.css'",[208,5119,1203],{"class":214},[208,5121,5122],{"class":210,"line":261},[208,5123,1092],{"emptyLinePlaceholder":866},[208,5125,5126,5128,5131],{"class":210,"line":269},[208,5127,1212],{"class":1190},[208,5129,5130],{"class":1215}," App",[208,5132,2297],{"class":214},[208,5134,5135,5137,5139,5141,5143,5145,5147,5149,5151],{"class":210,"line":277},[208,5136,1237],{"class":1190},[208,5138,2330],{"class":214},[208,5140,2333],{"class":221},[208,5142,1226],{"class":214},[208,5144,2338],{"class":221},[208,5146,2341],{"class":214},[208,5148,1778],{"class":1190},[208,5150,2346],{"class":1215},[208,5152,2349],{"class":214},[208,5154,5155,5157,5159,5161,5163,5165,5167,5169,5171,5173,5175],{"class":210,"line":283},[208,5156,1237],{"class":1190},[208,5158,2330],{"class":214},[208,5160,2358],{"class":221},[208,5162,1226],{"class":214},[208,5164,2363],{"class":221},[208,5166,2341],{"class":214},[208,5168,1778],{"class":1190},[208,5170,2346],{"class":1215},[208,5172,1727],{"class":214},[208,5174,2374],{"class":221},[208,5176,2377],{"class":214},[208,5178,5179,5181,5183,5186,5188,5191,5193,5195,5197,5199,5202],{"class":210,"line":289},[208,5180,1237],{"class":1190},[208,5182,2330],{"class":214},[208,5184,5185],{"class":221},"error",[208,5187,1226],{"class":214},[208,5189,5190],{"class":221},"setError",[208,5192,2341],{"class":214},[208,5194,1778],{"class":1190},[208,5196,2346],{"class":1215},[208,5198,1727],{"class":214},[208,5200,5201],{"class":221},"null",[208,5203,2377],{"class":214},[208,5205,5206,5208,5210,5212,5214,5217,5219,5221,5223,5225,5227],{"class":210,"line":295},[208,5207,1237],{"class":1190},[208,5209,2330],{"class":214},[208,5211,4392],{"class":221},[208,5213,1226],{"class":214},[208,5215,5216],{"class":221},"setCountry",[208,5218,2341],{"class":214},[208,5220,1778],{"class":1190},[208,5222,2346],{"class":1215},[208,5224,1727],{"class":214},[208,5226,4427],{"class":245},[208,5228,2377],{"class":214},[208,5230,5231,5233,5235,5237,5239,5242,5244,5246,5248,5250,5252],{"class":210,"line":301},[208,5232,1237],{"class":1190},[208,5234,2330],{"class":214},[208,5236,4397],{"class":221},[208,5238,1226],{"class":214},[208,5240,5241],{"class":221},"setCategory",[208,5243,2341],{"class":214},[208,5245,1778],{"class":1190},[208,5247,2346],{"class":1215},[208,5249,1727],{"class":214},[208,5251,5201],{"class":221},[208,5253,2377],{"class":214},[208,5255,5256,5258,5260,5263,5265,5268,5270,5272,5274,5276,5279],{"class":210,"line":1078},[208,5257,1237],{"class":1190},[208,5259,2330],{"class":214},[208,5261,5262],{"class":221},"searchQuery",[208,5264,1226],{"class":214},[208,5266,5267],{"class":221},"setSearchQuery",[208,5269,2341],{"class":214},[208,5271,1778],{"class":1190},[208,5273,2346],{"class":1215},[208,5275,1727],{"class":214},[208,5277,5278],{"class":245},"''",[208,5280,2377],{"class":214},[208,5282,5283],{"class":210,"line":1084},[208,5284,1092],{"emptyLinePlaceholder":866},[208,5286,5287,5290,5293,5295],{"class":210,"line":1089},[208,5288,5289],{"class":1215},"  useEffect",[208,5291,5292],{"class":214},"(() ",[208,5294,1712],{"class":1190},[208,5296,1715],{"class":214},[208,5298,5299,5302],{"class":210,"line":1095},[208,5300,5301],{"class":1215},"    fetchNews",[208,5303,2323],{"class":214},[208,5305,5306],{"class":210,"line":1481},[208,5307,5308],{"class":214},"  }, [country, category]);\n",[208,5310,5311],{"class":210,"line":1501},[208,5312,1092],{"emptyLinePlaceholder":866},[208,5314,5315,5317,5320,5322,5324,5327,5329],{"class":210,"line":1521},[208,5316,1237],{"class":1190},[208,5318,5319],{"class":1215}," fetchNews",[208,5321,1243],{"class":1190},[208,5323,2393],{"class":1190},[208,5325,5326],{"class":214}," () ",[208,5328,1712],{"class":1190},[208,5330,1715],{"class":214},[208,5332,5333,5336],{"class":210,"line":1541},[208,5334,5335],{"class":1190},"    try",[208,5337,1715],{"class":214},[208,5339,5340,5343,5345,5347],{"class":210,"line":1561},[208,5341,5342],{"class":1215},"      setLoading",[208,5344,1727],{"class":214},[208,5346,2374],{"class":221},[208,5348,2377],{"class":214},[208,5350,5351,5354,5356,5358],{"class":210,"line":1581},[208,5352,5353],{"class":1215},"      setError",[208,5355,1727],{"class":214},[208,5357,5201],{"class":221},[208,5359,2377],{"class":214},[208,5361,5362,5365,5368,5370,5372,5375],{"class":210,"line":1601},[208,5363,5364],{"class":1190},"      const",[208,5366,5367],{"class":221}," data",[208,5369,1243],{"class":1190},[208,5371,2433],{"class":1190},[208,5373,5374],{"class":1215}," getHeadlines",[208,5376,5377],{"class":214},"(country, category);\n",[208,5379,5380,5383,5386,5388],{"class":210,"line":1621},[208,5381,5382],{"class":1215},"      setArticles",[208,5384,5385],{"class":214},"(data.articles ",[208,5387,4850],{"class":1190},[208,5389,5390],{"class":214}," []);\n",[208,5392,5393,5396,5399],{"class":210,"line":1641},[208,5394,5395],{"class":214},"    } ",[208,5397,5398],{"class":1190},"catch",[208,5400,5401],{"class":214}," (err) {\n",[208,5403,5404,5406,5408,5411],{"class":210,"line":1661},[208,5405,5353],{"class":1215},[208,5407,1727],{"class":214},[208,5409,5410],{"class":245},"'Failed to fetch news. Please try again later.'",[208,5412,2377],{"class":214},[208,5414,5415,5418,5420],{"class":210,"line":1682},[208,5416,5417],{"class":214},"      console.",[208,5419,5185],{"class":1215},[208,5421,5422],{"class":214},"(err);\n",[208,5424,5425,5427,5430],{"class":210,"line":1688},[208,5426,5395],{"class":214},[208,5428,5429],{"class":1190},"finally",[208,5431,1715],{"class":214},[208,5433,5434,5436,5438,5441],{"class":210,"line":1693},[208,5435,5342],{"class":1215},[208,5437,1727],{"class":214},[208,5439,5440],{"class":221},"false",[208,5442,2377],{"class":214},[208,5444,5445],{"class":210,"line":1718},[208,5446,292],{"class":214},[208,5448,5449],{"class":210,"line":1736},[208,5450,1748],{"class":214},[208,5452,5453],{"class":210,"line":1745},[208,5454,1092],{"emptyLinePlaceholder":866},[208,5456,5457,5459,5462,5464,5466,5468,5470,5472,5474],{"class":210,"line":1751},[208,5458,1237],{"class":1190},[208,5460,5461],{"class":1215}," handleSearch",[208,5463,1243],{"class":1190},[208,5465,2393],{"class":1190},[208,5467,1703],{"class":214},[208,5469,1821],{"class":1222},[208,5471,1709],{"class":214},[208,5473,1712],{"class":1190},[208,5475,1715],{"class":214},[208,5477,5478,5481,5484],{"class":210,"line":1756},[208,5479,5480],{"class":214},"    e.",[208,5482,5483],{"class":1215},"preventDefault",[208,5485,2323],{"class":214},[208,5487,5488,5491,5493,5496,5499,5502],{"class":210,"line":1765},[208,5489,5490],{"class":1190},"    if",[208,5492,1703],{"class":214},[208,5494,5495],{"class":1190},"!",[208,5497,5498],{"class":214},"searchQuery.",[208,5500,5501],{"class":1215},"trim",[208,5503,5504],{"class":214},"()) {\n",[208,5506,5507,5510],{"class":210,"line":1787},[208,5508,5509],{"class":1215},"      fetchNews",[208,5511,2323],{"class":214},[208,5513,5514,5517],{"class":210,"line":1799},[208,5515,5516],{"class":1190},"      return",[208,5518,1203],{"class":214},[208,5520,5521],{"class":210,"line":1810},[208,5522,292],{"class":214},[208,5524,5525],{"class":210,"line":1833},[208,5526,1092],{"emptyLinePlaceholder":866},[208,5528,5529,5531],{"class":210,"line":1839},[208,5530,5335],{"class":1190},[208,5532,1715],{"class":214},[208,5534,5535,5537,5539,5541],{"class":210,"line":1858},[208,5536,5342],{"class":1215},[208,5538,1727],{"class":214},[208,5540,2374],{"class":221},[208,5542,2377],{"class":214},[208,5544,5545,5547,5549,5551],{"class":210,"line":1883},[208,5546,5353],{"class":1215},[208,5548,1727],{"class":214},[208,5550,5201],{"class":221},[208,5552,2377],{"class":214},[208,5554,5555,5557,5559,5561,5563,5566],{"class":210,"line":1889},[208,5556,5364],{"class":1190},[208,5558,5367],{"class":221},[208,5560,1243],{"class":1190},[208,5562,2433],{"class":1190},[208,5564,5565],{"class":1215}," searchNews",[208,5567,5568],{"class":214},"(searchQuery, country);\n",[208,5570,5571,5573,5575,5577],{"class":210,"line":1899},[208,5572,5382],{"class":1215},[208,5574,5385],{"class":214},[208,5576,4850],{"class":1190},[208,5578,5390],{"class":214},[208,5580,5581,5583,5585],{"class":210,"line":1905},[208,5582,5395],{"class":214},[208,5584,5398],{"class":1190},[208,5586,5401],{"class":214},[208,5588,5589,5591,5593,5596],{"class":210,"line":1915},[208,5590,5353],{"class":1215},[208,5592,1727],{"class":214},[208,5594,5595],{"class":245},"'Search failed. Please try again.'",[208,5597,2377],{"class":214},[208,5599,5600,5602,5604],{"class":210,"line":1925},[208,5601,5417],{"class":214},[208,5603,5185],{"class":1215},[208,5605,5422],{"class":214},[208,5607,5608,5610,5612],{"class":210,"line":1930},[208,5609,5395],{"class":214},[208,5611,5429],{"class":1190},[208,5613,1715],{"class":214},[208,5615,5616,5618,5620,5622],{"class":210,"line":1935},[208,5617,5342],{"class":1215},[208,5619,1727],{"class":214},[208,5621,5440],{"class":221},[208,5623,2377],{"class":214},[208,5625,5626],{"class":210,"line":1940},[208,5627,292],{"class":214},[208,5629,5630],{"class":210,"line":2230},[208,5631,1748],{"class":214},[208,5633,5634],{"class":210,"line":2236},[208,5635,1092],{"emptyLinePlaceholder":866},[208,5637,5638,5640],{"class":210,"line":2242},[208,5639,1759],{"class":1190},[208,5641,1762],{"class":214},[208,5643,5644,5646,5648,5650,5652,5655],{"class":210,"line":2247},[208,5645,1768],{"class":214},[208,5647,1772],{"class":1771},[208,5649,1775],{"class":1215},[208,5651,1778],{"class":1190},[208,5653,5654],{"class":245},"\"app\"",[208,5656,1784],{"class":214},[208,5658,5659,5661,5664,5666,5668,5671],{"class":210,"line":2253},[208,5660,1790],{"class":214},[208,5662,5663],{"class":1771},"header",[208,5665,1775],{"class":1215},[208,5667,1778],{"class":1190},[208,5669,5670],{"class":245},"\"app-header\"",[208,5672,1784],{"class":214},[208,5674,5675,5677,5679,5682,5684],{"class":210,"line":2258},[208,5676,2548],{"class":214},[208,5678,2482],{"class":1771},[208,5680,5681],{"class":214},">News Aggregator\u003C\u002F",[208,5683,2482],{"class":1771},[208,5685,1784],{"class":214},[208,5687,5688,5690,5692,5695,5697],{"class":210,"line":3213},[208,5689,2548],{"class":214},[208,5691,12],{"class":1771},[208,5693,5694],{"class":214},">Powered by AllNewsAPI\u003C\u002F",[208,5696,12],{"class":1771},[208,5698,1784],{"class":214},[208,5700,5701,5703,5705],{"class":210,"line":3219},[208,5702,1908],{"class":214},[208,5704,5663],{"class":1771},[208,5706,1784],{"class":214},[208,5708,5709],{"class":210,"line":5034},[208,5710,1092],{"emptyLinePlaceholder":866},[208,5712,5714,5716,5718,5720,5722,5725],{"class":210,"line":5713},60,[208,5715,1790],{"class":214},[208,5717,1772],{"class":1771},[208,5719,1775],{"class":1215},[208,5721,1778],{"class":1190},[208,5723,5724],{"class":245},"\"app-controls\"",[208,5726,1784],{"class":214},[208,5728,5730,5732],{"class":210,"line":5729},61,[208,5731,2548],{"class":214},[208,5733,5734],{"class":221},"Filters\n",[208,5736,5738,5741,5743],{"class":210,"line":5737},62,[208,5739,5740],{"class":1215},"          country",[208,5742,1778],{"class":1190},[208,5744,5745],{"class":214},"{country}\n",[208,5747,5749,5752,5754],{"class":210,"line":5748},63,[208,5750,5751],{"class":1215},"          category",[208,5753,1778],{"class":1190},[208,5755,5756],{"class":214},"{category}\n",[208,5758,5760,5763,5765],{"class":210,"line":5759},64,[208,5761,5762],{"class":1215},"          onCountryChange",[208,5764,1778],{"class":1190},[208,5766,5767],{"class":214},"{setCountry}\n",[208,5769,5771,5774,5776],{"class":210,"line":5770},65,[208,5772,5773],{"class":1215},"          onCategoryChange",[208,5775,1778],{"class":1190},[208,5777,5778],{"class":214},"{setCategory}\n",[208,5780,5782],{"class":210,"line":5781},66,[208,5783,4112],{"class":214},[208,5785,5787],{"class":210,"line":5786},67,[208,5788,1092],{"emptyLinePlaceholder":866},[208,5790,5792,5794,5797,5800,5802,5805,5808,5810,5813],{"class":210,"line":5791},68,[208,5793,2548],{"class":214},[208,5795,5796],{"class":1771},"form",[208,5798,5799],{"class":1215}," onSubmit",[208,5801,1778],{"class":1190},[208,5803,5804],{"class":214},"{handleSearch} ",[208,5806,5807],{"class":1215},"className",[208,5809,1778],{"class":1190},[208,5811,5812],{"class":245},"\"search-form\"",[208,5814,1784],{"class":214},[208,5816,5818,5820],{"class":210,"line":5817},69,[208,5819,1861],{"class":214},[208,5821,5822],{"class":1771},"input\n",[208,5824,5826,5829,5831],{"class":210,"line":5825},70,[208,5827,5828],{"class":1215},"            type",[208,5830,1778],{"class":1190},[208,5832,5833],{"class":245},"\"text\"\n",[208,5835,5837,5840,5842],{"class":210,"line":5836},71,[208,5838,5839],{"class":1215},"            placeholder",[208,5841,1778],{"class":1190},[208,5843,5844],{"class":245},"\"Search news...\"\n",[208,5846,5848,5851,5853],{"class":210,"line":5847},72,[208,5849,5850],{"class":1215},"            value",[208,5852,1778],{"class":1190},[208,5854,5855],{"class":214},"{searchQuery}\n",[208,5857,5859,5862,5864,5866,5868,5870,5872,5875],{"class":210,"line":5858},73,[208,5860,5861],{"class":1215},"            onChange",[208,5863,1778],{"class":1190},[208,5865,1818],{"class":214},[208,5867,1821],{"class":1222},[208,5869,1709],{"class":214},[208,5871,1712],{"class":1190},[208,5873,5874],{"class":1215}," setSearchQuery",[208,5876,1830],{"class":214},[208,5878,5880,5883,5885],{"class":210,"line":5879},74,[208,5881,5882],{"class":1215},"            className",[208,5884,1778],{"class":1190},[208,5886,5887],{"class":245},"\"search-input\"\n",[208,5889,5891],{"class":210,"line":5890},75,[208,5892,5893],{"class":214},"          \u002F>\n",[208,5895,5897,5899,5902,5905,5907,5910,5912,5914,5917],{"class":210,"line":5896},76,[208,5898,1861],{"class":214},[208,5900,5901],{"class":1771},"button",[208,5903,5904],{"class":1215}," type",[208,5906,1778],{"class":1190},[208,5908,5909],{"class":245},"\"submit\"",[208,5911,1775],{"class":1215},[208,5913,1778],{"class":1190},[208,5915,5916],{"class":245},"\"search-button\"",[208,5918,1784],{"class":214},[208,5920,5922],{"class":210,"line":5921},77,[208,5923,5924],{"class":214},"            Search\n",[208,5926,5928,5930,5932],{"class":210,"line":5927},78,[208,5929,1892],{"class":214},[208,5931,5901],{"class":1771},[208,5933,1784],{"class":214},[208,5935,5937,5939,5941],{"class":210,"line":5936},79,[208,5938,4258],{"class":214},[208,5940,5796],{"class":1771},[208,5942,1784],{"class":214},[208,5944,5946,5948,5950],{"class":210,"line":5945},80,[208,5947,1908],{"class":214},[208,5949,1772],{"class":1771},[208,5951,1784],{"class":214},[208,5953,5955],{"class":210,"line":5954},81,[208,5956,1092],{"emptyLinePlaceholder":866},[208,5958,5960,5962,5965,5967,5969,5972],{"class":210,"line":5959},82,[208,5961,1790],{"class":214},[208,5963,5964],{"class":1771},"main",[208,5966,1775],{"class":1215},[208,5968,1778],{"class":1190},[208,5970,5971],{"class":245},"\"app-content\"",[208,5973,1784],{"class":214},[208,5975,5977,5980,5982,5985,5987,5989,5991,5994,5997,5999],{"class":210,"line":5976},83,[208,5978,5979],{"class":214},"        {loading ",[208,5981,4066],{"class":1190},[208,5983,5984],{"class":214}," \u003C",[208,5986,1772],{"class":1771},[208,5988,1775],{"class":1215},[208,5990,1778],{"class":1190},[208,5992,5993],{"class":245},"\"loading\"",[208,5995,5996],{"class":214},">Loading news...\u003C\u002F",[208,5998,1772],{"class":1771},[208,6000,6001],{"class":214},">}\n",[208,6003,6005],{"class":210,"line":6004},84,[208,6006,6007],{"class":214},"        \n",[208,6009,6011,6014,6016,6018,6020,6022,6024,6027,6030,6032],{"class":210,"line":6010},85,[208,6012,6013],{"class":214},"        {error ",[208,6015,4066],{"class":1190},[208,6017,5984],{"class":214},[208,6019,1772],{"class":1771},[208,6021,1775],{"class":1215},[208,6023,1778],{"class":1190},[208,6025,6026],{"class":245},"\"error\"",[208,6028,6029],{"class":214},">{error}\u003C\u002F",[208,6031,1772],{"class":1771},[208,6033,6001],{"class":214},[208,6035,6037],{"class":210,"line":6036},86,[208,6038,6007],{"class":214},[208,6040,6042,6044,6046,6049,6051,6054,6057,6059,6061,6063,6065,6067,6070],{"class":210,"line":6041},87,[208,6043,3381],{"class":214},[208,6045,5495],{"class":1190},[208,6047,6048],{"class":214},"loading ",[208,6050,4066],{"class":1190},[208,6052,6053],{"class":1190}," !",[208,6055,6056],{"class":214},"error ",[208,6058,4066],{"class":1190},[208,6060,2576],{"class":214},[208,6062,2579],{"class":221},[208,6064,2582],{"class":1190},[208,6066,2585],{"class":221},[208,6068,6069],{"class":1190}," &&",[208,6071,1762],{"class":214},[208,6073,6075,6077,6079,6081,6083,6086,6089,6091],{"class":210,"line":6074},88,[208,6076,1861],{"class":214},[208,6078,1772],{"class":1771},[208,6080,1775],{"class":1215},[208,6082,1778],{"class":1190},[208,6084,6085],{"class":245},"\"no-results\"",[208,6087,6088],{"class":214},">No articles found\u003C\u002F",[208,6090,1772],{"class":1771},[208,6092,1784],{"class":214},[208,6094,6096],{"class":210,"line":6095},89,[208,6097,6098],{"class":214},"        )}\n",[208,6100,6102],{"class":210,"line":6101},90,[208,6103,6007],{"class":214},[208,6105,6107,6109,6111,6113,6115,6117,6119,6121,6123,6125,6128,6130,6132],{"class":210,"line":6106},91,[208,6108,3381],{"class":214},[208,6110,5495],{"class":1190},[208,6112,6048],{"class":214},[208,6114,4066],{"class":1190},[208,6116,6053],{"class":1190},[208,6118,6056],{"class":214},[208,6120,4066],{"class":1190},[208,6122,2576],{"class":214},[208,6124,2579],{"class":221},[208,6126,6127],{"class":1190}," >",[208,6129,2585],{"class":221},[208,6131,6069],{"class":1190},[208,6133,1762],{"class":214},[208,6135,6137,6139,6141,6143,6145,6148],{"class":210,"line":6136},92,[208,6138,1861],{"class":214},[208,6140,1772],{"class":1771},[208,6142,1775],{"class":1215},[208,6144,1778],{"class":1190},[208,6146,6147],{"class":245},"\"news-grid\"",[208,6149,1784],{"class":214},[208,6151,6153,6156,6158,6161,6163,6165,6168,6170,6172],{"class":210,"line":6152},93,[208,6154,6155],{"class":214},"            {articles.",[208,6157,1845],{"class":1215},[208,6159,6160],{"class":214},"((",[208,6162,4035],{"class":1222},[208,6164,1226],{"class":214},[208,6166,6167],{"class":1222},"index",[208,6169,1709],{"class":214},[208,6171,1712],{"class":1190},[208,6173,1762],{"class":214},[208,6175,6177,6180,6183,6185,6187,6190,6192,6194],{"class":210,"line":6176},94,[208,6178,6179],{"class":214},"              \u003C",[208,6181,6182],{"class":221},"NewsCard",[208,6184,1867],{"class":1215},[208,6186,1778],{"class":1190},[208,6188,6189],{"class":214},"{index} ",[208,6191,4035],{"class":1215},[208,6193,1778],{"class":1190},[208,6195,6196],{"class":214},"{article} \u002F>\n",[208,6198,6200],{"class":210,"line":6199},95,[208,6201,6202],{"class":214},"            ))}\n",[208,6204,6206,6208,6210],{"class":210,"line":6205},96,[208,6207,1892],{"class":214},[208,6209,1772],{"class":1771},[208,6211,1784],{"class":214},[208,6213,6215],{"class":210,"line":6214},97,[208,6216,6098],{"class":214},[208,6218,6220,6222,6224],{"class":210,"line":6219},98,[208,6221,1908],{"class":214},[208,6223,5964],{"class":1771},[208,6225,1784],{"class":214},[208,6227,6229,6231,6233],{"class":210,"line":6228},99,[208,6230,1918],{"class":214},[208,6232,1772],{"class":1771},[208,6234,1784],{"class":214},[208,6236,6238],{"class":210,"line":6237},100,[208,6239,1130],{"class":214},[208,6241,6243],{"class":210,"line":6242},101,[208,6244,304],{"class":214},[208,6246,6248],{"class":210,"line":6247},102,[208,6249,1092],{"emptyLinePlaceholder":866},[208,6251,6253,6255,6257],{"class":210,"line":6252},103,[208,6254,1943],{"class":1190},[208,6256,1946],{"class":1190},[208,6258,6259],{"class":214}," App;\n",[21,6261,6263],{"id":6262},"step-6-add-styling","Step 6: Add Styling",[12,6265,3997,6266,6269],{},[205,6267,6268],{},"src\u002FApp.css"," with your preferred styles. Here's a basic example:",[198,6271,6273],{"className":2665,"code":6272,"language":2667,"meta":203,"style":203},".app {\n  max-width: 1200px;\n  margin: 0 auto;\n  padding: 20px;\n}\n\n.app-header {\n  text-align: center;\n  margin-bottom: 30px;\n}\n\n.news-grid {\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n  gap: 20px;\n}\n\n.news-card {\n  border: 1px solid #ddd;\n  border-radius: 8px;\n  overflow: hidden;\n  transition: transform 0.2s;\n}\n\n.news-card:hover {\n  transform: translateY(-4px);\n  box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n}\n",[205,6274,6275,6282,6296,6310,6324,6328,6332,6339,6350,6364,6368,6372,6379,6391,6428,6441,6445,6449,6456,6475,6489,6501,6517,6521,6525,6532,6551,6593],{"__ignoreMap":203},[208,6276,6277,6280],{"class":210,"line":211},[208,6278,6279],{"class":1215},".app",[208,6281,1715],{"class":214},[208,6283,6284,6287,6289,6292,6294],{"class":210,"line":218},[208,6285,6286],{"class":221},"  max-width",[208,6288,242],{"class":214},[208,6290,6291],{"class":221},"1200",[208,6293,2799],{"class":1190},[208,6295,1203],{"class":214},[208,6297,6298,6301,6303,6305,6308],{"class":210,"line":228},[208,6299,6300],{"class":221},"  margin",[208,6302,242],{"class":214},[208,6304,2784],{"class":221},[208,6306,6307],{"class":221}," auto",[208,6309,1203],{"class":214},[208,6311,6312,6315,6317,6320,6322],{"class":210,"line":236},[208,6313,6314],{"class":221},"  padding",[208,6316,242],{"class":214},[208,6318,6319],{"class":221},"20",[208,6321,2799],{"class":1190},[208,6323,1203],{"class":214},[208,6325,6326],{"class":210,"line":252},[208,6327,304],{"class":214},[208,6329,6330],{"class":210,"line":261},[208,6331,1092],{"emptyLinePlaceholder":866},[208,6333,6334,6337],{"class":210,"line":269},[208,6335,6336],{"class":1215},".app-header",[208,6338,1715],{"class":214},[208,6340,6341,6343,6345,6348],{"class":210,"line":277},[208,6342,2707],{"class":221},[208,6344,242],{"class":214},[208,6346,6347],{"class":221},"center",[208,6349,1203],{"class":214},[208,6351,6352,6355,6357,6360,6362],{"class":210,"line":283},[208,6353,6354],{"class":221},"  margin-bottom",[208,6356,242],{"class":214},[208,6358,6359],{"class":221},"30",[208,6361,2799],{"class":1190},[208,6363,1203],{"class":214},[208,6365,6366],{"class":210,"line":289},[208,6367,304],{"class":214},[208,6369,6370],{"class":210,"line":295},[208,6371,1092],{"emptyLinePlaceholder":866},[208,6373,6374,6377],{"class":210,"line":301},[208,6375,6376],{"class":1215},".news-grid",[208,6378,1715],{"class":214},[208,6380,6381,6384,6386,6389],{"class":210,"line":1078},[208,6382,6383],{"class":221},"  display",[208,6385,242],{"class":214},[208,6387,6388],{"class":221},"grid",[208,6390,1203],{"class":214},[208,6392,6393,6396,6398,6401,6403,6406,6408,6411,6413,6416,6418,6420,6422,6425],{"class":210,"line":1084},[208,6394,6395],{"class":221},"  grid-template-columns",[208,6397,242],{"class":214},[208,6399,6400],{"class":221},"repeat",[208,6402,1727],{"class":214},[208,6404,6405],{"class":221},"auto-fill",[208,6407,1226],{"class":214},[208,6409,6410],{"class":221},"minmax",[208,6412,1727],{"class":214},[208,6414,6415],{"class":221},"300",[208,6417,2799],{"class":1190},[208,6419,1226],{"class":214},[208,6421,4980],{"class":221},[208,6423,6424],{"class":1190},"fr",[208,6426,6427],{"class":214},"));\n",[208,6429,6430,6433,6435,6437,6439],{"class":210,"line":1089},[208,6431,6432],{"class":221},"  gap",[208,6434,242],{"class":214},[208,6436,6319],{"class":221},[208,6438,2799],{"class":1190},[208,6440,1203],{"class":214},[208,6442,6443],{"class":210,"line":1095},[208,6444,304],{"class":214},[208,6446,6447],{"class":210,"line":1481},[208,6448,1092],{"emptyLinePlaceholder":866},[208,6450,6451,6454],{"class":210,"line":1501},[208,6452,6453],{"class":1215},".news-card",[208,6455,1715],{"class":214},[208,6457,6458,6461,6463,6465,6467,6470,6473],{"class":210,"line":1521},[208,6459,6460],{"class":221},"  border",[208,6462,242],{"class":214},[208,6464,4980],{"class":221},[208,6466,2799],{"class":1190},[208,6468,6469],{"class":221}," solid",[208,6471,6472],{"class":221}," #ddd",[208,6474,1203],{"class":214},[208,6476,6477,6480,6482,6485,6487],{"class":210,"line":1541},[208,6478,6479],{"class":221},"  border-radius",[208,6481,242],{"class":214},[208,6483,6484],{"class":221},"8",[208,6486,2799],{"class":1190},[208,6488,1203],{"class":214},[208,6490,6491,6494,6496,6499],{"class":210,"line":1561},[208,6492,6493],{"class":221},"  overflow",[208,6495,242],{"class":214},[208,6497,6498],{"class":221},"hidden",[208,6500,1203],{"class":214},[208,6502,6503,6506,6509,6512,6515],{"class":210,"line":1581},[208,6504,6505],{"class":221},"  transition",[208,6507,6508],{"class":214},": transform ",[208,6510,6511],{"class":221},"0.2",[208,6513,6514],{"class":1190},"s",[208,6516,1203],{"class":214},[208,6518,6519],{"class":210,"line":1601},[208,6520,304],{"class":214},[208,6522,6523],{"class":210,"line":1621},[208,6524,1092],{"emptyLinePlaceholder":866},[208,6526,6527,6530],{"class":210,"line":1641},[208,6528,6529],{"class":1215},".news-card:hover",[208,6531,1715],{"class":214},[208,6533,6534,6537,6539,6542,6544,6547,6549],{"class":210,"line":1661},[208,6535,6536],{"class":221},"  transform",[208,6538,242],{"class":214},[208,6540,6541],{"class":221},"translateY",[208,6543,1727],{"class":214},[208,6545,6546],{"class":221},"-4",[208,6548,2799],{"class":1190},[208,6550,2377],{"class":214},[208,6552,6553,6556,6558,6560,6563,6565,6568,6570,6573,6575,6577,6580,6582,6584,6586,6588,6591],{"class":210,"line":1682},[208,6554,6555],{"class":221},"  box-shadow",[208,6557,242],{"class":214},[208,6559,2784],{"class":221},[208,6561,6562],{"class":221}," 4",[208,6564,2799],{"class":1190},[208,6566,6567],{"class":221}," 12",[208,6569,2799],{"class":1190},[208,6571,6572],{"class":221}," rgba",[208,6574,1727],{"class":214},[208,6576,2784],{"class":221},[208,6578,6579],{"class":214},",",[208,6581,2784],{"class":221},[208,6583,6579],{"class":214},[208,6585,2784],{"class":221},[208,6587,6579],{"class":214},[208,6589,6590],{"class":221},"0.1",[208,6592,2377],{"class":214},[208,6594,6595],{"class":210,"line":1688},[208,6596,304],{"class":214},[21,6598,6600],{"id":6599},"step-7-environment-variables","Step 7: Environment Variables",[12,6602,6603,6604,6607],{},"Create a ",[205,6605,6606],{},".env"," file:",[198,6609,6612],{"className":6610,"code":6611,"language":381},[379],"VITE_NEWS_API_KEY=your_api_key_here\n",[205,6613,6611],{"__ignoreMap":203},[21,6615,6617],{"id":6616},"step-8-run-your-app","Step 8: Run Your App",[198,6619,6621],{"className":1963,"code":6620,"language":1965,"meta":203,"style":203},"npm run dev\n",[205,6622,6623],{"__ignoreMap":203},[208,6624,6625,6627,6630],{"class":210,"line":211},[208,6626,1972],{"class":1215},[208,6628,6629],{"class":245}," run",[208,6631,6632],{"class":245}," dev\n",[12,6634,6635,6636,6639],{},"Visit ",[205,6637,6638],{},"http:\u002F\u002Flocalhost:5173"," to see your news aggregator in action!",[21,6641,6643],{"id":6642},"next-steps","Next Steps",[12,6645,6646],{},"Enhance your app with:",[32,6648,6649,6652,6655,6658,6661],{},[35,6650,6651],{},"Pagination for large result sets",[35,6653,6654],{},"Favorite articles feature",[35,6656,6657],{},"Dark mode toggle",[35,6659,6660],{},"Social sharing buttons",[35,6662,6663],{},"Article bookmarking",[21,6665,779],{"id":778},[12,6667,6668],{},"You've built a fully functional news aggregator! This foundation can be extended with more features and customization to suit your needs.",[12,6670,6671,6672,6675],{},"Check out our ",[182,6673,6674],{"href":741},"API documentation"," for more advanced features and endpoints.",[825,6677,6678],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":203,"searchDepth":218,"depth":218,"links":6680},[6681,6682,6683,6684,6685,6686,6687,6688,6689,6690,6691,6692],{"id":3695,"depth":218,"text":3696},{"id":171,"depth":218,"text":172},{"id":3735,"depth":218,"text":3736},{"id":3804,"depth":218,"text":3805},{"id":3993,"depth":218,"text":3994},{"id":4369,"depth":218,"text":4370},{"id":5044,"depth":218,"text":5045},{"id":6262,"depth":218,"text":6263},{"id":6599,"depth":218,"text":6600},{"id":6616,"depth":218,"text":6617},{"id":6642,"depth":218,"text":6643},{"id":778,"depth":218,"text":779},"2024-11-28","A step-by-step tutorial on creating a modern news aggregator application using AllNewsAPI and React","\u002Fblog\u002Fbuilding-a-news-aggregator-app-with-allnewsapi.webp",{},"\u002Fblog\u002Fbuilding-news-aggregator-app",{"title":3687,"description":6694},{"loc":6697},"blog\u002Fbuilding-news-aggregator-app","3kiQ0CRdSChl_DZIZ1_wnhLs0y-1HxMh8mZE0cktxq4",{"id":6703,"title":6704,"author":7,"body":6705,"date":9213,"description":9214,"draft":862,"extension":863,"image":9215,"meta":9216,"navigation":866,"path":9217,"seo":9218,"sitemap":9219,"stem":9220,"tags":9221,"__hash__":9222},"blog\u002Fblog\u002Fpersonalized-news-feeds.md","Building Personalized News Feeds with Machine Learning",{"type":9,"value":6706,"toc":9193},[6707,6710,6714,6717,6734,6738,6742,6745,7355,7359,7362,7936,7940,7943,8195,8199,8203,8468,8472,8862,8866,8870,8873,8996,9000,9003,9027,9031,9034,9105,9107,9157,9159,9162,9168,9170,9190],[12,6708,6709],{},"Generic news feeds are a thing of the past. Modern users expect personalized content tailored to their interests. This guide shows you how to build intelligent news recommendation systems using machine learning.",[21,6711,6713],{"id":6712},"why-personalization-matters","Why Personalization Matters",[12,6715,6716],{},"Personalized news feeds lead to:",[32,6718,6719,6722,6725,6728,6731],{},[35,6720,6721],{},"3x higher engagement rates",[35,6723,6724],{},"2x longer session times",[35,6726,6727],{},"50% increase in return visits",[35,6729,6730],{},"Better user satisfaction",[35,6732,6733],{},"Reduced information overload",[21,6735,6737],{"id":6736},"personalization-approaches","Personalization Approaches",[94,6739,6741],{"id":6740},"_1-content-based-filtering","1. Content-Based Filtering",[12,6743,6744],{},"Recommend articles similar to what users have read:",[198,6746,6748],{"className":1013,"code":6747,"language":1015,"meta":203,"style":203},"class ContentBasedRecommender {\n  constructor() {\n    this.userProfiles = new Map();\n  }\n  \n  \u002F\u002F Extract features from article\n  extractFeatures(article) {\n    return {\n      category: article.category || 'general',\n      source: article.source.name,\n      keywords: this.extractKeywords(article.title + ' ' + article.description),\n      publishedAt: new Date(article.publishedAt)\n    };\n  }\n  \n  extractKeywords(text) {\n    \u002F\u002F Simple keyword extraction (use NLP library for production)\n    const words = text.toLowerCase()\n      .replace(\u002F[^\\w\\s]\u002Fg, '')\n      .split(\u002F\\s+\u002F)\n      .filter(word => word.length > 4);\n    \n    \u002F\u002F Count word frequency\n    const frequency = {};\n    words.forEach(word => {\n      frequency[word] = (frequency[word] || 0) + 1;\n    });\n    \n    \u002F\u002F Return top keywords\n    return Object.entries(frequency)\n      .sort((a, b) => b[1] - a[1])\n      .slice(0, 10)\n      .map(([word]) => word);\n  }\n  \n  \u002F\u002F Update user profile based on interactions\n  updateUserProfile(userId, article, interaction) {\n    if (!this.userProfiles.has(userId)) {\n      this.userProfiles.set(userId, {\n        categories: {},\n        sources: {},\n        keywords: {},\n        readCount: 0\n      });\n    }\n    \n    const profile = this.userProfiles.get(userId);\n    const features = this.extractFeatures(article);\n    \n    \u002F\u002F Weight based on interaction type\n    const weight = {\n      'read': 1,\n      'like': 2,\n      'share': 3,\n      'save': 2\n    }[interaction] || 1;\n    \n    \u002F\u002F Update category preferences\n    profile.categories[features.category] = \n      (profile.categories[features.category] || 0) + weight;\n    \n    \u002F\u002F Update source preferences\n    profile.sources[features.source] = \n      (profile.sources[features.source] || 0) + weight;\n    \n    \u002F\u002F Update keyword preferences\n    features.keywords.forEach(keyword => {\n      profile.keywords[keyword] = \n        (profile.keywords[keyword] || 0) + weight;\n    });\n    \n    profile.readCount++;\n  }\n  \n  \u002F\u002F Calculate similarity score between article and user profile\n  calculateScore(userId, article) {\n    const profile = this.userProfiles.get(userId);\n    if (!profile || profile.readCount === 0) return 0;\n    \n    const features = this.extractFeatures(article);\n    let score = 0;\n    \n    \u002F\u002F Category score (40% weight)\n    const categoryScore = profile.categories[features.category] || 0;\n    score += (categoryScore \u002F profile.readCount) * 0.4;\n    \n    \u002F\u002F Source score (20% weight)\n    const sourceScore = profile.sources[features.source] || 0;\n    score += (sourceScore \u002F profile.readCount) * 0.2;\n    \n    \u002F\u002F Keyword score (40% weight)\n    const keywordScores = features.keywords.map(\n      keyword => profile.keywords[keyword] || 0\n    );\n    const avgKeywordScore = keywordScores.reduce((a, b) => a + b, 0) \u002F \n      (keywordScores.length || 1);\n    score += (avgKeywordScore \u002F profile.readCount) * 0.4;\n    \n    return score;\n  }\n  \n  \u002F\u002F Get personalized recommendations\n  recommend(userId, articles, limit = 10) {\n    const scoredArticles = articles.map(article => ({\n      article,\n      score: this.calculateScore(userId, article)\n    }));\n    \n    return scoredArticles\n      .sort((a, b) => b.score - a.score)\n      .slice(0, limit)\n      .map(item => item.article);\n  }\n}\n\n\u002F\u002F Usage\nconst recommender = new ContentBasedRecommender();\n\n\u002F\u002F Track user interactions\nrecommender.updateUserProfile('user123', article, 'read');\nrecommender.updateUserProfile('user123', article, 'like');\n\n\u002F\u002F Get recommendations\nconst recommendations = recommender.recommend('user123', allArticles, 10);\n",[205,6749,6750,6755,6759,6764,6768,6772,6777,6782,6787,6792,6797,6802,6807,6812,6816,6820,6825,6830,6835,6840,6845,6850,6854,6859,6864,6869,6874,6878,6882,6887,6892,6897,6902,6907,6911,6915,6920,6925,6930,6935,6940,6945,6950,6955,6960,6964,6968,6973,6978,6982,6987,6992,6997,7002,7007,7012,7017,7021,7026,7031,7036,7040,7045,7050,7055,7059,7064,7069,7074,7079,7083,7087,7092,7096,7100,7105,7110,7114,7119,7123,7127,7132,7136,7141,7146,7151,7155,7160,7165,7170,7174,7179,7184,7189,7194,7199,7204,7209,7213,7218,7222,7226,7231,7236,7242,7248,7254,7260,7265,7271,7277,7283,7289,7294,7299,7304,7309,7315,7320,7326,7332,7338,7343,7349],{"__ignoreMap":203},[208,6751,6752],{"class":210,"line":211},[208,6753,6754],{},"class ContentBasedRecommender {\n",[208,6756,6757],{"class":210,"line":218},[208,6758,3487],{},[208,6760,6761],{"class":210,"line":228},[208,6762,6763],{},"    this.userProfiles = new Map();\n",[208,6765,6766],{"class":210,"line":236},[208,6767,298],{},[208,6769,6770],{"class":210,"line":252},[208,6771,1042],{},[208,6773,6774],{"class":210,"line":261},[208,6775,6776],{},"  \u002F\u002F Extract features from article\n",[208,6778,6779],{"class":210,"line":269},[208,6780,6781],{},"  extractFeatures(article) {\n",[208,6783,6784],{"class":210,"line":277},[208,6785,6786],{},"    return {\n",[208,6788,6789],{"class":210,"line":283},[208,6790,6791],{},"      category: article.category || 'general',\n",[208,6793,6794],{"class":210,"line":289},[208,6795,6796],{},"      source: article.source.name,\n",[208,6798,6799],{"class":210,"line":295},[208,6800,6801],{},"      keywords: this.extractKeywords(article.title + ' ' + article.description),\n",[208,6803,6804],{"class":210,"line":301},[208,6805,6806],{},"      publishedAt: new Date(article.publishedAt)\n",[208,6808,6809],{"class":210,"line":1078},[208,6810,6811],{},"    };\n",[208,6813,6814],{"class":210,"line":1084},[208,6815,298],{},[208,6817,6818],{"class":210,"line":1089},[208,6819,1042],{},[208,6821,6822],{"class":210,"line":1095},[208,6823,6824],{},"  extractKeywords(text) {\n",[208,6826,6827],{"class":210,"line":1481},[208,6828,6829],{},"    \u002F\u002F Simple keyword extraction (use NLP library for production)\n",[208,6831,6832],{"class":210,"line":1501},[208,6833,6834],{},"    const words = text.toLowerCase()\n",[208,6836,6837],{"class":210,"line":1521},[208,6838,6839],{},"      .replace(\u002F[^\\w\\s]\u002Fg, '')\n",[208,6841,6842],{"class":210,"line":1541},[208,6843,6844],{},"      .split(\u002F\\s+\u002F)\n",[208,6846,6847],{"class":210,"line":1561},[208,6848,6849],{},"      .filter(word => word.length > 4);\n",[208,6851,6852],{"class":210,"line":1581},[208,6853,3543],{},[208,6855,6856],{"class":210,"line":1601},[208,6857,6858],{},"    \u002F\u002F Count word frequency\n",[208,6860,6861],{"class":210,"line":1621},[208,6862,6863],{},"    const frequency = {};\n",[208,6865,6866],{"class":210,"line":1641},[208,6867,6868],{},"    words.forEach(word => {\n",[208,6870,6871],{"class":210,"line":1661},[208,6872,6873],{},"      frequency[word] = (frequency[word] || 0) + 1;\n",[208,6875,6876],{"class":210,"line":1682},[208,6877,3603],{},[208,6879,6880],{"class":210,"line":1688},[208,6881,3543],{},[208,6883,6884],{"class":210,"line":1693},[208,6885,6886],{},"    \u002F\u002F Return top keywords\n",[208,6888,6889],{"class":210,"line":1718},[208,6890,6891],{},"    return Object.entries(frequency)\n",[208,6893,6894],{"class":210,"line":1736},[208,6895,6896],{},"      .sort((a, b) => b[1] - a[1])\n",[208,6898,6899],{"class":210,"line":1745},[208,6900,6901],{},"      .slice(0, 10)\n",[208,6903,6904],{"class":210,"line":1751},[208,6905,6906],{},"      .map(([word]) => word);\n",[208,6908,6909],{"class":210,"line":1756},[208,6910,298],{},[208,6912,6913],{"class":210,"line":1765},[208,6914,1042],{},[208,6916,6917],{"class":210,"line":1787},[208,6918,6919],{},"  \u002F\u002F Update user profile based on interactions\n",[208,6921,6922],{"class":210,"line":1799},[208,6923,6924],{},"  updateUserProfile(userId, article, interaction) {\n",[208,6926,6927],{"class":210,"line":1810},[208,6928,6929],{},"    if (!this.userProfiles.has(userId)) {\n",[208,6931,6932],{"class":210,"line":1833},[208,6933,6934],{},"      this.userProfiles.set(userId, {\n",[208,6936,6937],{"class":210,"line":1839},[208,6938,6939],{},"        categories: {},\n",[208,6941,6942],{"class":210,"line":1858},[208,6943,6944],{},"        sources: {},\n",[208,6946,6947],{"class":210,"line":1883},[208,6948,6949],{},"        keywords: {},\n",[208,6951,6952],{"class":210,"line":1889},[208,6953,6954],{},"        readCount: 0\n",[208,6956,6957],{"class":210,"line":1899},[208,6958,6959],{},"      });\n",[208,6961,6962],{"class":210,"line":1905},[208,6963,292],{},[208,6965,6966],{"class":210,"line":1915},[208,6967,3543],{},[208,6969,6970],{"class":210,"line":1925},[208,6971,6972],{},"    const profile = this.userProfiles.get(userId);\n",[208,6974,6975],{"class":210,"line":1930},[208,6976,6977],{},"    const features = this.extractFeatures(article);\n",[208,6979,6980],{"class":210,"line":1935},[208,6981,3543],{},[208,6983,6984],{"class":210,"line":1940},[208,6985,6986],{},"    \u002F\u002F Weight based on interaction type\n",[208,6988,6989],{"class":210,"line":2230},[208,6990,6991],{},"    const weight = {\n",[208,6993,6994],{"class":210,"line":2236},[208,6995,6996],{},"      'read': 1,\n",[208,6998,6999],{"class":210,"line":2242},[208,7000,7001],{},"      'like': 2,\n",[208,7003,7004],{"class":210,"line":2247},[208,7005,7006],{},"      'share': 3,\n",[208,7008,7009],{"class":210,"line":2253},[208,7010,7011],{},"      'save': 2\n",[208,7013,7014],{"class":210,"line":2258},[208,7015,7016],{},"    }[interaction] || 1;\n",[208,7018,7019],{"class":210,"line":3213},[208,7020,3543],{},[208,7022,7023],{"class":210,"line":3219},[208,7024,7025],{},"    \u002F\u002F Update category preferences\n",[208,7027,7028],{"class":210,"line":5034},[208,7029,7030],{},"    profile.categories[features.category] = \n",[208,7032,7033],{"class":210,"line":5713},[208,7034,7035],{},"      (profile.categories[features.category] || 0) + weight;\n",[208,7037,7038],{"class":210,"line":5729},[208,7039,3543],{},[208,7041,7042],{"class":210,"line":5737},[208,7043,7044],{},"    \u002F\u002F Update source preferences\n",[208,7046,7047],{"class":210,"line":5748},[208,7048,7049],{},"    profile.sources[features.source] = \n",[208,7051,7052],{"class":210,"line":5759},[208,7053,7054],{},"      (profile.sources[features.source] || 0) + weight;\n",[208,7056,7057],{"class":210,"line":5770},[208,7058,3543],{},[208,7060,7061],{"class":210,"line":5781},[208,7062,7063],{},"    \u002F\u002F Update keyword preferences\n",[208,7065,7066],{"class":210,"line":5786},[208,7067,7068],{},"    features.keywords.forEach(keyword => {\n",[208,7070,7071],{"class":210,"line":5791},[208,7072,7073],{},"      profile.keywords[keyword] = \n",[208,7075,7076],{"class":210,"line":5817},[208,7077,7078],{},"        (profile.keywords[keyword] || 0) + weight;\n",[208,7080,7081],{"class":210,"line":5825},[208,7082,3603],{},[208,7084,7085],{"class":210,"line":5836},[208,7086,3543],{},[208,7088,7089],{"class":210,"line":5847},[208,7090,7091],{},"    profile.readCount++;\n",[208,7093,7094],{"class":210,"line":5858},[208,7095,298],{},[208,7097,7098],{"class":210,"line":5879},[208,7099,1042],{},[208,7101,7102],{"class":210,"line":5890},[208,7103,7104],{},"  \u002F\u002F Calculate similarity score between article and user profile\n",[208,7106,7107],{"class":210,"line":5896},[208,7108,7109],{},"  calculateScore(userId, article) {\n",[208,7111,7112],{"class":210,"line":5921},[208,7113,6972],{},[208,7115,7116],{"class":210,"line":5927},[208,7117,7118],{},"    if (!profile || profile.readCount === 0) return 0;\n",[208,7120,7121],{"class":210,"line":5936},[208,7122,3543],{},[208,7124,7125],{"class":210,"line":5945},[208,7126,6977],{},[208,7128,7129],{"class":210,"line":5954},[208,7130,7131],{},"    let score = 0;\n",[208,7133,7134],{"class":210,"line":5959},[208,7135,3543],{},[208,7137,7138],{"class":210,"line":5976},[208,7139,7140],{},"    \u002F\u002F Category score (40% weight)\n",[208,7142,7143],{"class":210,"line":6004},[208,7144,7145],{},"    const categoryScore = profile.categories[features.category] || 0;\n",[208,7147,7148],{"class":210,"line":6010},[208,7149,7150],{},"    score += (categoryScore \u002F profile.readCount) * 0.4;\n",[208,7152,7153],{"class":210,"line":6036},[208,7154,3543],{},[208,7156,7157],{"class":210,"line":6041},[208,7158,7159],{},"    \u002F\u002F Source score (20% weight)\n",[208,7161,7162],{"class":210,"line":6074},[208,7163,7164],{},"    const sourceScore = profile.sources[features.source] || 0;\n",[208,7166,7167],{"class":210,"line":6095},[208,7168,7169],{},"    score += (sourceScore \u002F profile.readCount) * 0.2;\n",[208,7171,7172],{"class":210,"line":6101},[208,7173,3543],{},[208,7175,7176],{"class":210,"line":6106},[208,7177,7178],{},"    \u002F\u002F Keyword score (40% weight)\n",[208,7180,7181],{"class":210,"line":6136},[208,7182,7183],{},"    const keywordScores = features.keywords.map(\n",[208,7185,7186],{"class":210,"line":6152},[208,7187,7188],{},"      keyword => profile.keywords[keyword] || 0\n",[208,7190,7191],{"class":210,"line":6176},[208,7192,7193],{},"    );\n",[208,7195,7196],{"class":210,"line":6199},[208,7197,7198],{},"    const avgKeywordScore = keywordScores.reduce((a, b) => a + b, 0) \u002F \n",[208,7200,7201],{"class":210,"line":6205},[208,7202,7203],{},"      (keywordScores.length || 1);\n",[208,7205,7206],{"class":210,"line":6214},[208,7207,7208],{},"    score += (avgKeywordScore \u002F profile.readCount) * 0.4;\n",[208,7210,7211],{"class":210,"line":6219},[208,7212,3543],{},[208,7214,7215],{"class":210,"line":6228},[208,7216,7217],{},"    return score;\n",[208,7219,7220],{"class":210,"line":6237},[208,7221,298],{},[208,7223,7224],{"class":210,"line":6242},[208,7225,1042],{},[208,7227,7228],{"class":210,"line":6247},[208,7229,7230],{},"  \u002F\u002F Get personalized recommendations\n",[208,7232,7233],{"class":210,"line":6252},[208,7234,7235],{},"  recommend(userId, articles, limit = 10) {\n",[208,7237,7239],{"class":210,"line":7238},104,[208,7240,7241],{},"    const scoredArticles = articles.map(article => ({\n",[208,7243,7245],{"class":210,"line":7244},105,[208,7246,7247],{},"      article,\n",[208,7249,7251],{"class":210,"line":7250},106,[208,7252,7253],{},"      score: this.calculateScore(userId, article)\n",[208,7255,7257],{"class":210,"line":7256},107,[208,7258,7259],{},"    }));\n",[208,7261,7263],{"class":210,"line":7262},108,[208,7264,3543],{},[208,7266,7268],{"class":210,"line":7267},109,[208,7269,7270],{},"    return scoredArticles\n",[208,7272,7274],{"class":210,"line":7273},110,[208,7275,7276],{},"      .sort((a, b) => b.score - a.score)\n",[208,7278,7280],{"class":210,"line":7279},111,[208,7281,7282],{},"      .slice(0, limit)\n",[208,7284,7286],{"class":210,"line":7285},112,[208,7287,7288],{},"      .map(item => item.article);\n",[208,7290,7292],{"class":210,"line":7291},113,[208,7293,298],{},[208,7295,7297],{"class":210,"line":7296},114,[208,7298,304],{},[208,7300,7302],{"class":210,"line":7301},115,[208,7303,1092],{"emptyLinePlaceholder":866},[208,7305,7307],{"class":210,"line":7306},116,[208,7308,2912],{},[208,7310,7312],{"class":210,"line":7311},117,[208,7313,7314],{},"const recommender = new ContentBasedRecommender();\n",[208,7316,7318],{"class":210,"line":7317},118,[208,7319,1092],{"emptyLinePlaceholder":866},[208,7321,7323],{"class":210,"line":7322},119,[208,7324,7325],{},"\u002F\u002F Track user interactions\n",[208,7327,7329],{"class":210,"line":7328},120,[208,7330,7331],{},"recommender.updateUserProfile('user123', article, 'read');\n",[208,7333,7335],{"class":210,"line":7334},121,[208,7336,7337],{},"recommender.updateUserProfile('user123', article, 'like');\n",[208,7339,7341],{"class":210,"line":7340},122,[208,7342,1092],{"emptyLinePlaceholder":866},[208,7344,7346],{"class":210,"line":7345},123,[208,7347,7348],{},"\u002F\u002F Get recommendations\n",[208,7350,7352],{"class":210,"line":7351},124,[208,7353,7354],{},"const recommendations = recommender.recommend('user123', allArticles, 10);\n",[94,7356,7358],{"id":7357},"_2-collaborative-filtering","2. Collaborative Filtering",[12,7360,7361],{},"Recommend based on similar users' preferences:",[198,7363,7365],{"className":1013,"code":7364,"language":1015,"meta":203,"style":203},"class CollaborativeFilteringRecommender {\n  constructor() {\n    this.userArticleMatrix = new Map(); \u002F\u002F userId -> Set of article URLs\n    this.articleUserMatrix = new Map(); \u002F\u002F article URL -> Set of userIds\n  }\n  \n  \u002F\u002F Record user interaction with article\n  recordInteraction(userId, articleUrl) {\n    \u002F\u002F Update user-article matrix\n    if (!this.userArticleMatrix.has(userId)) {\n      this.userArticleMatrix.set(userId, new Set());\n    }\n    this.userArticleMatrix.get(userId).add(articleUrl);\n    \n    \u002F\u002F Update article-user matrix\n    if (!this.articleUserMatrix.has(articleUrl)) {\n      this.articleUserMatrix.set(articleUrl, new Set());\n    }\n    this.articleUserMatrix.get(articleUrl).add(userId);\n  }\n  \n  \u002F\u002F Calculate similarity between two users (Jaccard similarity)\n  calculateUserSimilarity(userId1, userId2) {\n    const articles1 = this.userArticleMatrix.get(userId1) || new Set();\n    const articles2 = this.userArticleMatrix.get(userId2) || new Set();\n    \n    if (articles1.size === 0 || articles2.size === 0) return 0;\n    \n    \u002F\u002F Intersection\n    const intersection = new Set(\n      [...articles1].filter(x => articles2.has(x))\n    );\n    \n    \u002F\u002F Union\n    const union = new Set([...articles1, ...articles2]);\n    \n    return intersection.size \u002F union.size;\n  }\n  \n  \u002F\u002F Find similar users\n  findSimilarUsers(userId, limit = 10) {\n    const similarities = [];\n    \n    for (const [otherUserId] of this.userArticleMatrix) {\n      if (otherUserId === userId) continue;\n      \n      const similarity = this.calculateUserSimilarity(userId, otherUserId);\n      if (similarity > 0) {\n        similarities.push({ userId: otherUserId, similarity });\n      }\n    }\n    \n    return similarities\n      .sort((a, b) => b.similarity - a.similarity)\n      .slice(0, limit);\n  }\n  \n  \u002F\u002F Get recommendations based on similar users\n  recommend(userId, allArticles, limit = 10) {\n    const userArticles = this.userArticleMatrix.get(userId) || new Set();\n    const similarUsers = this.findSimilarUsers(userId, 20);\n    \n    if (similarUsers.length === 0) {\n      \u002F\u002F No similar users, return popular articles\n      return this.getPopularArticles(allArticles, limit);\n    }\n    \n    \u002F\u002F Score articles based on similar users\n    const articleScores = new Map();\n    \n    similarUsers.forEach(({ userId: similarUserId, similarity }) => {\n      const articles = this.userArticleMatrix.get(similarUserId) || new Set();\n      \n      articles.forEach(articleUrl => {\n        \u002F\u002F Skip articles user has already seen\n        if (userArticles.has(articleUrl)) return;\n        \n        const currentScore = articleScores.get(articleUrl) || 0;\n        articleScores.set(articleUrl, currentScore + similarity);\n      });\n    });\n    \n    \u002F\u002F Get top scored articles\n    const recommendations = Array.from(articleScores.entries())\n      .sort((a, b) => b[1] - a[1])\n      .slice(0, limit)\n      .map(([url]) => url);\n    \n    \u002F\u002F Map URLs back to article objects\n    return allArticles.filter(article => \n      recommendations.includes(article.url)\n    );\n  }\n  \n  getPopularArticles(articles, limit) {\n    \u002F\u002F Return most read articles\n    const popularity = new Map();\n    \n    for (const [articleUrl, users] of this.articleUserMatrix) {\n      popularity.set(articleUrl, users.size);\n    }\n    \n    return articles\n      .sort((a, b) => {\n        const popA = popularity.get(a.url) || 0;\n        const popB = popularity.get(b.url) || 0;\n        return popB - popA;\n      })\n      .slice(0, limit);\n  }\n}\n\n\u002F\u002F Usage\nconst cfRecommender = new CollaborativeFilteringRecommender();\n\n\u002F\u002F Record interactions\ncfRecommender.recordInteraction('user1', 'article-url-1');\ncfRecommender.recordInteraction('user1', 'article-url-2');\ncfRecommender.recordInteraction('user2', 'article-url-1');\ncfRecommender.recordInteraction('user2', 'article-url-3');\n\n\u002F\u002F Get recommendations\nconst recommendations = cfRecommender.recommend('user1', allArticles, 10);\n",[205,7366,7367,7372,7376,7381,7386,7390,7394,7399,7404,7409,7414,7419,7423,7428,7432,7437,7442,7447,7451,7456,7460,7464,7469,7474,7479,7484,7488,7493,7497,7502,7507,7512,7516,7520,7525,7530,7534,7539,7543,7547,7552,7557,7562,7566,7571,7576,7581,7586,7591,7596,7601,7605,7609,7614,7619,7624,7628,7632,7637,7642,7647,7652,7656,7661,7666,7671,7675,7679,7684,7689,7693,7698,7703,7707,7712,7717,7722,7726,7731,7736,7740,7744,7748,7753,7758,7762,7766,7771,7775,7780,7785,7790,7794,7798,7802,7807,7812,7817,7821,7826,7831,7835,7839,7844,7849,7854,7859,7864,7869,7873,7877,7881,7885,7889,7894,7898,7903,7908,7913,7918,7923,7927,7931],{"__ignoreMap":203},[208,7368,7369],{"class":210,"line":211},[208,7370,7371],{},"class CollaborativeFilteringRecommender {\n",[208,7373,7374],{"class":210,"line":218},[208,7375,3487],{},[208,7377,7378],{"class":210,"line":228},[208,7379,7380],{},"    this.userArticleMatrix = new Map(); \u002F\u002F userId -> Set of article URLs\n",[208,7382,7383],{"class":210,"line":236},[208,7384,7385],{},"    this.articleUserMatrix = new Map(); \u002F\u002F article URL -> Set of userIds\n",[208,7387,7388],{"class":210,"line":252},[208,7389,298],{},[208,7391,7392],{"class":210,"line":261},[208,7393,1042],{},[208,7395,7396],{"class":210,"line":269},[208,7397,7398],{},"  \u002F\u002F Record user interaction with article\n",[208,7400,7401],{"class":210,"line":277},[208,7402,7403],{},"  recordInteraction(userId, articleUrl) {\n",[208,7405,7406],{"class":210,"line":283},[208,7407,7408],{},"    \u002F\u002F Update user-article matrix\n",[208,7410,7411],{"class":210,"line":289},[208,7412,7413],{},"    if (!this.userArticleMatrix.has(userId)) {\n",[208,7415,7416],{"class":210,"line":295},[208,7417,7418],{},"      this.userArticleMatrix.set(userId, new Set());\n",[208,7420,7421],{"class":210,"line":301},[208,7422,292],{},[208,7424,7425],{"class":210,"line":1078},[208,7426,7427],{},"    this.userArticleMatrix.get(userId).add(articleUrl);\n",[208,7429,7430],{"class":210,"line":1084},[208,7431,3543],{},[208,7433,7434],{"class":210,"line":1089},[208,7435,7436],{},"    \u002F\u002F Update article-user matrix\n",[208,7438,7439],{"class":210,"line":1095},[208,7440,7441],{},"    if (!this.articleUserMatrix.has(articleUrl)) {\n",[208,7443,7444],{"class":210,"line":1481},[208,7445,7446],{},"      this.articleUserMatrix.set(articleUrl, new Set());\n",[208,7448,7449],{"class":210,"line":1501},[208,7450,292],{},[208,7452,7453],{"class":210,"line":1521},[208,7454,7455],{},"    this.articleUserMatrix.get(articleUrl).add(userId);\n",[208,7457,7458],{"class":210,"line":1541},[208,7459,298],{},[208,7461,7462],{"class":210,"line":1561},[208,7463,1042],{},[208,7465,7466],{"class":210,"line":1581},[208,7467,7468],{},"  \u002F\u002F Calculate similarity between two users (Jaccard similarity)\n",[208,7470,7471],{"class":210,"line":1601},[208,7472,7473],{},"  calculateUserSimilarity(userId1, userId2) {\n",[208,7475,7476],{"class":210,"line":1621},[208,7477,7478],{},"    const articles1 = this.userArticleMatrix.get(userId1) || new Set();\n",[208,7480,7481],{"class":210,"line":1641},[208,7482,7483],{},"    const articles2 = this.userArticleMatrix.get(userId2) || new Set();\n",[208,7485,7486],{"class":210,"line":1661},[208,7487,3543],{},[208,7489,7490],{"class":210,"line":1682},[208,7491,7492],{},"    if (articles1.size === 0 || articles2.size === 0) return 0;\n",[208,7494,7495],{"class":210,"line":1688},[208,7496,3543],{},[208,7498,7499],{"class":210,"line":1693},[208,7500,7501],{},"    \u002F\u002F Intersection\n",[208,7503,7504],{"class":210,"line":1718},[208,7505,7506],{},"    const intersection = new Set(\n",[208,7508,7509],{"class":210,"line":1736},[208,7510,7511],{},"      [...articles1].filter(x => articles2.has(x))\n",[208,7513,7514],{"class":210,"line":1745},[208,7515,7193],{},[208,7517,7518],{"class":210,"line":1751},[208,7519,3543],{},[208,7521,7522],{"class":210,"line":1756},[208,7523,7524],{},"    \u002F\u002F Union\n",[208,7526,7527],{"class":210,"line":1765},[208,7528,7529],{},"    const union = new Set([...articles1, ...articles2]);\n",[208,7531,7532],{"class":210,"line":1787},[208,7533,3543],{},[208,7535,7536],{"class":210,"line":1799},[208,7537,7538],{},"    return intersection.size \u002F union.size;\n",[208,7540,7541],{"class":210,"line":1810},[208,7542,298],{},[208,7544,7545],{"class":210,"line":1833},[208,7546,1042],{},[208,7548,7549],{"class":210,"line":1839},[208,7550,7551],{},"  \u002F\u002F Find similar users\n",[208,7553,7554],{"class":210,"line":1858},[208,7555,7556],{},"  findSimilarUsers(userId, limit = 10) {\n",[208,7558,7559],{"class":210,"line":1883},[208,7560,7561],{},"    const similarities = [];\n",[208,7563,7564],{"class":210,"line":1889},[208,7565,3543],{},[208,7567,7568],{"class":210,"line":1899},[208,7569,7570],{},"    for (const [otherUserId] of this.userArticleMatrix) {\n",[208,7572,7573],{"class":210,"line":1905},[208,7574,7575],{},"      if (otherUserId === userId) continue;\n",[208,7577,7578],{"class":210,"line":1915},[208,7579,7580],{},"      \n",[208,7582,7583],{"class":210,"line":1925},[208,7584,7585],{},"      const similarity = this.calculateUserSimilarity(userId, otherUserId);\n",[208,7587,7588],{"class":210,"line":1930},[208,7589,7590],{},"      if (similarity > 0) {\n",[208,7592,7593],{"class":210,"line":1935},[208,7594,7595],{},"        similarities.push({ userId: otherUserId, similarity });\n",[208,7597,7598],{"class":210,"line":1940},[208,7599,7600],{},"      }\n",[208,7602,7603],{"class":210,"line":2230},[208,7604,292],{},[208,7606,7607],{"class":210,"line":2236},[208,7608,3543],{},[208,7610,7611],{"class":210,"line":2242},[208,7612,7613],{},"    return similarities\n",[208,7615,7616],{"class":210,"line":2247},[208,7617,7618],{},"      .sort((a, b) => b.similarity - a.similarity)\n",[208,7620,7621],{"class":210,"line":2253},[208,7622,7623],{},"      .slice(0, limit);\n",[208,7625,7626],{"class":210,"line":2258},[208,7627,298],{},[208,7629,7630],{"class":210,"line":3213},[208,7631,1042],{},[208,7633,7634],{"class":210,"line":3219},[208,7635,7636],{},"  \u002F\u002F Get recommendations based on similar users\n",[208,7638,7639],{"class":210,"line":5034},[208,7640,7641],{},"  recommend(userId, allArticles, limit = 10) {\n",[208,7643,7644],{"class":210,"line":5713},[208,7645,7646],{},"    const userArticles = this.userArticleMatrix.get(userId) || new Set();\n",[208,7648,7649],{"class":210,"line":5729},[208,7650,7651],{},"    const similarUsers = this.findSimilarUsers(userId, 20);\n",[208,7653,7654],{"class":210,"line":5737},[208,7655,3543],{},[208,7657,7658],{"class":210,"line":5748},[208,7659,7660],{},"    if (similarUsers.length === 0) {\n",[208,7662,7663],{"class":210,"line":5759},[208,7664,7665],{},"      \u002F\u002F No similar users, return popular articles\n",[208,7667,7668],{"class":210,"line":5770},[208,7669,7670],{},"      return this.getPopularArticles(allArticles, limit);\n",[208,7672,7673],{"class":210,"line":5781},[208,7674,292],{},[208,7676,7677],{"class":210,"line":5786},[208,7678,3543],{},[208,7680,7681],{"class":210,"line":5791},[208,7682,7683],{},"    \u002F\u002F Score articles based on similar users\n",[208,7685,7686],{"class":210,"line":5817},[208,7687,7688],{},"    const articleScores = new Map();\n",[208,7690,7691],{"class":210,"line":5825},[208,7692,3543],{},[208,7694,7695],{"class":210,"line":5836},[208,7696,7697],{},"    similarUsers.forEach(({ userId: similarUserId, similarity }) => {\n",[208,7699,7700],{"class":210,"line":5847},[208,7701,7702],{},"      const articles = this.userArticleMatrix.get(similarUserId) || new Set();\n",[208,7704,7705],{"class":210,"line":5858},[208,7706,7580],{},[208,7708,7709],{"class":210,"line":5879},[208,7710,7711],{},"      articles.forEach(articleUrl => {\n",[208,7713,7714],{"class":210,"line":5890},[208,7715,7716],{},"        \u002F\u002F Skip articles user has already seen\n",[208,7718,7719],{"class":210,"line":5896},[208,7720,7721],{},"        if (userArticles.has(articleUrl)) return;\n",[208,7723,7724],{"class":210,"line":5921},[208,7725,6007],{},[208,7727,7728],{"class":210,"line":5927},[208,7729,7730],{},"        const currentScore = articleScores.get(articleUrl) || 0;\n",[208,7732,7733],{"class":210,"line":5936},[208,7734,7735],{},"        articleScores.set(articleUrl, currentScore + similarity);\n",[208,7737,7738],{"class":210,"line":5945},[208,7739,6959],{},[208,7741,7742],{"class":210,"line":5954},[208,7743,3603],{},[208,7745,7746],{"class":210,"line":5959},[208,7747,3543],{},[208,7749,7750],{"class":210,"line":5976},[208,7751,7752],{},"    \u002F\u002F Get top scored articles\n",[208,7754,7755],{"class":210,"line":6004},[208,7756,7757],{},"    const recommendations = Array.from(articleScores.entries())\n",[208,7759,7760],{"class":210,"line":6010},[208,7761,6896],{},[208,7763,7764],{"class":210,"line":6036},[208,7765,7282],{},[208,7767,7768],{"class":210,"line":6041},[208,7769,7770],{},"      .map(([url]) => url);\n",[208,7772,7773],{"class":210,"line":6074},[208,7774,3543],{},[208,7776,7777],{"class":210,"line":6095},[208,7778,7779],{},"    \u002F\u002F Map URLs back to article objects\n",[208,7781,7782],{"class":210,"line":6101},[208,7783,7784],{},"    return allArticles.filter(article => \n",[208,7786,7787],{"class":210,"line":6106},[208,7788,7789],{},"      recommendations.includes(article.url)\n",[208,7791,7792],{"class":210,"line":6136},[208,7793,7193],{},[208,7795,7796],{"class":210,"line":6152},[208,7797,298],{},[208,7799,7800],{"class":210,"line":6176},[208,7801,1042],{},[208,7803,7804],{"class":210,"line":6199},[208,7805,7806],{},"  getPopularArticles(articles, limit) {\n",[208,7808,7809],{"class":210,"line":6205},[208,7810,7811],{},"    \u002F\u002F Return most read articles\n",[208,7813,7814],{"class":210,"line":6214},[208,7815,7816],{},"    const popularity = new Map();\n",[208,7818,7819],{"class":210,"line":6219},[208,7820,3543],{},[208,7822,7823],{"class":210,"line":6228},[208,7824,7825],{},"    for (const [articleUrl, users] of this.articleUserMatrix) {\n",[208,7827,7828],{"class":210,"line":6237},[208,7829,7830],{},"      popularity.set(articleUrl, users.size);\n",[208,7832,7833],{"class":210,"line":6242},[208,7834,292],{},[208,7836,7837],{"class":210,"line":6247},[208,7838,3543],{},[208,7840,7841],{"class":210,"line":6252},[208,7842,7843],{},"    return articles\n",[208,7845,7846],{"class":210,"line":7238},[208,7847,7848],{},"      .sort((a, b) => {\n",[208,7850,7851],{"class":210,"line":7244},[208,7852,7853],{},"        const popA = popularity.get(a.url) || 0;\n",[208,7855,7856],{"class":210,"line":7250},[208,7857,7858],{},"        const popB = popularity.get(b.url) || 0;\n",[208,7860,7861],{"class":210,"line":7256},[208,7862,7863],{},"        return popB - popA;\n",[208,7865,7866],{"class":210,"line":7262},[208,7867,7868],{},"      })\n",[208,7870,7871],{"class":210,"line":7267},[208,7872,7623],{},[208,7874,7875],{"class":210,"line":7273},[208,7876,298],{},[208,7878,7879],{"class":210,"line":7279},[208,7880,304],{},[208,7882,7883],{"class":210,"line":7285},[208,7884,1092],{"emptyLinePlaceholder":866},[208,7886,7887],{"class":210,"line":7291},[208,7888,2912],{},[208,7890,7891],{"class":210,"line":7296},[208,7892,7893],{},"const cfRecommender = new CollaborativeFilteringRecommender();\n",[208,7895,7896],{"class":210,"line":7301},[208,7897,1092],{"emptyLinePlaceholder":866},[208,7899,7900],{"class":210,"line":7306},[208,7901,7902],{},"\u002F\u002F Record interactions\n",[208,7904,7905],{"class":210,"line":7311},[208,7906,7907],{},"cfRecommender.recordInteraction('user1', 'article-url-1');\n",[208,7909,7910],{"class":210,"line":7317},[208,7911,7912],{},"cfRecommender.recordInteraction('user1', 'article-url-2');\n",[208,7914,7915],{"class":210,"line":7322},[208,7916,7917],{},"cfRecommender.recordInteraction('user2', 'article-url-1');\n",[208,7919,7920],{"class":210,"line":7328},[208,7921,7922],{},"cfRecommender.recordInteraction('user2', 'article-url-3');\n",[208,7924,7925],{"class":210,"line":7334},[208,7926,1092],{"emptyLinePlaceholder":866},[208,7928,7929],{"class":210,"line":7340},[208,7930,7348],{},[208,7932,7933],{"class":210,"line":7345},[208,7934,7935],{},"const recommendations = cfRecommender.recommend('user1', allArticles, 10);\n",[94,7937,7939],{"id":7938},"_3-hybrid-approach","3. Hybrid Approach",[12,7941,7942],{},"Combine multiple recommendation strategies:",[198,7944,7946],{"className":1013,"code":7945,"language":1015,"meta":203,"style":203},"class HybridRecommender {\n  constructor() {\n    this.contentBased = new ContentBasedRecommender();\n    this.collaborative = new CollaborativeFilteringRecommender();\n  }\n  \n  recordInteraction(userId, article, interactionType) {\n    \u002F\u002F Update both recommenders\n    this.contentBased.updateUserProfile(userId, article, interactionType);\n    this.collaborative.recordInteraction(userId, article.url);\n  }\n  \n  recommend(userId, articles, limit = 10) {\n    \u002F\u002F Get recommendations from both systems\n    const contentRecs = this.contentBased.recommend(userId, articles, limit * 2);\n    const collabRecs = this.collaborative.recommend(userId, articles, limit * 2);\n    \n    \u002F\u002F Combine and deduplicate\n    const combined = new Map();\n    \n    \u002F\u002F Add content-based recommendations (weight: 0.6)\n    contentRecs.forEach((article, index) => {\n      const score = (contentRecs.length - index) * 0.6;\n      combined.set(article.url, { article, score });\n    });\n    \n    \u002F\u002F Add collaborative recommendations (weight: 0.4)\n    collabRecs.forEach((article, index) => {\n      const score = (collabRecs.length - index) * 0.4;\n      const existing = combined.get(article.url);\n      \n      if (existing) {\n        existing.score += score;\n      } else {\n        combined.set(article.url, { article, score });\n      }\n    });\n    \n    \u002F\u002F Sort by combined score and return top N\n    return Array.from(combined.values())\n      .sort((a, b) => b.score - a.score)\n      .slice(0, limit)\n      .map(item => item.article);\n  }\n}\n\n\u002F\u002F Usage\nconst recommender = new HybridRecommender();\n\n\u002F\u002F Track interactions\nrecommender.recordInteraction('user123', article, 'read');\n\n\u002F\u002F Get personalized feed\nconst personalizedFeed = recommender.recommend('user123', allArticles, 20);\n",[205,7947,7948,7953,7957,7962,7967,7971,7975,7980,7985,7990,7995,7999,8003,8007,8012,8017,8022,8026,8031,8036,8040,8045,8050,8055,8060,8064,8068,8073,8078,8083,8088,8092,8097,8102,8107,8112,8116,8120,8124,8129,8134,8138,8142,8146,8150,8154,8158,8162,8167,8171,8176,8181,8185,8190],{"__ignoreMap":203},[208,7949,7950],{"class":210,"line":211},[208,7951,7952],{},"class HybridRecommender {\n",[208,7954,7955],{"class":210,"line":218},[208,7956,3487],{},[208,7958,7959],{"class":210,"line":228},[208,7960,7961],{},"    this.contentBased = new ContentBasedRecommender();\n",[208,7963,7964],{"class":210,"line":236},[208,7965,7966],{},"    this.collaborative = new CollaborativeFilteringRecommender();\n",[208,7968,7969],{"class":210,"line":252},[208,7970,298],{},[208,7972,7973],{"class":210,"line":261},[208,7974,1042],{},[208,7976,7977],{"class":210,"line":269},[208,7978,7979],{},"  recordInteraction(userId, article, interactionType) {\n",[208,7981,7982],{"class":210,"line":277},[208,7983,7984],{},"    \u002F\u002F Update both recommenders\n",[208,7986,7987],{"class":210,"line":283},[208,7988,7989],{},"    this.contentBased.updateUserProfile(userId, article, interactionType);\n",[208,7991,7992],{"class":210,"line":289},[208,7993,7994],{},"    this.collaborative.recordInteraction(userId, article.url);\n",[208,7996,7997],{"class":210,"line":295},[208,7998,298],{},[208,8000,8001],{"class":210,"line":301},[208,8002,1042],{},[208,8004,8005],{"class":210,"line":1078},[208,8006,7235],{},[208,8008,8009],{"class":210,"line":1084},[208,8010,8011],{},"    \u002F\u002F Get recommendations from both systems\n",[208,8013,8014],{"class":210,"line":1089},[208,8015,8016],{},"    const contentRecs = this.contentBased.recommend(userId, articles, limit * 2);\n",[208,8018,8019],{"class":210,"line":1095},[208,8020,8021],{},"    const collabRecs = this.collaborative.recommend(userId, articles, limit * 2);\n",[208,8023,8024],{"class":210,"line":1481},[208,8025,3543],{},[208,8027,8028],{"class":210,"line":1501},[208,8029,8030],{},"    \u002F\u002F Combine and deduplicate\n",[208,8032,8033],{"class":210,"line":1521},[208,8034,8035],{},"    const combined = new Map();\n",[208,8037,8038],{"class":210,"line":1541},[208,8039,3543],{},[208,8041,8042],{"class":210,"line":1561},[208,8043,8044],{},"    \u002F\u002F Add content-based recommendations (weight: 0.6)\n",[208,8046,8047],{"class":210,"line":1581},[208,8048,8049],{},"    contentRecs.forEach((article, index) => {\n",[208,8051,8052],{"class":210,"line":1601},[208,8053,8054],{},"      const score = (contentRecs.length - index) * 0.6;\n",[208,8056,8057],{"class":210,"line":1621},[208,8058,8059],{},"      combined.set(article.url, { article, score });\n",[208,8061,8062],{"class":210,"line":1641},[208,8063,3603],{},[208,8065,8066],{"class":210,"line":1661},[208,8067,3543],{},[208,8069,8070],{"class":210,"line":1682},[208,8071,8072],{},"    \u002F\u002F Add collaborative recommendations (weight: 0.4)\n",[208,8074,8075],{"class":210,"line":1688},[208,8076,8077],{},"    collabRecs.forEach((article, index) => {\n",[208,8079,8080],{"class":210,"line":1693},[208,8081,8082],{},"      const score = (collabRecs.length - index) * 0.4;\n",[208,8084,8085],{"class":210,"line":1718},[208,8086,8087],{},"      const existing = combined.get(article.url);\n",[208,8089,8090],{"class":210,"line":1736},[208,8091,7580],{},[208,8093,8094],{"class":210,"line":1745},[208,8095,8096],{},"      if (existing) {\n",[208,8098,8099],{"class":210,"line":1751},[208,8100,8101],{},"        existing.score += score;\n",[208,8103,8104],{"class":210,"line":1756},[208,8105,8106],{},"      } else {\n",[208,8108,8109],{"class":210,"line":1765},[208,8110,8111],{},"        combined.set(article.url, { article, score });\n",[208,8113,8114],{"class":210,"line":1787},[208,8115,7600],{},[208,8117,8118],{"class":210,"line":1799},[208,8119,3603],{},[208,8121,8122],{"class":210,"line":1810},[208,8123,3543],{},[208,8125,8126],{"class":210,"line":1833},[208,8127,8128],{},"    \u002F\u002F Sort by combined score and return top N\n",[208,8130,8131],{"class":210,"line":1839},[208,8132,8133],{},"    return Array.from(combined.values())\n",[208,8135,8136],{"class":210,"line":1858},[208,8137,7276],{},[208,8139,8140],{"class":210,"line":1883},[208,8141,7282],{},[208,8143,8144],{"class":210,"line":1889},[208,8145,7288],{},[208,8147,8148],{"class":210,"line":1899},[208,8149,298],{},[208,8151,8152],{"class":210,"line":1905},[208,8153,304],{},[208,8155,8156],{"class":210,"line":1915},[208,8157,1092],{"emptyLinePlaceholder":866},[208,8159,8160],{"class":210,"line":1925},[208,8161,2912],{},[208,8163,8164],{"class":210,"line":1930},[208,8165,8166],{},"const recommender = new HybridRecommender();\n",[208,8168,8169],{"class":210,"line":1935},[208,8170,1092],{"emptyLinePlaceholder":866},[208,8172,8173],{"class":210,"line":1940},[208,8174,8175],{},"\u002F\u002F Track interactions\n",[208,8177,8178],{"class":210,"line":2230},[208,8179,8180],{},"recommender.recordInteraction('user123', article, 'read');\n",[208,8182,8183],{"class":210,"line":2236},[208,8184,1092],{"emptyLinePlaceholder":866},[208,8186,8187],{"class":210,"line":2242},[208,8188,8189],{},"\u002F\u002F Get personalized feed\n",[208,8191,8192],{"class":210,"line":2247},[208,8193,8194],{},"const personalizedFeed = recommender.recommend('user123', allArticles, 20);\n",[21,8196,8198],{"id":8197},"building-a-complete-personalization-system","Building a Complete Personalization System",[94,8200,8202],{"id":8201},"backend-service","Backend Service",[198,8204,8206],{"className":1013,"code":8205,"language":1015,"meta":203,"style":203},"\u002F\u002F personalization-service.js\nconst express = require('express');\nconst app = express();\nconst HybridRecommender = require('.\u002Frecommender');\nconst newsApi = require('.\u002Fnews-api');\n\nconst recommender = new HybridRecommender();\n\n\u002F\u002F Track article view\napp.post('\u002Fapi\u002Ftrack\u002Fview', async (req, res) => {\n  const { userId, articleUrl } = req.body;\n  \n  try {\n    const article = await getArticleByUrl(articleUrl);\n    recommender.recordInteraction(userId, article, 'read');\n    res.json({ success: true });\n  } catch (error) {\n    res.status(500).json({ error: error.message });\n  }\n});\n\n\u002F\u002F Track article interaction\napp.post('\u002Fapi\u002Ftrack\u002Finteraction', async (req, res) => {\n  const { userId, articleUrl, type } = req.body;\n  \n  try {\n    const article = await getArticleByUrl(articleUrl);\n    recommender.recordInteraction(userId, article, type);\n    res.json({ success: true });\n  } catch (error) {\n    res.status(500).json({ error: error.message });\n  }\n});\n\n\u002F\u002F Get personalized feed\napp.get('\u002Fapi\u002Ffeed\u002Fpersonalized', async (req, res) => {\n  const { userId, limit = 20 } = req.query;\n  \n  try {\n    \u002F\u002F Fetch latest articles\n    const articles = await newsApi.getHeadlines('us');\n    \n    \u002F\u002F Get personalized recommendations\n    const recommendations = recommender.recommend(\n      userId, \n      articles.articles, \n      parseInt(limit)\n    );\n    \n    res.json({ articles: recommendations });\n  } catch (error) {\n    res.status(500).json({ error: error.message });\n  }\n});\n\napp.listen(3000, () => {\n  console.log('Personalization service running on port 3000');\n});\n",[205,8207,8208,8213,8218,8223,8228,8233,8237,8241,8245,8250,8255,8260,8264,8268,8273,8278,8283,8287,8292,8296,8300,8304,8309,8314,8319,8323,8327,8331,8336,8340,8344,8348,8352,8356,8360,8364,8369,8374,8378,8382,8387,8392,8396,8401,8406,8411,8416,8421,8425,8429,8434,8438,8442,8446,8450,8454,8459,8464],{"__ignoreMap":203},[208,8209,8210],{"class":210,"line":211},[208,8211,8212],{},"\u002F\u002F personalization-service.js\n",[208,8214,8215],{"class":210,"line":218},[208,8216,8217],{},"const express = require('express');\n",[208,8219,8220],{"class":210,"line":228},[208,8221,8222],{},"const app = express();\n",[208,8224,8225],{"class":210,"line":236},[208,8226,8227],{},"const HybridRecommender = require('.\u002Frecommender');\n",[208,8229,8230],{"class":210,"line":252},[208,8231,8232],{},"const newsApi = require('.\u002Fnews-api');\n",[208,8234,8235],{"class":210,"line":261},[208,8236,1092],{"emptyLinePlaceholder":866},[208,8238,8239],{"class":210,"line":269},[208,8240,8166],{},[208,8242,8243],{"class":210,"line":277},[208,8244,1092],{"emptyLinePlaceholder":866},[208,8246,8247],{"class":210,"line":283},[208,8248,8249],{},"\u002F\u002F Track article view\n",[208,8251,8252],{"class":210,"line":289},[208,8253,8254],{},"app.post('\u002Fapi\u002Ftrack\u002Fview', async (req, res) => {\n",[208,8256,8257],{"class":210,"line":295},[208,8258,8259],{},"  const { userId, articleUrl } = req.body;\n",[208,8261,8262],{"class":210,"line":301},[208,8263,1042],{},[208,8265,8266],{"class":210,"line":1078},[208,8267,3882],{},[208,8269,8270],{"class":210,"line":1084},[208,8271,8272],{},"    const article = await getArticleByUrl(articleUrl);\n",[208,8274,8275],{"class":210,"line":1089},[208,8276,8277],{},"    recommender.recordInteraction(userId, article, 'read');\n",[208,8279,8280],{"class":210,"line":1095},[208,8281,8282],{},"    res.json({ success: true });\n",[208,8284,8285],{"class":210,"line":1481},[208,8286,3911],{},[208,8288,8289],{"class":210,"line":1501},[208,8290,8291],{},"    res.status(500).json({ error: error.message });\n",[208,8293,8294],{"class":210,"line":1521},[208,8295,298],{},[208,8297,8298],{"class":210,"line":1541},[208,8299,3868],{},[208,8301,8302],{"class":210,"line":1561},[208,8303,1092],{"emptyLinePlaceholder":866},[208,8305,8306],{"class":210,"line":1581},[208,8307,8308],{},"\u002F\u002F Track article interaction\n",[208,8310,8311],{"class":210,"line":1601},[208,8312,8313],{},"app.post('\u002Fapi\u002Ftrack\u002Finteraction', async (req, res) => {\n",[208,8315,8316],{"class":210,"line":1621},[208,8317,8318],{},"  const { userId, articleUrl, type } = req.body;\n",[208,8320,8321],{"class":210,"line":1641},[208,8322,1042],{},[208,8324,8325],{"class":210,"line":1661},[208,8326,3882],{},[208,8328,8329],{"class":210,"line":1682},[208,8330,8272],{},[208,8332,8333],{"class":210,"line":1688},[208,8334,8335],{},"    recommender.recordInteraction(userId, article, type);\n",[208,8337,8338],{"class":210,"line":1693},[208,8339,8282],{},[208,8341,8342],{"class":210,"line":1718},[208,8343,3911],{},[208,8345,8346],{"class":210,"line":1736},[208,8347,8291],{},[208,8349,8350],{"class":210,"line":1745},[208,8351,298],{},[208,8353,8354],{"class":210,"line":1751},[208,8355,3868],{},[208,8357,8358],{"class":210,"line":1756},[208,8359,1092],{"emptyLinePlaceholder":866},[208,8361,8362],{"class":210,"line":1765},[208,8363,8189],{},[208,8365,8366],{"class":210,"line":1787},[208,8367,8368],{},"app.get('\u002Fapi\u002Ffeed\u002Fpersonalized', async (req, res) => {\n",[208,8370,8371],{"class":210,"line":1799},[208,8372,8373],{},"  const { userId, limit = 20 } = req.query;\n",[208,8375,8376],{"class":210,"line":1810},[208,8377,1042],{},[208,8379,8380],{"class":210,"line":1833},[208,8381,3882],{},[208,8383,8384],{"class":210,"line":1839},[208,8385,8386],{},"    \u002F\u002F Fetch latest articles\n",[208,8388,8389],{"class":210,"line":1858},[208,8390,8391],{},"    const articles = await newsApi.getHeadlines('us');\n",[208,8393,8394],{"class":210,"line":1883},[208,8395,3543],{},[208,8397,8398],{"class":210,"line":1889},[208,8399,8400],{},"    \u002F\u002F Get personalized recommendations\n",[208,8402,8403],{"class":210,"line":1899},[208,8404,8405],{},"    const recommendations = recommender.recommend(\n",[208,8407,8408],{"class":210,"line":1905},[208,8409,8410],{},"      userId, \n",[208,8412,8413],{"class":210,"line":1915},[208,8414,8415],{},"      articles.articles, \n",[208,8417,8418],{"class":210,"line":1925},[208,8419,8420],{},"      parseInt(limit)\n",[208,8422,8423],{"class":210,"line":1930},[208,8424,7193],{},[208,8426,8427],{"class":210,"line":1935},[208,8428,3543],{},[208,8430,8431],{"class":210,"line":1940},[208,8432,8433],{},"    res.json({ articles: recommendations });\n",[208,8435,8436],{"class":210,"line":2230},[208,8437,3911],{},[208,8439,8440],{"class":210,"line":2236},[208,8441,8291],{},[208,8443,8444],{"class":210,"line":2242},[208,8445,298],{},[208,8447,8448],{"class":210,"line":2247},[208,8449,3868],{},[208,8451,8452],{"class":210,"line":2253},[208,8453,1092],{"emptyLinePlaceholder":866},[208,8455,8456],{"class":210,"line":2258},[208,8457,8458],{},"app.listen(3000, () => {\n",[208,8460,8461],{"class":210,"line":3213},[208,8462,8463],{},"  console.log('Personalization service running on port 3000');\n",[208,8465,8466],{"class":210,"line":3219},[208,8467,3868],{},[94,8469,8471],{"id":8470},"frontend-integration","Frontend Integration",[198,8473,8475],{"className":1013,"code":8474,"language":1015,"meta":203,"style":203},"\u002F\u002F PersonalizedFeed.jsx\nimport React, { useState, useEffect } from 'react';\nimport ArticleCard from '.\u002FArticleCard';\n\nfunction PersonalizedFeed({ userId }) {\n  const [articles, setArticles] = useState([]);\n  const [loading, setLoading] = useState(true);\n  \n  useEffect(() => {\n    fetchPersonalizedFeed();\n  }, [userId]);\n  \n  async function fetchPersonalizedFeed() {\n    try {\n      const response = await fetch(\n        `\u002Fapi\u002Ffeed\u002Fpersonalized?userId=${userId}&limit=20`\n      );\n      const data = await response.json();\n      setArticles(data.articles);\n    } catch (error) {\n      console.error('Error fetching feed:', error);\n    } finally {\n      setLoading(false);\n    }\n  }\n  \n  async function trackView(article) {\n    await fetch('\u002Fapi\u002Ftrack\u002Fview', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify({\n        userId,\n        articleUrl: article.url\n      })\n    });\n  }\n  \n  async function trackInteraction(article, type) {\n    await fetch('\u002Fapi\u002Ftrack\u002Finteraction', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application\u002Fjson' },\n      body: JSON.stringify({\n        userId,\n        articleUrl: article.url,\n        type\n      })\n    });\n  }\n  \n  function handleArticleClick(article) {\n    trackView(article);\n    window.open(article.url, '_blank');\n  }\n  \n  function handleLike(article) {\n    trackInteraction(article, 'like');\n  }\n  \n  function handleShare(article) {\n    trackInteraction(article, 'share');\n  }\n  \n  if (loading) return \u003Cdiv>Loading your personalized feed...\u003C\u002Fdiv>;\n  \n  return (\n    \u003Cdiv className=\"personalized-feed\">\n      \u003Ch2>Your Personalized News Feed\u003C\u002Fh2>\n      \u003Cdiv className=\"articles\">\n        {articles.map(article => (\n          \u003CArticleCard\n            key={article.url}\n            article={article}\n            onClick={() => handleArticleClick(article)}\n            onLike={() => handleLike(article)}\n            onShare={() => handleShare(article)}\n          \u002F>\n        ))}\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  );\n}\n\nexport default PersonalizedFeed;\n",[205,8476,8477,8482,8487,8492,8496,8501,8506,8511,8515,8520,8525,8530,8534,8539,8544,8549,8554,8559,8564,8569,8574,8579,8584,8589,8593,8597,8601,8606,8611,8616,8621,8626,8631,8636,8640,8644,8648,8652,8657,8662,8666,8670,8674,8678,8683,8688,8692,8696,8700,8704,8709,8714,8719,8723,8727,8732,8737,8741,8745,8750,8755,8759,8763,8768,8772,8777,8782,8787,8792,8797,8802,8807,8812,8817,8822,8827,8831,8835,8840,8845,8849,8853,8857],{"__ignoreMap":203},[208,8478,8479],{"class":210,"line":211},[208,8480,8481],{},"\u002F\u002F PersonalizedFeed.jsx\n",[208,8483,8484],{"class":210,"line":218},[208,8485,8486],{},"import React, { useState, useEffect } from 'react';\n",[208,8488,8489],{"class":210,"line":228},[208,8490,8491],{},"import ArticleCard from '.\u002FArticleCard';\n",[208,8493,8494],{"class":210,"line":236},[208,8495,1092],{"emptyLinePlaceholder":866},[208,8497,8498],{"class":210,"line":252},[208,8499,8500],{},"function PersonalizedFeed({ userId }) {\n",[208,8502,8503],{"class":210,"line":261},[208,8504,8505],{},"  const [articles, setArticles] = useState([]);\n",[208,8507,8508],{"class":210,"line":269},[208,8509,8510],{},"  const [loading, setLoading] = useState(true);\n",[208,8512,8513],{"class":210,"line":277},[208,8514,1042],{},[208,8516,8517],{"class":210,"line":283},[208,8518,8519],{},"  useEffect(() => {\n",[208,8521,8522],{"class":210,"line":289},[208,8523,8524],{},"    fetchPersonalizedFeed();\n",[208,8526,8527],{"class":210,"line":295},[208,8528,8529],{},"  }, [userId]);\n",[208,8531,8532],{"class":210,"line":301},[208,8533,1042],{},[208,8535,8536],{"class":210,"line":1078},[208,8537,8538],{},"  async function fetchPersonalizedFeed() {\n",[208,8540,8541],{"class":210,"line":1084},[208,8542,8543],{},"    try {\n",[208,8545,8546],{"class":210,"line":1089},[208,8547,8548],{},"      const response = await fetch(\n",[208,8550,8551],{"class":210,"line":1095},[208,8552,8553],{},"        `\u002Fapi\u002Ffeed\u002Fpersonalized?userId=${userId}&limit=20`\n",[208,8555,8556],{"class":210,"line":1481},[208,8557,8558],{},"      );\n",[208,8560,8561],{"class":210,"line":1501},[208,8562,8563],{},"      const data = await response.json();\n",[208,8565,8566],{"class":210,"line":1521},[208,8567,8568],{},"      setArticles(data.articles);\n",[208,8570,8571],{"class":210,"line":1541},[208,8572,8573],{},"    } catch (error) {\n",[208,8575,8576],{"class":210,"line":1561},[208,8577,8578],{},"      console.error('Error fetching feed:', error);\n",[208,8580,8581],{"class":210,"line":1581},[208,8582,8583],{},"    } finally {\n",[208,8585,8586],{"class":210,"line":1601},[208,8587,8588],{},"      setLoading(false);\n",[208,8590,8591],{"class":210,"line":1621},[208,8592,292],{},[208,8594,8595],{"class":210,"line":1641},[208,8596,298],{},[208,8598,8599],{"class":210,"line":1661},[208,8600,1042],{},[208,8602,8603],{"class":210,"line":1682},[208,8604,8605],{},"  async function trackView(article) {\n",[208,8607,8608],{"class":210,"line":1688},[208,8609,8610],{},"    await fetch('\u002Fapi\u002Ftrack\u002Fview', {\n",[208,8612,8613],{"class":210,"line":1693},[208,8614,8615],{},"      method: 'POST',\n",[208,8617,8618],{"class":210,"line":1718},[208,8619,8620],{},"      headers: { 'Content-Type': 'application\u002Fjson' },\n",[208,8622,8623],{"class":210,"line":1736},[208,8624,8625],{},"      body: JSON.stringify({\n",[208,8627,8628],{"class":210,"line":1745},[208,8629,8630],{},"        userId,\n",[208,8632,8633],{"class":210,"line":1751},[208,8634,8635],{},"        articleUrl: article.url\n",[208,8637,8638],{"class":210,"line":1756},[208,8639,7868],{},[208,8641,8642],{"class":210,"line":1765},[208,8643,3603],{},[208,8645,8646],{"class":210,"line":1787},[208,8647,298],{},[208,8649,8650],{"class":210,"line":1799},[208,8651,1042],{},[208,8653,8654],{"class":210,"line":1810},[208,8655,8656],{},"  async function trackInteraction(article, type) {\n",[208,8658,8659],{"class":210,"line":1833},[208,8660,8661],{},"    await fetch('\u002Fapi\u002Ftrack\u002Finteraction', {\n",[208,8663,8664],{"class":210,"line":1839},[208,8665,8615],{},[208,8667,8668],{"class":210,"line":1858},[208,8669,8620],{},[208,8671,8672],{"class":210,"line":1883},[208,8673,8625],{},[208,8675,8676],{"class":210,"line":1889},[208,8677,8630],{},[208,8679,8680],{"class":210,"line":1899},[208,8681,8682],{},"        articleUrl: article.url,\n",[208,8684,8685],{"class":210,"line":1905},[208,8686,8687],{},"        type\n",[208,8689,8690],{"class":210,"line":1915},[208,8691,7868],{},[208,8693,8694],{"class":210,"line":1925},[208,8695,3603],{},[208,8697,8698],{"class":210,"line":1930},[208,8699,298],{},[208,8701,8702],{"class":210,"line":1935},[208,8703,1042],{},[208,8705,8706],{"class":210,"line":1940},[208,8707,8708],{},"  function handleArticleClick(article) {\n",[208,8710,8711],{"class":210,"line":2230},[208,8712,8713],{},"    trackView(article);\n",[208,8715,8716],{"class":210,"line":2236},[208,8717,8718],{},"    window.open(article.url, '_blank');\n",[208,8720,8721],{"class":210,"line":2242},[208,8722,298],{},[208,8724,8725],{"class":210,"line":2247},[208,8726,1042],{},[208,8728,8729],{"class":210,"line":2253},[208,8730,8731],{},"  function handleLike(article) {\n",[208,8733,8734],{"class":210,"line":2258},[208,8735,8736],{},"    trackInteraction(article, 'like');\n",[208,8738,8739],{"class":210,"line":3213},[208,8740,298],{},[208,8742,8743],{"class":210,"line":3219},[208,8744,1042],{},[208,8746,8747],{"class":210,"line":5034},[208,8748,8749],{},"  function handleShare(article) {\n",[208,8751,8752],{"class":210,"line":5713},[208,8753,8754],{},"    trackInteraction(article, 'share');\n",[208,8756,8757],{"class":210,"line":5729},[208,8758,298],{},[208,8760,8761],{"class":210,"line":5737},[208,8762,1042],{},[208,8764,8765],{"class":210,"line":5748},[208,8766,8767],{},"  if (loading) return \u003Cdiv>Loading your personalized feed...\u003C\u002Fdiv>;\n",[208,8769,8770],{"class":210,"line":5759},[208,8771,1042],{},[208,8773,8774],{"class":210,"line":5770},[208,8775,8776],{},"  return (\n",[208,8778,8779],{"class":210,"line":5781},[208,8780,8781],{},"    \u003Cdiv className=\"personalized-feed\">\n",[208,8783,8784],{"class":210,"line":5786},[208,8785,8786],{},"      \u003Ch2>Your Personalized News Feed\u003C\u002Fh2>\n",[208,8788,8789],{"class":210,"line":5791},[208,8790,8791],{},"      \u003Cdiv className=\"articles\">\n",[208,8793,8794],{"class":210,"line":5817},[208,8795,8796],{},"        {articles.map(article => (\n",[208,8798,8799],{"class":210,"line":5825},[208,8800,8801],{},"          \u003CArticleCard\n",[208,8803,8804],{"class":210,"line":5836},[208,8805,8806],{},"            key={article.url}\n",[208,8808,8809],{"class":210,"line":5847},[208,8810,8811],{},"            article={article}\n",[208,8813,8814],{"class":210,"line":5858},[208,8815,8816],{},"            onClick={() => handleArticleClick(article)}\n",[208,8818,8819],{"class":210,"line":5879},[208,8820,8821],{},"            onLike={() => handleLike(article)}\n",[208,8823,8824],{"class":210,"line":5890},[208,8825,8826],{},"            onShare={() => handleShare(article)}\n",[208,8828,8829],{"class":210,"line":5896},[208,8830,5893],{},[208,8832,8833],{"class":210,"line":5921},[208,8834,1902],{},[208,8836,8837],{"class":210,"line":5927},[208,8838,8839],{},"      \u003C\u002Fdiv>\n",[208,8841,8842],{"class":210,"line":5936},[208,8843,8844],{},"    \u003C\u002Fdiv>\n",[208,8846,8847],{"class":210,"line":5945},[208,8848,1130],{},[208,8850,8851],{"class":210,"line":5954},[208,8852,304],{},[208,8854,8855],{"class":210,"line":5959},[208,8856,1092],{"emptyLinePlaceholder":866},[208,8858,8859],{"class":210,"line":5976},[208,8860,8861],{},"export default PersonalizedFeed;\n",[21,8863,8865],{"id":8864},"advanced-features","Advanced Features",[94,8867,8869],{"id":8868},"_1-diversity-in-recommendations","1. Diversity in Recommendations",[12,8871,8872],{},"Avoid filter bubbles by ensuring diversity:",[198,8874,8876],{"className":1013,"code":8875,"language":1015,"meta":203,"style":203},"function diversifyRecommendations(articles, limit) {\n  const diverse = [];\n  const usedCategories = new Set();\n  const usedSources = new Set();\n  \n  for (const article of articles) {\n    if (diverse.length >= limit) break;\n    \n    \u002F\u002F Ensure category diversity\n    if (usedCategories.size \u003C 3 || !usedCategories.has(article.category)) {\n      diverse.push(article);\n      usedCategories.add(article.category);\n      usedSources.add(article.source.name);\n    }\n  }\n  \n  \u002F\u002F Fill remaining slots\n  for (const article of articles) {\n    if (diverse.length >= limit) break;\n    if (!diverse.includes(article)) {\n      diverse.push(article);\n    }\n  }\n  \n  return diverse;\n}\n",[205,8877,8878,8883,8888,8893,8898,8902,8907,8912,8916,8921,8926,8931,8936,8941,8945,8949,8953,8958,8962,8966,8971,8975,8979,8983,8987,8992],{"__ignoreMap":203},[208,8879,8880],{"class":210,"line":211},[208,8881,8882],{},"function diversifyRecommendations(articles, limit) {\n",[208,8884,8885],{"class":210,"line":218},[208,8886,8887],{},"  const diverse = [];\n",[208,8889,8890],{"class":210,"line":228},[208,8891,8892],{},"  const usedCategories = new Set();\n",[208,8894,8895],{"class":210,"line":236},[208,8896,8897],{},"  const usedSources = new Set();\n",[208,8899,8900],{"class":210,"line":252},[208,8901,1042],{},[208,8903,8904],{"class":210,"line":261},[208,8905,8906],{},"  for (const article of articles) {\n",[208,8908,8909],{"class":210,"line":269},[208,8910,8911],{},"    if (diverse.length >= limit) break;\n",[208,8913,8914],{"class":210,"line":277},[208,8915,3543],{},[208,8917,8918],{"class":210,"line":283},[208,8919,8920],{},"    \u002F\u002F Ensure category diversity\n",[208,8922,8923],{"class":210,"line":289},[208,8924,8925],{},"    if (usedCategories.size \u003C 3 || !usedCategories.has(article.category)) {\n",[208,8927,8928],{"class":210,"line":295},[208,8929,8930],{},"      diverse.push(article);\n",[208,8932,8933],{"class":210,"line":301},[208,8934,8935],{},"      usedCategories.add(article.category);\n",[208,8937,8938],{"class":210,"line":1078},[208,8939,8940],{},"      usedSources.add(article.source.name);\n",[208,8942,8943],{"class":210,"line":1084},[208,8944,292],{},[208,8946,8947],{"class":210,"line":1089},[208,8948,298],{},[208,8950,8951],{"class":210,"line":1095},[208,8952,1042],{},[208,8954,8955],{"class":210,"line":1481},[208,8956,8957],{},"  \u002F\u002F Fill remaining slots\n",[208,8959,8960],{"class":210,"line":1501},[208,8961,8906],{},[208,8963,8964],{"class":210,"line":1521},[208,8965,8911],{},[208,8967,8968],{"class":210,"line":1541},[208,8969,8970],{},"    if (!diverse.includes(article)) {\n",[208,8972,8973],{"class":210,"line":1561},[208,8974,8930],{},[208,8976,8977],{"class":210,"line":1581},[208,8978,292],{},[208,8980,8981],{"class":210,"line":1601},[208,8982,298],{},[208,8984,8985],{"class":210,"line":1621},[208,8986,1042],{},[208,8988,8989],{"class":210,"line":1641},[208,8990,8991],{},"  return diverse;\n",[208,8993,8994],{"class":210,"line":1661},[208,8995,304],{},[94,8997,8999],{"id":8998},"_2-time-decay","2. Time Decay",[12,9001,9002],{},"Give more weight to recent interactions:",[198,9004,9006],{"className":1013,"code":9005,"language":1015,"meta":203,"style":203},"function applyTimeDecay(score, timestamp, decayRate = 0.1) {\n  const daysSince = (Date.now() - timestamp) \u002F (1000 * 60 * 60 * 24);\n  return score * Math.exp(-decayRate * daysSince);\n}\n",[205,9007,9008,9013,9018,9023],{"__ignoreMap":203},[208,9009,9010],{"class":210,"line":211},[208,9011,9012],{},"function applyTimeDecay(score, timestamp, decayRate = 0.1) {\n",[208,9014,9015],{"class":210,"line":218},[208,9016,9017],{},"  const daysSince = (Date.now() - timestamp) \u002F (1000 * 60 * 60 * 24);\n",[208,9019,9020],{"class":210,"line":228},[208,9021,9022],{},"  return score * Math.exp(-decayRate * daysSince);\n",[208,9024,9025],{"class":210,"line":236},[208,9026,304],{},[94,9028,9030],{"id":9029},"_3-cold-start-problem","3. Cold Start Problem",[12,9032,9033],{},"Handle new users with no history:",[198,9035,9037],{"className":1013,"code":9036,"language":1015,"meta":203,"style":203},"function handleColdStart(userId, articles) {\n  \u002F\u002F Show popular articles from diverse categories\n  const categories = ['technology', 'business', 'sports', 'entertainment'];\n  const recommendations = [];\n  \n  categories.forEach(category => {\n    const categoryArticles = articles\n      .filter(a => a.category === category)\n      .slice(0, 3);\n    recommendations.push(...categoryArticles);\n  });\n  \n  return recommendations;\n}\n",[205,9038,9039,9044,9049,9054,9059,9063,9068,9073,9078,9083,9088,9092,9096,9101],{"__ignoreMap":203},[208,9040,9041],{"class":210,"line":211},[208,9042,9043],{},"function handleColdStart(userId, articles) {\n",[208,9045,9046],{"class":210,"line":218},[208,9047,9048],{},"  \u002F\u002F Show popular articles from diverse categories\n",[208,9050,9051],{"class":210,"line":228},[208,9052,9053],{},"  const categories = ['technology', 'business', 'sports', 'entertainment'];\n",[208,9055,9056],{"class":210,"line":236},[208,9057,9058],{},"  const recommendations = [];\n",[208,9060,9061],{"class":210,"line":252},[208,9062,1042],{},[208,9064,9065],{"class":210,"line":261},[208,9066,9067],{},"  categories.forEach(category => {\n",[208,9069,9070],{"class":210,"line":269},[208,9071,9072],{},"    const categoryArticles = articles\n",[208,9074,9075],{"class":210,"line":277},[208,9076,9077],{},"      .filter(a => a.category === category)\n",[208,9079,9080],{"class":210,"line":283},[208,9081,9082],{},"      .slice(0, 3);\n",[208,9084,9085],{"class":210,"line":289},[208,9086,9087],{},"    recommendations.push(...categoryArticles);\n",[208,9089,9090],{"class":210,"line":295},[208,9091,2250],{},[208,9093,9094],{"class":210,"line":301},[208,9095,1042],{},[208,9097,9098],{"class":210,"line":1078},[208,9099,9100],{},"  return recommendations;\n",[208,9102,9103],{"class":210,"line":1084},[208,9104,304],{},[21,9106,3421],{"id":3420},[693,9108,9109,9115,9121,9127,9133,9139,9145,9151],{},[35,9110,9111,9114],{},[16,9112,9113],{},"Start simple"," - Begin with content-based filtering",[35,9116,9117,9120],{},[16,9118,9119],{},"Track everything"," - More data = better recommendations",[35,9122,9123,9126],{},[16,9124,9125],{},"Ensure diversity"," - Avoid filter bubbles",[35,9128,9129,9132],{},[16,9130,9131],{},"Handle cold start"," - Have fallbacks for new users",[35,9134,9135,9138],{},[16,9136,9137],{},"A\u002FB test"," - Measure impact on engagement",[35,9140,9141,9144],{},[16,9142,9143],{},"Respect privacy"," - Be transparent about data usage",[35,9146,9147,9150],{},[16,9148,9149],{},"Allow feedback"," - Let users refine recommendations",[35,9152,9153,9156],{},[16,9154,9155],{},"Monitor performance"," - Track recommendation quality",[21,9158,779],{"id":778},[12,9160,9161],{},"Personalized news feeds significantly improve user engagement and satisfaction. Start with simple content-based filtering and progressively add collaborative filtering and hybrid approaches as you gather more data.",[12,9163,9164,9165,3632],{},"Ready to build personalized experiences? ",[182,9166,9167],{"href":184},"Get started with AllNewsAPI",[21,9169,719],{"id":718},[32,9171,9172,9179,9183],{},[35,9173,9174],{},[182,9175,9178],{"href":9176,"rel":9177},"https:\u002F\u002Fwww.springer.com\u002Fgp\u002Fbook\u002F9780387858203",[732],"Recommendation Systems Handbook",[35,9180,9181],{},[182,9182,3641],{"href":741},[35,9184,9185],{},[182,9186,9189],{"href":9187,"rel":9188},"https:\u002F\u002Fdevelopers.google.com\u002Fmachine-learning\u002Frecommendation",[732],"Collaborative Filtering Tutorial",[825,9191,9192],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":203,"searchDepth":218,"depth":218,"links":9194},[9195,9196,9201,9205,9210,9211,9212],{"id":6712,"depth":218,"text":6713},{"id":6736,"depth":218,"text":6737,"children":9197},[9198,9199,9200],{"id":6740,"depth":228,"text":6741},{"id":7357,"depth":228,"text":7358},{"id":7938,"depth":228,"text":7939},{"id":8197,"depth":218,"text":8198,"children":9202},[9203,9204],{"id":8201,"depth":228,"text":8202},{"id":8470,"depth":228,"text":8471},{"id":8864,"depth":218,"text":8865,"children":9206},[9207,9208,9209],{"id":8868,"depth":228,"text":8869},{"id":8998,"depth":228,"text":8999},{"id":9029,"depth":228,"text":9030},{"id":3420,"depth":218,"text":3421},{"id":778,"depth":218,"text":779},{"id":718,"depth":218,"text":719},"2024-11-18","Learn how to create personalized news recommendations using collaborative filtering and content-based algorithms","\u002Fblog\u002Fbuilding-personalized-news-feeds-with-machine-learning.webp",{},"\u002Fblog\u002Fpersonalized-news-feeds",{"title":6704,"description":9214},{"loc":9217},"blog\u002Fpersonalized-news-feeds","machine-learning","UDqij_fvbWXynJM3YQ9Z33q5PbG-TgdOTpC0tvbQpw4",{"id":9224,"title":9225,"author":7,"body":9226,"date":9939,"description":9940,"draft":862,"extension":863,"image":9941,"meta":9942,"navigation":866,"path":9943,"seo":9944,"sitemap":9945,"stem":9946,"tags":4035,"__hash__":9947},"blog\u002Fblog\u002Fnews-api-vs-web-scraping.md","News APIs vs Web Scraping",{"type":9,"value":9227,"toc":9912},[9228,9231,9235,9238,9242,9315,9319,9322,9326,9346,9350,9354,9359,9370,9375,9386,9390,9394,9408,9412,9426,9430,9434,9454,9458,9477,9481,9485,9499,9503,9517,9521,9525,9539,9543,9557,9561,9565,9579,9583,9597,9601,9605,9616,9620,9634,9638,9642,9670,9674,9697,9701,9704,9721,9725,9728,9748,9752,9755,9759,9765,9769,9775,9780,9789,9793,9796,9859,9861,9864,9887,9893,9897,9910],[12,9229,9230],{},"When building a news aggregation application, developers face a crucial decision: should you use a news API or build a web scraper? Let's explore both approaches to help you make an informed choice.",[21,9232,9234],{"id":9233},"what-is-web-scraping","What is Web Scraping?",[12,9236,9237],{},"Web scraping involves writing code that visits news websites, parses their HTML, and extracts article data. It's like teaching a robot to read websites the way humans do.",[94,9239,9241],{"id":9240},"example-web-scraper","Example Web Scraper",[198,9243,9247],{"className":9244,"code":9245,"language":9246,"meta":203,"style":203},"language-python shiki shiki-themes github-light github-dark","import requests\nfrom bs4 import BeautifulSoup\n\ndef scrape_news(url):\n    response = requests.get(url)\n    soup = BeautifulSoup(response.content, 'html.parser')\n    \n    articles = []\n    for article in soup.find_all('article'):\n        title = article.find('h2').text\n        link = article.find('a')['href']\n        articles.append({'title': title, 'link': link})\n    \n    return articles\n","python",[205,9248,9249,9254,9259,9263,9268,9273,9278,9282,9287,9292,9297,9302,9307,9311],{"__ignoreMap":203},[208,9250,9251],{"class":210,"line":211},[208,9252,9253],{},"import requests\n",[208,9255,9256],{"class":210,"line":218},[208,9257,9258],{},"from bs4 import BeautifulSoup\n",[208,9260,9261],{"class":210,"line":228},[208,9262,1092],{"emptyLinePlaceholder":866},[208,9264,9265],{"class":210,"line":236},[208,9266,9267],{},"def scrape_news(url):\n",[208,9269,9270],{"class":210,"line":252},[208,9271,9272],{},"    response = requests.get(url)\n",[208,9274,9275],{"class":210,"line":261},[208,9276,9277],{},"    soup = BeautifulSoup(response.content, 'html.parser')\n",[208,9279,9280],{"class":210,"line":269},[208,9281,3543],{},[208,9283,9284],{"class":210,"line":277},[208,9285,9286],{},"    articles = []\n",[208,9288,9289],{"class":210,"line":283},[208,9290,9291],{},"    for article in soup.find_all('article'):\n",[208,9293,9294],{"class":210,"line":289},[208,9295,9296],{},"        title = article.find('h2').text\n",[208,9298,9299],{"class":210,"line":295},[208,9300,9301],{},"        link = article.find('a')['href']\n",[208,9303,9304],{"class":210,"line":301},[208,9305,9306],{},"        articles.append({'title': title, 'link': link})\n",[208,9308,9309],{"class":210,"line":1078},[208,9310,3543],{},[208,9312,9313],{"class":210,"line":1084},[208,9314,7843],{},[21,9316,9318],{"id":9317},"what-is-a-news-api","What is a News API?",[12,9320,9321],{},"A news API provides structured access to news data through standardized endpoints. Instead of parsing HTML, you make HTTP requests and receive clean JSON responses.",[94,9323,9325],{"id":9324},"example-api-call","Example API Call",[198,9327,9329],{"className":1013,"code":9328,"language":1015,"meta":203,"style":203},"const response = await fetch('https:\u002F\u002Fapi.allnewsapi.com\u002Fv1\u002Fheadlines?apikey=YOUR_KEY');\nconst data = await response.json();\n\u002F\u002F Clean, structured data ready to use\n",[205,9330,9331,9336,9341],{"__ignoreMap":203},[208,9332,9333],{"class":210,"line":211},[208,9334,9335],{},"const response = await fetch('https:\u002F\u002Fapi.allnewsapi.com\u002Fv1\u002Fheadlines?apikey=YOUR_KEY');\n",[208,9337,9338],{"class":210,"line":218},[208,9339,9340],{},"const data = await response.json();\n",[208,9342,9343],{"class":210,"line":228},[208,9344,9345],{},"\u002F\u002F Clean, structured data ready to use\n",[21,9347,9349],{"id":9348},"comparison-web-scraping-vs-news-apis","Comparison: Web Scraping vs News APIs",[94,9351,9353],{"id":9352},"_1-reliability","1. Reliability",[12,9355,9356],{},[16,9357,9358],{},"Web Scraping:",[32,9360,9361,9364,9367],{},[35,9362,9363],{},"❌ Breaks when websites change their HTML structure",[35,9365,9366],{},"❌ Requires constant maintenance",[35,9368,9369],{},"❌ No guarantees of uptime or data availability",[12,9371,9372],{},[16,9373,9374],{},"News APIs:",[32,9376,9377,9380,9383],{},[35,9378,9379],{},"✅ Stable, versioned endpoints",[35,9381,9382],{},"✅ Maintained by the provider",[35,9384,9385],{},"✅ SLA guarantees for uptime",[94,9387,9389],{"id":9388},"_2-legal-and-ethical-considerations","2. Legal and Ethical Considerations",[12,9391,9392],{},[16,9393,9358],{},[32,9395,9396,9399,9402,9405],{},[35,9397,9398],{},"⚠️ May violate terms of service",[35,9400,9401],{},"⚠️ Can lead to IP bans",[35,9403,9404],{},"⚠️ Legal gray area in many jurisdictions",[35,9406,9407],{},"⚠️ Ethical concerns about server load",[12,9409,9410],{},[16,9411,9374],{},[32,9413,9414,9417,9420,9423],{},[35,9415,9416],{},"✅ Explicit permission to access data",[35,9418,9419],{},"✅ Clear terms of service",[35,9421,9422],{},"✅ Legal and ethical",[35,9424,9425],{},"✅ Supports content creators",[94,9427,9429],{"id":9428},"_3-development-time","3. Development Time",[12,9431,9432],{},[16,9433,9358],{},[32,9435,9436,9439,9442,9445,9448],{},[35,9437,9438],{},"❌ Write scrapers for each news source",[35,9440,9441],{},"❌ Handle different HTML structures",[35,9443,9444],{},"❌ Implement error handling for each site",[35,9446,9447],{},"❌ Build and maintain parsing logic",[35,9449,9450,9453],{},[16,9451,9452],{},"Estimated time:"," Weeks to months",[12,9455,9456],{},[16,9457,9374],{},[32,9459,9460,9463,9466,9469,9472],{},[35,9461,9462],{},"✅ Single integration point",[35,9464,9465],{},"✅ Consistent data format",[35,9467,9468],{},"✅ Built-in error handling",[35,9470,9471],{},"✅ Ready-to-use SDKs",[35,9473,9474,9476],{},[16,9475,9452],{}," Hours to days",[94,9478,9480],{"id":9479},"_4-data-quality","4. Data Quality",[12,9482,9483],{},[16,9484,9358],{},[32,9486,9487,9490,9493,9496],{},[35,9488,9489],{},"⚠️ Inconsistent data formats",[35,9491,9492],{},"⚠️ Missing metadata",[35,9494,9495],{},"⚠️ Requires extensive cleaning",[35,9497,9498],{},"⚠️ No standardization across sources",[12,9500,9501],{},[16,9502,9374],{},[32,9504,9505,9508,9511,9514],{},[35,9506,9507],{},"✅ Standardized data format",[35,9509,9510],{},"✅ Rich metadata (author, date, category)",[35,9512,9513],{},"✅ Clean, validated data",[35,9515,9516],{},"✅ Consistent across all sources",[94,9518,9520],{"id":9519},"_5-performance","5. Performance",[12,9522,9523],{},[16,9524,9358],{},[32,9526,9527,9530,9533,9536],{},[35,9528,9529],{},"❌ Slow (must download and parse HTML)",[35,9531,9532],{},"❌ High bandwidth usage",[35,9534,9535],{},"❌ Resource-intensive",[35,9537,9538],{},"❌ Difficult to scale",[12,9540,9541],{},[16,9542,9374],{},[32,9544,9545,9548,9551,9554],{},[35,9546,9547],{},"✅ Fast JSON responses",[35,9549,9550],{},"✅ Efficient data transfer",[35,9552,9553],{},"✅ Optimized for performance",[35,9555,9556],{},"✅ Easy to scale",[94,9558,9560],{"id":9559},"_6-maintenance","6. Maintenance",[12,9562,9563],{},[16,9564,9358],{},[32,9566,9567,9570,9573,9576],{},[35,9568,9569],{},"❌ Constant monitoring required",[35,9571,9572],{},"❌ Frequent updates needed",[35,9574,9575],{},"❌ Breaks without warning",[35,9577,9578],{},"❌ High ongoing costs",[12,9580,9581],{},[16,9582,9374],{},[32,9584,9585,9588,9591,9594],{},[35,9586,9587],{},"✅ Provider handles maintenance",[35,9589,9590],{},"✅ Backward compatibility",[35,9592,9593],{},"✅ Advance notice of changes",[35,9595,9596],{},"✅ Low maintenance overhead",[94,9598,9600],{"id":9599},"_7-coverage","7. Coverage",[12,9602,9603],{},[16,9604,9358],{},[32,9606,9607,9610,9613],{},[35,9608,9609],{},"⚠️ Limited to sites you scrape",[35,9611,9612],{},"⚠️ Time-consuming to add sources",[35,9614,9615],{},"⚠️ Difficult to maintain many sources",[12,9617,9618],{},[16,9619,9374],{},[32,9621,9622,9625,9628,9631],{},[35,9623,9624],{},"✅ Access to hundreds of sources",[35,9626,9627],{},"✅ Multiple countries and languages",[35,9629,9630],{},"✅ Instant access to new sources",[35,9632,9633],{},"✅ Comprehensive coverage",[94,9635,9637],{"id":9636},"_8-cost","8. Cost",[12,9639,9640],{},[16,9641,9358],{},[32,9643,9644,9647,9664],{},[35,9645,9646],{},"Initial cost: Low (just development time)",[35,9648,9649,9650],{},"Ongoing costs:\n",[32,9651,9652,9655,9658,9661],{},[35,9653,9654],{},"Developer time for maintenance",[35,9656,9657],{},"Server costs for running scrapers",[35,9659,9660],{},"Proxy services to avoid bans",[35,9662,9663],{},"Legal risks",[35,9665,9666,9669],{},[16,9667,9668],{},"Total:"," Often higher than expected",[12,9671,9672],{},[16,9673,9374],{},[32,9675,9676,9679,9692],{},[35,9677,9678],{},"Initial cost: Low (quick integration)",[35,9680,9649,9681],{},[32,9682,9683,9686,9689],{},[35,9684,9685],{},"Subscription fee (predictable)",[35,9687,9688],{},"Minimal maintenance",[35,9690,9691],{},"No infrastructure needed",[35,9693,9694,9696],{},[16,9695,9668],{}," Predictable and often lower",[21,9698,9700],{"id":9699},"when-to-use-web-scraping","When to Use Web Scraping",[12,9702,9703],{},"Web scraping might be appropriate when:",[693,9705,9706,9709,9712,9715,9718],{},[35,9707,9708],{},"You need data from a single, specific source",[35,9710,9711],{},"No API is available for that source",[35,9713,9714],{},"You have explicit permission from the website",[35,9716,9717],{},"You have resources for ongoing maintenance",[35,9719,9720],{},"You're doing academic research with proper authorization",[21,9722,9724],{"id":9723},"when-to-use-a-news-api","When to Use a News API",[12,9726,9727],{},"A news API is the better choice when:",[693,9729,9730,9733,9736,9739,9742,9745],{},[35,9731,9732],{},"You need data from multiple sources ✅",[35,9734,9735],{},"You want reliable, maintained access ✅",[35,9737,9738],{},"You need to launch quickly ✅",[35,9740,9741],{},"You want to focus on your app, not data collection ✅",[35,9743,9744],{},"You need legal, ethical data access ✅",[35,9746,9747],{},"You want predictable costs ✅",[21,9749,9751],{"id":9750},"real-world-example-cost-comparison","Real-World Example: Cost Comparison",[12,9753,9754],{},"Let's compare building a news aggregator for 10 sources:",[94,9756,9758],{"id":9757},"web-scraping-approach","Web Scraping Approach",[198,9760,9763],{"className":9761,"code":9762,"language":381},[379],"Development: 2 weeks × $100\u002Fhour = $8,000\nMonthly maintenance: 20 hours × $100\u002Fhour = $2,000\nServer costs: $200\u002Fmonth\nProxy service: $100\u002Fmonth\nTotal first year: $8,000 + ($2,300 × 12) = $35,600\n",[205,9764,9762],{"__ignoreMap":203},[94,9766,9768],{"id":9767},"api-approach","API Approach",[198,9770,9773],{"className":9771,"code":9772,"language":381},[379],"Development: 2 days × $100\u002Fhour × 8 hours = $1,600\nAllNewsAPI subscription: Starting from $9\u002Fmonth\nMonthly maintenance: 2 hours × $100\u002Fhour = $200\nTotal first year: $1,600 + (subscription × 12) + ($200 × 12) = significantly lower\n",[205,9774,9772],{"__ignoreMap":203},[12,9776,9777],{},[16,9778,9779],{},"Savings with API: Tens of thousands in the first year",[12,9781,9782],{},[813,9783,9784,9785,9788],{},"Note: Check ",[182,9786,9787],{"href":686},"current pricing"," for the plan that fits your needs.",[21,9790,9792],{"id":9791},"making-the-switch","Making the Switch",[12,9794,9795],{},"If you're currently using web scraping, migrating to AllNewsAPI is straightforward:",[198,9797,9799],{"className":1013,"code":9798,"language":1015,"meta":203,"style":203},"\u002F\u002F Old scraping approach\nconst articles = await scrapeMultipleSites([\n  'site1.com',\n  'site2.com',\n  'site3.com'\n]);\n\n\u002F\u002F New API approach\nconst response = await fetch(\n  'https:\u002F\u002Fapi.allnewsapi.com\u002Fv1\u002Fheadlines?apikey=YOUR_KEY&country=us'\n);\nconst { articles } = await response.json();\n",[205,9800,9801,9806,9811,9816,9821,9826,9831,9835,9840,9845,9850,9854],{"__ignoreMap":203},[208,9802,9803],{"class":210,"line":211},[208,9804,9805],{},"\u002F\u002F Old scraping approach\n",[208,9807,9808],{"class":210,"line":218},[208,9809,9810],{},"const articles = await scrapeMultipleSites([\n",[208,9812,9813],{"class":210,"line":228},[208,9814,9815],{},"  'site1.com',\n",[208,9817,9818],{"class":210,"line":236},[208,9819,9820],{},"  'site2.com',\n",[208,9822,9823],{"class":210,"line":252},[208,9824,9825],{},"  'site3.com'\n",[208,9827,9828],{"class":210,"line":261},[208,9829,9830],{},"]);\n",[208,9832,9833],{"class":210,"line":269},[208,9834,1092],{"emptyLinePlaceholder":866},[208,9836,9837],{"class":210,"line":277},[208,9838,9839],{},"\u002F\u002F New API approach\n",[208,9841,9842],{"class":210,"line":283},[208,9843,9844],{},"const response = await fetch(\n",[208,9846,9847],{"class":210,"line":289},[208,9848,9849],{},"  'https:\u002F\u002Fapi.allnewsapi.com\u002Fv1\u002Fheadlines?apikey=YOUR_KEY&country=us'\n",[208,9851,9852],{"class":210,"line":295},[208,9853,2377],{},[208,9855,9856],{"class":210,"line":301},[208,9857,9858],{},"const { articles } = await response.json();\n",[21,9860,779],{"id":778},[12,9862,9863],{},"While web scraping might seem appealing initially, news APIs provide a more reliable, legal, and cost-effective solution for most use cases. AllNewsAPI offers:",[32,9865,9866,9869,9872,9875,9878,9881,9884],{},[35,9867,9868],{},"Access to 244 countries",[35,9870,9871],{},"22 languages supported",[35,9873,9874],{},"10 years of historical data",[35,9876,9877],{},"Reliable, maintained infrastructure",[35,9879,9880],{},"Legal, ethical data access",[35,9882,9883],{},"Predictable costs",[35,9885,9886],{},"Fast integration",[12,9888,9889,9890,9892],{},"Ready to make the switch? ",[182,9891,794],{"href":184}," and get started in minutes.",[21,9894,9896],{"id":9895},"further-reading","Further Reading",[32,9898,9899,9905],{},[35,9900,9901],{},[182,9902,9904],{"href":9903},"\u002Fblog\u002Fgetting-started-with-allnewsapi","Getting Started with AllNewsAPI",[35,9906,9907],{},[182,9908,9909],{"href":686},"View our pricing plans",[825,9911,9192],{},{"title":203,"searchDepth":218,"depth":218,"links":9913},[9914,9917,9920,9930,9931,9932,9936,9937,9938],{"id":9233,"depth":218,"text":9234,"children":9915},[9916],{"id":9240,"depth":228,"text":9241},{"id":9317,"depth":218,"text":9318,"children":9918},[9919],{"id":9324,"depth":228,"text":9325},{"id":9348,"depth":218,"text":9349,"children":9921},[9922,9923,9924,9925,9926,9927,9928,9929],{"id":9352,"depth":228,"text":9353},{"id":9388,"depth":228,"text":9389},{"id":9428,"depth":228,"text":9429},{"id":9479,"depth":228,"text":9480},{"id":9519,"depth":228,"text":9520},{"id":9559,"depth":228,"text":9560},{"id":9599,"depth":228,"text":9600},{"id":9636,"depth":228,"text":9637},{"id":9699,"depth":218,"text":9700},{"id":9723,"depth":218,"text":9724},{"id":9750,"depth":218,"text":9751,"children":9933},[9934,9935],{"id":9757,"depth":228,"text":9758},{"id":9767,"depth":228,"text":9768},{"id":9791,"depth":218,"text":9792},{"id":778,"depth":218,"text":779},{"id":9895,"depth":218,"text":9896},"2024-10-20","Explore the pros and cons of using news APIs versus web scraping for your news aggregation project","\u002Fblog\u002Fnews-apis-vs-web-scraping.webp",{},"\u002Fblog\u002Fnews-api-vs-web-scraping",{"title":9225,"description":9940},{"loc":9943},"blog\u002Fnews-api-vs-web-scraping","3HNNBXJKu6AJlpqW00Jxruy9ZxcASqKbyPxnsTwTWmA",{"id":9949,"title":9950,"author":7,"body":9951,"date":13718,"description":13719,"draft":862,"extension":863,"image":13720,"meta":13721,"navigation":866,"path":13722,"seo":13723,"sitemap":13724,"stem":13725,"tags":13726,"__hash__":13727},"blog\u002Fblog\u002Fnews-sentiment-analysis.md","Using Built-in Sentiment Analysis with AllNewsAPI",{"type":9,"value":9952,"toc":13697},[9953,9956,9960,9963,9977,9981,9984,9998,10080,10083,10087,10090,10195,10199,10202,10282,10286,10289,10365,10369,10372,10711,10715,10718,12694,12698,12701,13038,13042,13046,13049,13156,13159,13163,13166,13363,13367,13370,13558,13560,13604,13608,13611,13636,13639,13664,13666,13669,13674,13676,13694],[12,9954,9955],{},"Great news! AllNewsAPI includes built-in AI-powered sentiment analysis for every article. This tutorial shows you how to leverage this feature to build sentiment-aware news applications without any additional machine learning setup.",[21,9957,9959],{"id":9958},"what-is-sentiment-analysis","What is Sentiment Analysis?",[12,9961,9962],{},"Sentiment analysis (also called opinion mining) uses machine learning to determine whether text expresses positive, negative, or neutral sentiment. For news applications, this helps users:",[32,9964,9965,9968,9971,9974],{},[35,9966,9967],{},"Quickly gauge article tone",[35,9969,9970],{},"Filter news by sentiment",[35,9972,9973],{},"Track sentiment trends over time",[35,9975,9976],{},"Identify controversial topics",[21,9978,9980],{"id":9979},"allnewsapis-built-in-sentiment-feature","AllNewsAPI's Built-in Sentiment Feature",[12,9982,9983],{},"Every article returned by AllNewsAPI includes two sentiment fields:",[693,9985,9986,9992],{},[35,9987,9988,9991],{},[16,9989,9990],{},"sentiment",": A simple classification (positive, negative, or neutral)",[35,9993,9994,9997],{},[16,9995,9996],{},"sentimentScores",": Detailed confidence scores for each sentiment category",[198,9999,10001],{"className":200,"code":10000,"language":202,"meta":203,"style":203},"{\n  \"title\": \"Tech Company Announces Breakthrough Innovation\",\n  \"sentiment\": \"positive\",\n  \"sentimentScores\": {\n    \"positive\": 0.85,\n    \"neutral\": 0.12,\n    \"negative\": 0.03\n  }\n}\n",[205,10002,10003,10007,10019,10031,10038,10050,10062,10072,10076],{"__ignoreMap":203},[208,10004,10005],{"class":210,"line":211},[208,10006,215],{"class":214},[208,10008,10009,10012,10014,10017],{"class":210,"line":218},[208,10010,10011],{"class":221},"  \"title\"",[208,10013,242],{"class":214},[208,10015,10016],{"class":245},"\"Tech Company Announces Breakthrough Innovation\"",[208,10018,249],{"class":214},[208,10020,10021,10024,10026,10029],{"class":210,"line":228},[208,10022,10023],{"class":221},"  \"sentiment\"",[208,10025,242],{"class":214},[208,10027,10028],{"class":245},"\"positive\"",[208,10030,249],{"class":214},[208,10032,10033,10036],{"class":210,"line":236},[208,10034,10035],{"class":221},"  \"sentimentScores\"",[208,10037,225],{"class":214},[208,10039,10040,10043,10045,10048],{"class":210,"line":252},[208,10041,10042],{"class":221},"    \"positive\"",[208,10044,242],{"class":214},[208,10046,10047],{"class":221},"0.85",[208,10049,249],{"class":214},[208,10051,10052,10055,10057,10060],{"class":210,"line":261},[208,10053,10054],{"class":221},"    \"neutral\"",[208,10056,242],{"class":214},[208,10058,10059],{"class":221},"0.12",[208,10061,249],{"class":214},[208,10063,10064,10067,10069],{"class":210,"line":269},[208,10065,10066],{"class":221},"    \"negative\"",[208,10068,242],{"class":214},[208,10070,10071],{"class":221},"0.03\n",[208,10073,10074],{"class":210,"line":277},[208,10075,298],{"class":214},[208,10077,10078],{"class":210,"line":283},[208,10079,304],{"class":214},[12,10081,10082],{},"This means you can start building sentiment-aware features immediately without any ML setup!",[21,10084,10086],{"id":10085},"step-1-fetching-news-with-sentiment-data","Step 1: Fetching News with Sentiment Data",[12,10088,10089],{},"Simply fetch news from AllNewsAPI - sentiment data is included automatically:",[198,10091,10093],{"className":1013,"code":10092,"language":1015,"meta":203,"style":203},"const API_KEY = 'your_api_key_here';\n\nasync function fetchNewsWithSentiment(country = 'us') {\n  const response = await fetch(\n    `https:\u002F\u002Fapi.allnewsapi.com\u002Fheadlines?apikey=${API_KEY}&country=${country}`\n  );\n  \n  const data = await response.json();\n  \n  \u002F\u002F Each article already includes sentiment and sentimentScores!\n  return data.articles;\n}\n\n\u002F\u002F Usage\nconst articles = await fetchNewsWithSentiment('us');\n\narticles.forEach(article => {\n  console.log(`Title: ${article.title}`);\n  console.log(`Sentiment: ${article.sentiment}`);\n  console.log(`Scores:`, article.sentimentScores);\n  console.log('---');\n});\n",[205,10094,10095,10100,10104,10109,10113,10118,10122,10126,10131,10135,10140,10145,10149,10153,10157,10162,10166,10171,10176,10181,10186,10191],{"__ignoreMap":203},[208,10096,10097],{"class":210,"line":211},[208,10098,10099],{},"const API_KEY = 'your_api_key_here';\n",[208,10101,10102],{"class":210,"line":218},[208,10103,1092],{"emptyLinePlaceholder":866},[208,10105,10106],{"class":210,"line":228},[208,10107,10108],{},"async function fetchNewsWithSentiment(country = 'us') {\n",[208,10110,10111],{"class":210,"line":236},[208,10112,1120],{},[208,10114,10115],{"class":210,"line":252},[208,10116,10117],{},"    `https:\u002F\u002Fapi.allnewsapi.com\u002Fheadlines?apikey=${API_KEY}&country=${country}`\n",[208,10119,10120],{"class":210,"line":261},[208,10121,1130],{},[208,10123,10124],{"class":210,"line":269},[208,10125,1042],{},[208,10127,10128],{"class":210,"line":277},[208,10129,10130],{},"  const data = await response.json();\n",[208,10132,10133],{"class":210,"line":283},[208,10134,1042],{},[208,10136,10137],{"class":210,"line":289},[208,10138,10139],{},"  \u002F\u002F Each article already includes sentiment and sentimentScores!\n",[208,10141,10142],{"class":210,"line":295},[208,10143,10144],{},"  return data.articles;\n",[208,10146,10147],{"class":210,"line":301},[208,10148,304],{},[208,10150,10151],{"class":210,"line":1078},[208,10152,1092],{"emptyLinePlaceholder":866},[208,10154,10155],{"class":210,"line":1084},[208,10156,2912],{},[208,10158,10159],{"class":210,"line":1089},[208,10160,10161],{},"const articles = await fetchNewsWithSentiment('us');\n",[208,10163,10164],{"class":210,"line":1095},[208,10165,1092],{"emptyLinePlaceholder":866},[208,10167,10168],{"class":210,"line":1481},[208,10169,10170],{},"articles.forEach(article => {\n",[208,10172,10173],{"class":210,"line":1501},[208,10174,10175],{},"  console.log(`Title: ${article.title}`);\n",[208,10177,10178],{"class":210,"line":1521},[208,10179,10180],{},"  console.log(`Sentiment: ${article.sentiment}`);\n",[208,10182,10183],{"class":210,"line":1541},[208,10184,10185],{},"  console.log(`Scores:`, article.sentimentScores);\n",[208,10187,10188],{"class":210,"line":1561},[208,10189,10190],{},"  console.log('---');\n",[208,10192,10193],{"class":210,"line":1581},[208,10194,3868],{},[21,10196,10198],{"id":10197},"step-2-filtering-by-sentiment","Step 2: Filtering by Sentiment",[12,10200,10201],{},"Filter articles based on their sentiment classification:",[198,10203,10205],{"className":1013,"code":10204,"language":1015,"meta":203,"style":203},"function filterBySentiment(articles, sentimentType) {\n  return articles.filter(article => article.sentiment === sentimentType);\n}\n\n\u002F\u002F Get only positive news\nconst positiveNews = filterBySentiment(articles, 'positive');\n\n\u002F\u002F Get only negative news\nconst negativeNews = filterBySentiment(articles, 'negative');\n\n\u002F\u002F Get neutral news\nconst neutralNews = filterBySentiment(articles, 'neutral');\n\nconsole.log(`Positive articles: ${positiveNews.length}`);\nconsole.log(`Negative articles: ${negativeNews.length}`);\nconsole.log(`Neutral articles: ${neutralNews.length}`);\n",[205,10206,10207,10212,10217,10221,10225,10230,10235,10239,10244,10249,10253,10258,10263,10267,10272,10277],{"__ignoreMap":203},[208,10208,10209],{"class":210,"line":211},[208,10210,10211],{},"function filterBySentiment(articles, sentimentType) {\n",[208,10213,10214],{"class":210,"line":218},[208,10215,10216],{},"  return articles.filter(article => article.sentiment === sentimentType);\n",[208,10218,10219],{"class":210,"line":228},[208,10220,304],{},[208,10222,10223],{"class":210,"line":236},[208,10224,1092],{"emptyLinePlaceholder":866},[208,10226,10227],{"class":210,"line":252},[208,10228,10229],{},"\u002F\u002F Get only positive news\n",[208,10231,10232],{"class":210,"line":261},[208,10233,10234],{},"const positiveNews = filterBySentiment(articles, 'positive');\n",[208,10236,10237],{"class":210,"line":269},[208,10238,1092],{"emptyLinePlaceholder":866},[208,10240,10241],{"class":210,"line":277},[208,10242,10243],{},"\u002F\u002F Get only negative news\n",[208,10245,10246],{"class":210,"line":283},[208,10247,10248],{},"const negativeNews = filterBySentiment(articles, 'negative');\n",[208,10250,10251],{"class":210,"line":289},[208,10252,1092],{"emptyLinePlaceholder":866},[208,10254,10255],{"class":210,"line":295},[208,10256,10257],{},"\u002F\u002F Get neutral news\n",[208,10259,10260],{"class":210,"line":301},[208,10261,10262],{},"const neutralNews = filterBySentiment(articles, 'neutral');\n",[208,10264,10265],{"class":210,"line":1078},[208,10266,1092],{"emptyLinePlaceholder":866},[208,10268,10269],{"class":210,"line":1084},[208,10270,10271],{},"console.log(`Positive articles: ${positiveNews.length}`);\n",[208,10273,10274],{"class":210,"line":1089},[208,10275,10276],{},"console.log(`Negative articles: ${negativeNews.length}`);\n",[208,10278,10279],{"class":210,"line":1095},[208,10280,10281],{},"console.log(`Neutral articles: ${neutralNews.length}`);\n",[21,10283,10285],{"id":10284},"step-3-sorting-by-sentiment-confidence","Step 3: Sorting by Sentiment Confidence",[12,10287,10288],{},"Sort articles by how confident the sentiment analysis is:",[198,10290,10292],{"className":1013,"code":10291,"language":1015,"meta":203,"style":203},"function sortBySentimentConfidence(articles, sentimentType) {\n  return articles\n    .filter(article => article.sentiment === sentimentType)\n    .sort((a, b) => {\n      const scoreA = a.sentimentScores[sentimentType];\n      const scoreB = b.sentimentScores[sentimentType];\n      return scoreB - scoreA;\n    });\n}\n\n\u002F\u002F Get most confidently positive articles\nconst mostPositive = sortBySentimentConfidence(articles, 'positive');\n\nconsole.log('Most positive article:', mostPositive[0].title);\nconsole.log('Positive score:', mostPositive[0].sentimentScores.positive);\n",[205,10293,10294,10299,10304,10309,10314,10319,10324,10329,10333,10337,10341,10346,10351,10355,10360],{"__ignoreMap":203},[208,10295,10296],{"class":210,"line":211},[208,10297,10298],{},"function sortBySentimentConfidence(articles, sentimentType) {\n",[208,10300,10301],{"class":210,"line":218},[208,10302,10303],{},"  return articles\n",[208,10305,10306],{"class":210,"line":228},[208,10307,10308],{},"    .filter(article => article.sentiment === sentimentType)\n",[208,10310,10311],{"class":210,"line":236},[208,10312,10313],{},"    .sort((a, b) => {\n",[208,10315,10316],{"class":210,"line":252},[208,10317,10318],{},"      const scoreA = a.sentimentScores[sentimentType];\n",[208,10320,10321],{"class":210,"line":261},[208,10322,10323],{},"      const scoreB = b.sentimentScores[sentimentType];\n",[208,10325,10326],{"class":210,"line":269},[208,10327,10328],{},"      return scoreB - scoreA;\n",[208,10330,10331],{"class":210,"line":277},[208,10332,3603],{},[208,10334,10335],{"class":210,"line":283},[208,10336,304],{},[208,10338,10339],{"class":210,"line":289},[208,10340,1092],{"emptyLinePlaceholder":866},[208,10342,10343],{"class":210,"line":295},[208,10344,10345],{},"\u002F\u002F Get most confidently positive articles\n",[208,10347,10348],{"class":210,"line":301},[208,10349,10350],{},"const mostPositive = sortBySentimentConfidence(articles, 'positive');\n",[208,10352,10353],{"class":210,"line":1078},[208,10354,1092],{"emptyLinePlaceholder":866},[208,10356,10357],{"class":210,"line":1084},[208,10358,10359],{},"console.log('Most positive article:', mostPositive[0].title);\n",[208,10361,10362],{"class":210,"line":1089},[208,10363,10364],{},"console.log('Positive score:', mostPositive[0].sentimentScores.positive);\n",[21,10366,10368],{"id":10367},"step-4-building-a-complete-news-sentiment-dashboard","Step 4: Building a Complete News Sentiment Dashboard",[12,10370,10371],{},"Create a full-featured sentiment analysis dashboard using AllNewsAPI's built-in sentiment data:",[198,10373,10375],{"className":1013,"code":10374,"language":1015,"meta":203,"style":203},"\u002F\u002F sentiment-service.js\nclass NewsSentimentService {\n  constructor(apiKey) {\n    this.apiKey = apiKey;\n    this.apiUrl = 'https:\u002F\u002Fapi.allnewsapi.com\u002Fheadlines';\n  }\n  \n  async fetchNews(country = 'us', category = null) {\n    let url = `${this.apiUrl}?apikey=${this.apiKey}&country=${country}`;\n    if (category) url += `&category=${category}`;\n    \n    const response = await fetch(url);\n    const data = await response.json();\n    \n    \u002F\u002F Articles already include sentiment and sentimentScores from API\n    return data.articles || [];\n  }\n  \n  getSentimentStats(articles) {\n    const stats = {\n      total: articles.length,\n      positive: 0,\n      negative: 0,\n      neutral: 0,\n      averagePositiveScore: 0,\n      averageNegativeScore: 0,\n      averageNeutralScore: 0\n    };\n    \n    let totalPositive = 0;\n    let totalNegative = 0;\n    let totalNeutral = 0;\n    \n    articles.forEach(article => {\n      \u002F\u002F Use the built-in sentiment classification\n      stats[article.sentiment]++;\n      \n      \u002F\u002F Accumulate scores for averages\n      totalPositive += article.sentimentScores.positive;\n      totalNegative += article.sentimentScores.negative;\n      totalNeutral += article.sentimentScores.neutral;\n    });\n    \n    \u002F\u002F Calculate average scores\n    stats.averagePositiveScore = totalPositive \u002F articles.length;\n    stats.averageNegativeScore = totalNegative \u002F articles.length;\n    stats.averageNeutralScore = totalNeutral \u002F articles.length;\n    \n    return stats;\n  }\n  \n  filterBySentiment(articles, sentimentType) {\n    return articles.filter(article => article.sentiment === sentimentType);\n  }\n  \n  sortBySentimentScore(articles, sentimentType, order = 'desc') {\n    return [...articles].sort((a, b) => {\n      const scoreA = a.sentimentScores[sentimentType];\n      const scoreB = b.sentimentScores[sentimentType];\n      return order === 'desc' ? scoreB - scoreA : scoreA - scoreB;\n    });\n  }\n  \n  getHighConfidenceArticles(articles, sentimentType, threshold = 0.7) {\n    return articles.filter(article => \n      article.sentiment === sentimentType && \n      article.sentimentScores[sentimentType] >= threshold\n    );\n  }\n}\n\nmodule.exports = NewsSentimentService;\n",[205,10376,10377,10382,10387,10392,10397,10402,10406,10410,10415,10420,10425,10429,10434,10439,10443,10448,10453,10457,10461,10466,10471,10476,10481,10486,10491,10496,10501,10506,10510,10514,10519,10524,10529,10533,10538,10543,10548,10552,10557,10562,10567,10572,10576,10580,10585,10590,10595,10600,10604,10609,10613,10617,10622,10627,10631,10635,10640,10645,10649,10653,10658,10662,10666,10670,10675,10680,10685,10690,10694,10698,10702,10706],{"__ignoreMap":203},[208,10378,10379],{"class":210,"line":211},[208,10380,10381],{},"\u002F\u002F sentiment-service.js\n",[208,10383,10384],{"class":210,"line":218},[208,10385,10386],{},"class NewsSentimentService {\n",[208,10388,10389],{"class":210,"line":228},[208,10390,10391],{},"  constructor(apiKey) {\n",[208,10393,10394],{"class":210,"line":236},[208,10395,10396],{},"    this.apiKey = apiKey;\n",[208,10398,10399],{"class":210,"line":252},[208,10400,10401],{},"    this.apiUrl = 'https:\u002F\u002Fapi.allnewsapi.com\u002Fheadlines';\n",[208,10403,10404],{"class":210,"line":261},[208,10405,298],{},[208,10407,10408],{"class":210,"line":269},[208,10409,1042],{},[208,10411,10412],{"class":210,"line":277},[208,10413,10414],{},"  async fetchNews(country = 'us', category = null) {\n",[208,10416,10417],{"class":210,"line":283},[208,10418,10419],{},"    let url = `${this.apiUrl}?apikey=${this.apiKey}&country=${country}`;\n",[208,10421,10422],{"class":210,"line":289},[208,10423,10424],{},"    if (category) url += `&category=${category}`;\n",[208,10426,10427],{"class":210,"line":295},[208,10428,3543],{},[208,10430,10431],{"class":210,"line":301},[208,10432,10433],{},"    const response = await fetch(url);\n",[208,10435,10436],{"class":210,"line":1078},[208,10437,10438],{},"    const data = await response.json();\n",[208,10440,10441],{"class":210,"line":1084},[208,10442,3543],{},[208,10444,10445],{"class":210,"line":1089},[208,10446,10447],{},"    \u002F\u002F Articles already include sentiment and sentimentScores from API\n",[208,10449,10450],{"class":210,"line":1095},[208,10451,10452],{},"    return data.articles || [];\n",[208,10454,10455],{"class":210,"line":1481},[208,10456,298],{},[208,10458,10459],{"class":210,"line":1501},[208,10460,1042],{},[208,10462,10463],{"class":210,"line":1521},[208,10464,10465],{},"  getSentimentStats(articles) {\n",[208,10467,10468],{"class":210,"line":1541},[208,10469,10470],{},"    const stats = {\n",[208,10472,10473],{"class":210,"line":1561},[208,10474,10475],{},"      total: articles.length,\n",[208,10477,10478],{"class":210,"line":1581},[208,10479,10480],{},"      positive: 0,\n",[208,10482,10483],{"class":210,"line":1601},[208,10484,10485],{},"      negative: 0,\n",[208,10487,10488],{"class":210,"line":1621},[208,10489,10490],{},"      neutral: 0,\n",[208,10492,10493],{"class":210,"line":1641},[208,10494,10495],{},"      averagePositiveScore: 0,\n",[208,10497,10498],{"class":210,"line":1661},[208,10499,10500],{},"      averageNegativeScore: 0,\n",[208,10502,10503],{"class":210,"line":1682},[208,10504,10505],{},"      averageNeutralScore: 0\n",[208,10507,10508],{"class":210,"line":1688},[208,10509,6811],{},[208,10511,10512],{"class":210,"line":1693},[208,10513,3543],{},[208,10515,10516],{"class":210,"line":1718},[208,10517,10518],{},"    let totalPositive = 0;\n",[208,10520,10521],{"class":210,"line":1736},[208,10522,10523],{},"    let totalNegative = 0;\n",[208,10525,10526],{"class":210,"line":1745},[208,10527,10528],{},"    let totalNeutral = 0;\n",[208,10530,10531],{"class":210,"line":1751},[208,10532,3543],{},[208,10534,10535],{"class":210,"line":1756},[208,10536,10537],{},"    articles.forEach(article => {\n",[208,10539,10540],{"class":210,"line":1765},[208,10541,10542],{},"      \u002F\u002F Use the built-in sentiment classification\n",[208,10544,10545],{"class":210,"line":1787},[208,10546,10547],{},"      stats[article.sentiment]++;\n",[208,10549,10550],{"class":210,"line":1799},[208,10551,7580],{},[208,10553,10554],{"class":210,"line":1810},[208,10555,10556],{},"      \u002F\u002F Accumulate scores for averages\n",[208,10558,10559],{"class":210,"line":1833},[208,10560,10561],{},"      totalPositive += article.sentimentScores.positive;\n",[208,10563,10564],{"class":210,"line":1839},[208,10565,10566],{},"      totalNegative += article.sentimentScores.negative;\n",[208,10568,10569],{"class":210,"line":1858},[208,10570,10571],{},"      totalNeutral += article.sentimentScores.neutral;\n",[208,10573,10574],{"class":210,"line":1883},[208,10575,3603],{},[208,10577,10578],{"class":210,"line":1889},[208,10579,3543],{},[208,10581,10582],{"class":210,"line":1899},[208,10583,10584],{},"    \u002F\u002F Calculate average scores\n",[208,10586,10587],{"class":210,"line":1905},[208,10588,10589],{},"    stats.averagePositiveScore = totalPositive \u002F articles.length;\n",[208,10591,10592],{"class":210,"line":1915},[208,10593,10594],{},"    stats.averageNegativeScore = totalNegative \u002F articles.length;\n",[208,10596,10597],{"class":210,"line":1925},[208,10598,10599],{},"    stats.averageNeutralScore = totalNeutral \u002F articles.length;\n",[208,10601,10602],{"class":210,"line":1930},[208,10603,3543],{},[208,10605,10606],{"class":210,"line":1935},[208,10607,10608],{},"    return stats;\n",[208,10610,10611],{"class":210,"line":1940},[208,10612,298],{},[208,10614,10615],{"class":210,"line":2230},[208,10616,1042],{},[208,10618,10619],{"class":210,"line":2236},[208,10620,10621],{},"  filterBySentiment(articles, sentimentType) {\n",[208,10623,10624],{"class":210,"line":2242},[208,10625,10626],{},"    return articles.filter(article => article.sentiment === sentimentType);\n",[208,10628,10629],{"class":210,"line":2247},[208,10630,298],{},[208,10632,10633],{"class":210,"line":2253},[208,10634,1042],{},[208,10636,10637],{"class":210,"line":2258},[208,10638,10639],{},"  sortBySentimentScore(articles, sentimentType, order = 'desc') {\n",[208,10641,10642],{"class":210,"line":3213},[208,10643,10644],{},"    return [...articles].sort((a, b) => {\n",[208,10646,10647],{"class":210,"line":3219},[208,10648,10318],{},[208,10650,10651],{"class":210,"line":5034},[208,10652,10323],{},[208,10654,10655],{"class":210,"line":5713},[208,10656,10657],{},"      return order === 'desc' ? scoreB - scoreA : scoreA - scoreB;\n",[208,10659,10660],{"class":210,"line":5729},[208,10661,3603],{},[208,10663,10664],{"class":210,"line":5737},[208,10665,298],{},[208,10667,10668],{"class":210,"line":5748},[208,10669,1042],{},[208,10671,10672],{"class":210,"line":5759},[208,10673,10674],{},"  getHighConfidenceArticles(articles, sentimentType, threshold = 0.7) {\n",[208,10676,10677],{"class":210,"line":5770},[208,10678,10679],{},"    return articles.filter(article => \n",[208,10681,10682],{"class":210,"line":5781},[208,10683,10684],{},"      article.sentiment === sentimentType && \n",[208,10686,10687],{"class":210,"line":5786},[208,10688,10689],{},"      article.sentimentScores[sentimentType] >= threshold\n",[208,10691,10692],{"class":210,"line":5791},[208,10693,7193],{},[208,10695,10696],{"class":210,"line":5817},[208,10697,298],{},[208,10699,10700],{"class":210,"line":5825},[208,10701,304],{},[208,10703,10704],{"class":210,"line":5836},[208,10705,1092],{"emptyLinePlaceholder":866},[208,10707,10708],{"class":210,"line":5847},[208,10709,10710],{},"module.exports = NewsSentimentService;\n",[21,10712,10714],{"id":10713},"step-5-creating-the-frontend","Step 5: Creating the Frontend",[12,10716,10717],{},"Build a React component to display sentiment using AllNewsAPI's built-in data:",[198,10719,10721],{"className":1181,"code":10720,"language":1183,"meta":203,"style":203},"import React, { useState, useEffect } from 'react';\nimport '.\u002FSentimentDashboard.css';\n\nfunction SentimentDashboard() {\n  const [articles, setArticles] = useState([]);\n  const [filter, setFilter] = useState('all');\n  const [stats, setStats] = useState(null);\n  const [loading, setLoading] = useState(true);\n  \n  useEffect(() => {\n    fetchNewsWithSentiment();\n  }, []);\n  \n  async function fetchNewsWithSentiment() {\n    try {\n      const API_KEY = process.env.REACT_APP_NEWS_API_KEY;\n      const response = await fetch(\n        `https:\u002F\u002Fapi.allnewsapi.com\u002Fheadlines?apikey=${API_KEY}&country=us`\n      );\n      const data = await response.json();\n      \n      \u002F\u002F Articles already include sentiment data!\n      setArticles(data.articles);\n      setStats(calculateStats(data.articles));\n    } catch (error) {\n      console.error('Error fetching news:', error);\n    } finally {\n      setLoading(false);\n    }\n  }\n  \n  function calculateStats(articles) {\n    const stats = { total: articles.length, positive: 0, negative: 0, neutral: 0 };\n    articles.forEach(article => {\n      stats[article.sentiment]++;\n    });\n    return stats;\n  }\n  \n  const filteredArticles = filter === 'all'\n    ? articles\n    : articles.filter(a => a.sentiment === filter);\n  \n  function getSentimentColor(sentiment) {\n    switch (sentiment) {\n      case 'positive': return '#4caf50';\n      case 'negative': return '#f44336';\n      default: return '#9e9e9e';\n    }\n  }\n  \n  function getSentimentEmoji(sentiment) {\n    switch (sentiment) {\n      case 'positive': return '😊';\n      case 'negative': return '😟';\n      default: return '😐';\n    }\n  }\n  \n  if (loading) return \u003Cdiv>Loading...\u003C\u002Fdiv>;\n  \n  return (\n    \u003Cdiv className=\"sentiment-dashboard\">\n      \u003Ch1>News Sentiment Analysis\u003C\u002Fh1>\n      \u003Cp className=\"subtitle\">Powered by AllNewsAPI's built-in AI sentiment analysis\u003C\u002Fp>\n      \n      {stats && (\n        \u003Cdiv className=\"stats-panel\">\n          \u003Cdiv className=\"stat\">\n            \u003Cspan className=\"stat-label\">Total Articles\u003C\u002Fspan>\n            \u003Cspan className=\"stat-value\">{stats.total}\u003C\u002Fspan>\n          \u003C\u002Fdiv>\n          \u003Cdiv className=\"stat positive\">\n            \u003Cspan className=\"stat-label\">Positive\u003C\u002Fspan>\n            \u003Cspan className=\"stat-value\">{stats.positive}\u003C\u002Fspan>\n          \u003C\u002Fdiv>\n          \u003Cdiv className=\"stat neutral\">\n            \u003Cspan className=\"stat-label\">Neutral\u003C\u002Fspan>\n            \u003Cspan className=\"stat-value\">{stats.neutral}\u003C\u002Fspan>\n          \u003C\u002Fdiv>\n          \u003Cdiv className=\"stat negative\">\n            \u003Cspan className=\"stat-label\">Negative\u003C\u002Fspan>\n            \u003Cspan className=\"stat-value\">{stats.negative}\u003C\u002Fspan>\n          \u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      )}\n      \n      \u003Cdiv className=\"filters\">\n        \u003Cbutton \n          className={filter === 'all' ? 'active' : ''}\n          onClick={() => setFilter('all')}\n        >\n          All\n        \u003C\u002Fbutton>\n        \u003Cbutton \n          className={filter === 'positive' ? 'active' : ''}\n          onClick={() => setFilter('positive')}\n        >\n          😊 Positive\n        \u003C\u002Fbutton>\n        \u003Cbutton \n          className={filter === 'neutral' ? 'active' : ''}\n          onClick={() => setFilter('neutral')}\n        >\n          😐 Neutral\n        \u003C\u002Fbutton>\n        \u003Cbutton \n          className={filter === 'negative' ? 'active' : ''}\n          onClick={() => setFilter('negative')}\n        >\n          😟 Negative\n        \u003C\u002Fbutton>\n      \u003C\u002Fdiv>\n      \n      \u003Cdiv className=\"articles-grid\">\n        {filteredArticles.map((article, index) => (\n          \u003Cdiv key={index} className=\"article-card\">\n            \u003Cdiv \n              className=\"sentiment-badge\"\n              style={{ backgroundColor: getSentimentColor(article.sentiment) }}\n            >\n              {getSentimentEmoji(article.sentiment)}\n              {article.sentiment}\n            \u003C\u002Fdiv>\n            \n            {\u002F* Show confidence scores *\u002F}\n            \u003Cdiv className=\"sentiment-scores\">\n              \u003Cdiv className=\"score-bar\">\n                \u003Cspan>Positive: {(article.sentimentScores.positive * 100).toFixed(0)}%\u003C\u002Fspan>\n                \u003Cdiv className=\"bar\" style={{ width: `${article.sentimentScores.positive * 100}%`, backgroundColor: '#4caf50' }} \u002F>\n              \u003C\u002Fdiv>\n              \u003Cdiv className=\"score-bar\">\n                \u003Cspan>Neutral: {(article.sentimentScores.neutral * 100).toFixed(0)}%\u003C\u002Fspan>\n                \u003Cdiv className=\"bar\" style={{ width: `${article.sentimentScores.neutral * 100}%`, backgroundColor: '#9e9e9e' }} \u002F>\n              \u003C\u002Fdiv>\n              \u003Cdiv className=\"score-bar\">\n                \u003Cspan>Negative: {(article.sentimentScores.negative * 100).toFixed(0)}%\u003C\u002Fspan>\n                \u003Cdiv className=\"bar\" style={{ width: `${article.sentimentScores.negative * 100}%`, backgroundColor: '#f44336' }} \u002F>\n              \u003C\u002Fdiv>\n            \u003C\u002Fdiv>\n            \n            \u003Ch3>{article.title}\u003C\u002Fh3>\n            \u003Cp>{article.description}\u003C\u002Fp>\n            \n            \u003Cdiv className=\"article-meta\">\n              \u003Cspan>{article.source.name}\u003C\u002Fspan>\n              \u003Cspan>{new Date(article.publishedAt).toLocaleDateString()}\u003C\u002Fspan>\n            \u003C\u002Fdiv>\n            \n            \u003Ca href={article.url} target=\"_blank\" rel=\"noopener noreferrer\">\n              Read More →\n            \u003C\u002Fa>\n          \u003C\u002Fdiv>\n        ))}\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  );\n}\n\nexport default SentimentDashboard;\n",[205,10722,10723,10736,10745,10749,10758,10778,10805,10831,10855,10859,10869,10876,10881,10885,10898,10904,10921,10938,10949,10953,10970,10974,10979,10986,10999,11008,11022,11030,11040,11044,11048,11052,11067,11099,11115,11125,11129,11137,11141,11145,11163,11171,11194,11198,11211,11219,11237,11253,11267,11271,11275,11279,11292,11298,11313,11328,11341,11345,11349,11353,11375,11379,11385,11400,11413,11433,11437,11446,11461,11476,11496,11516,11524,11539,11558,11577,11585,11600,11619,11638,11646,11661,11680,11699,11707,11715,11719,11723,11737,11745,11771,11792,11796,11801,11809,11817,11839,11858,11862,11867,11875,11883,11906,11925,11929,11934,11942,11950,11972,11991,11995,12000,12008,12016,12020,12035,12056,12077,12085,12095,12111,12116,12127,12132,12140,12146,12156,12172,12188,12221,12274,12284,12299,12327,12372,12381,12396,12424,12469,12478,12487,12492,12505,12518,12523,12539,12552,12578,12587,12592,12622,12628,12637,12646,12651,12660,12669,12674,12679,12684],{"__ignoreMap":203},[208,10724,10725,10727,10730,10732,10734],{"class":210,"line":211},[208,10726,1191],{"class":1190},[208,10728,10729],{"class":214}," React, { useState, useEffect } ",[208,10731,1197],{"class":1190},[208,10733,1200],{"class":245},[208,10735,1203],{"class":214},[208,10737,10738,10740,10743],{"class":210,"line":218},[208,10739,1191],{"class":1190},[208,10741,10742],{"class":245}," '.\u002FSentimentDashboard.css'",[208,10744,1203],{"class":214},[208,10746,10747],{"class":210,"line":228},[208,10748,1092],{"emptyLinePlaceholder":866},[208,10750,10751,10753,10756],{"class":210,"line":236},[208,10752,1212],{"class":1190},[208,10754,10755],{"class":1215}," SentimentDashboard",[208,10757,2297],{"class":214},[208,10759,10760,10762,10764,10766,10768,10770,10772,10774,10776],{"class":210,"line":252},[208,10761,1237],{"class":1190},[208,10763,2330],{"class":214},[208,10765,2333],{"class":221},[208,10767,1226],{"class":214},[208,10769,2338],{"class":221},[208,10771,2341],{"class":214},[208,10773,1778],{"class":1190},[208,10775,2346],{"class":1215},[208,10777,2349],{"class":214},[208,10779,10780,10782,10784,10787,10789,10792,10794,10796,10798,10800,10803],{"class":210,"line":261},[208,10781,1237],{"class":1190},[208,10783,2330],{"class":214},[208,10785,10786],{"class":221},"filter",[208,10788,1226],{"class":214},[208,10790,10791],{"class":221},"setFilter",[208,10793,2341],{"class":214},[208,10795,1778],{"class":1190},[208,10797,2346],{"class":1215},[208,10799,1727],{"class":214},[208,10801,10802],{"class":245},"'all'",[208,10804,2377],{"class":214},[208,10806,10807,10809,10811,10814,10816,10819,10821,10823,10825,10827,10829],{"class":210,"line":269},[208,10808,1237],{"class":1190},[208,10810,2330],{"class":214},[208,10812,10813],{"class":221},"stats",[208,10815,1226],{"class":214},[208,10817,10818],{"class":221},"setStats",[208,10820,2341],{"class":214},[208,10822,1778],{"class":1190},[208,10824,2346],{"class":1215},[208,10826,1727],{"class":214},[208,10828,5201],{"class":221},[208,10830,2377],{"class":214},[208,10832,10833,10835,10837,10839,10841,10843,10845,10847,10849,10851,10853],{"class":210,"line":277},[208,10834,1237],{"class":1190},[208,10836,2330],{"class":214},[208,10838,2358],{"class":221},[208,10840,1226],{"class":214},[208,10842,2363],{"class":221},[208,10844,2341],{"class":214},[208,10846,1778],{"class":1190},[208,10848,2346],{"class":1215},[208,10850,1727],{"class":214},[208,10852,2374],{"class":221},[208,10854,2377],{"class":214},[208,10856,10857],{"class":210,"line":283},[208,10858,1042],{"class":214},[208,10860,10861,10863,10865,10867],{"class":210,"line":289},[208,10862,5289],{"class":1215},[208,10864,5292],{"class":214},[208,10866,1712],{"class":1190},[208,10868,1715],{"class":214},[208,10870,10871,10874],{"class":210,"line":295},[208,10872,10873],{"class":1215},"    fetchNewsWithSentiment",[208,10875,2323],{"class":214},[208,10877,10878],{"class":210,"line":301},[208,10879,10880],{"class":214},"  }, []);\n",[208,10882,10883],{"class":210,"line":1078},[208,10884,1042],{"class":214},[208,10886,10887,10890,10893,10896],{"class":210,"line":1084},[208,10888,10889],{"class":1190},"  async",[208,10891,10892],{"class":1190}," function",[208,10894,10895],{"class":1215}," fetchNewsWithSentiment",[208,10897,2297],{"class":214},[208,10899,10900,10902],{"class":210,"line":1089},[208,10901,5335],{"class":1190},[208,10903,1715],{"class":214},[208,10905,10906,10908,10911,10913,10916,10919],{"class":210,"line":1095},[208,10907,5364],{"class":1190},[208,10909,10910],{"class":221}," API_KEY",[208,10912,1243],{"class":1190},[208,10914,10915],{"class":214}," process.env.",[208,10917,10918],{"class":221},"REACT_APP_NEWS_API_KEY",[208,10920,1203],{"class":214},[208,10922,10923,10925,10928,10930,10932,10935],{"class":210,"line":1481},[208,10924,5364],{"class":1190},[208,10926,10927],{"class":221}," response",[208,10929,1243],{"class":1190},[208,10931,2433],{"class":1190},[208,10933,10934],{"class":1215}," fetch",[208,10936,10937],{"class":214},"(\n",[208,10939,10940,10943,10946],{"class":210,"line":1501},[208,10941,10942],{"class":245},"        `https:\u002F\u002Fapi.allnewsapi.com\u002Fheadlines?apikey=${",[208,10944,10945],{"class":221},"API_KEY",[208,10947,10948],{"class":245},"}&country=us`\n",[208,10950,10951],{"class":210,"line":1521},[208,10952,8558],{"class":214},[208,10954,10955,10957,10959,10961,10963,10966,10968],{"class":210,"line":1541},[208,10956,5364],{"class":1190},[208,10958,5367],{"class":221},[208,10960,1243],{"class":1190},[208,10962,2433],{"class":1190},[208,10964,10965],{"class":214}," response.",[208,10967,202],{"class":1215},[208,10969,2323],{"class":214},[208,10971,10972],{"class":210,"line":1561},[208,10973,7580],{"class":214},[208,10975,10976],{"class":210,"line":1581},[208,10977,10978],{"class":2419},"      \u002F\u002F Articles already include sentiment data!\n",[208,10980,10981,10983],{"class":210,"line":1601},[208,10982,5382],{"class":1215},[208,10984,10985],{"class":214},"(data.articles);\n",[208,10987,10988,10991,10993,10996],{"class":210,"line":1621},[208,10989,10990],{"class":1215},"      setStats",[208,10992,1727],{"class":214},[208,10994,10995],{"class":1215},"calculateStats",[208,10997,10998],{"class":214},"(data.articles));\n",[208,11000,11001,11003,11005],{"class":210,"line":1641},[208,11002,5395],{"class":214},[208,11004,5398],{"class":1190},[208,11006,11007],{"class":214}," (error) {\n",[208,11009,11010,11012,11014,11016,11019],{"class":210,"line":1661},[208,11011,5417],{"class":214},[208,11013,5185],{"class":1215},[208,11015,1727],{"class":214},[208,11017,11018],{"class":245},"'Error fetching news:'",[208,11020,11021],{"class":214},", error);\n",[208,11023,11024,11026,11028],{"class":210,"line":1682},[208,11025,5395],{"class":214},[208,11027,5429],{"class":1190},[208,11029,1715],{"class":214},[208,11031,11032,11034,11036,11038],{"class":210,"line":1688},[208,11033,5342],{"class":1215},[208,11035,1727],{"class":214},[208,11037,5440],{"class":221},[208,11039,2377],{"class":214},[208,11041,11042],{"class":210,"line":1693},[208,11043,292],{"class":214},[208,11045,11046],{"class":210,"line":1718},[208,11047,298],{"class":214},[208,11049,11050],{"class":210,"line":1736},[208,11051,1042],{"class":214},[208,11053,11054,11057,11060,11062,11064],{"class":210,"line":1745},[208,11055,11056],{"class":1190},"  function",[208,11058,11059],{"class":1215}," calculateStats",[208,11061,1727],{"class":214},[208,11063,2333],{"class":1222},[208,11065,11066],{"class":214},") {\n",[208,11068,11069,11071,11074,11076,11079,11081,11084,11086,11089,11091,11094,11096],{"class":210,"line":1751},[208,11070,2425],{"class":1190},[208,11072,11073],{"class":221}," stats",[208,11075,1243],{"class":1190},[208,11077,11078],{"class":214}," { total: articles.",[208,11080,2579],{"class":221},[208,11082,11083],{"class":214},", positive: ",[208,11085,2784],{"class":221},[208,11087,11088],{"class":214},", negative: ",[208,11090,2784],{"class":221},[208,11092,11093],{"class":214},", neutral: ",[208,11095,2784],{"class":221},[208,11097,11098],{"class":214}," };\n",[208,11100,11101,11104,11107,11109,11111,11113],{"class":210,"line":1756},[208,11102,11103],{"class":214},"    articles.",[208,11105,11106],{"class":1215},"forEach",[208,11108,1727],{"class":214},[208,11110,4035],{"class":1222},[208,11112,1853],{"class":1190},[208,11114,1715],{"class":214},[208,11116,11117,11120,11123],{"class":210,"line":1765},[208,11118,11119],{"class":214},"      stats[article.sentiment]",[208,11121,11122],{"class":1190},"++",[208,11124,1203],{"class":214},[208,11126,11127],{"class":210,"line":1787},[208,11128,3603],{"class":214},[208,11130,11131,11134],{"class":210,"line":1799},[208,11132,11133],{"class":1190},"    return",[208,11135,11136],{"class":214}," stats;\n",[208,11138,11139],{"class":210,"line":1810},[208,11140,298],{"class":214},[208,11142,11143],{"class":210,"line":1833},[208,11144,1042],{"class":214},[208,11146,11147,11149,11152,11154,11157,11160],{"class":210,"line":1839},[208,11148,1237],{"class":1190},[208,11150,11151],{"class":221}," filteredArticles",[208,11153,1243],{"class":1190},[208,11155,11156],{"class":214}," filter ",[208,11158,11159],{"class":1190},"===",[208,11161,11162],{"class":245}," 'all'\n",[208,11164,11165,11168],{"class":210,"line":1858},[208,11166,11167],{"class":1190},"    ?",[208,11169,11170],{"class":214}," articles\n",[208,11172,11173,11176,11178,11180,11182,11184,11186,11189,11191],{"class":210,"line":1883},[208,11174,11175],{"class":1190},"    :",[208,11177,2576],{"class":214},[208,11179,10786],{"class":1215},[208,11181,1727],{"class":214},[208,11183,182],{"class":1222},[208,11185,1853],{"class":1190},[208,11187,11188],{"class":214}," a.sentiment ",[208,11190,11159],{"class":1190},[208,11192,11193],{"class":214}," filter);\n",[208,11195,11196],{"class":210,"line":1889},[208,11197,1042],{"class":214},[208,11199,11200,11202,11205,11207,11209],{"class":210,"line":1899},[208,11201,11056],{"class":1190},[208,11203,11204],{"class":1215}," getSentimentColor",[208,11206,1727],{"class":214},[208,11208,9990],{"class":1222},[208,11210,11066],{"class":214},[208,11212,11213,11216],{"class":210,"line":1905},[208,11214,11215],{"class":1190},"    switch",[208,11217,11218],{"class":214}," (sentiment) {\n",[208,11220,11221,11224,11227,11229,11232,11235],{"class":210,"line":1915},[208,11222,11223],{"class":1190},"      case",[208,11225,11226],{"class":245}," 'positive'",[208,11228,242],{"class":214},[208,11230,11231],{"class":1190},"return",[208,11233,11234],{"class":245}," '#4caf50'",[208,11236,1203],{"class":214},[208,11238,11239,11241,11244,11246,11248,11251],{"class":210,"line":1925},[208,11240,11223],{"class":1190},[208,11242,11243],{"class":245}," 'negative'",[208,11245,242],{"class":214},[208,11247,11231],{"class":1190},[208,11249,11250],{"class":245}," '#f44336'",[208,11252,1203],{"class":214},[208,11254,11255,11258,11260,11262,11265],{"class":210,"line":1930},[208,11256,11257],{"class":1190},"      default",[208,11259,242],{"class":214},[208,11261,11231],{"class":1190},[208,11263,11264],{"class":245}," '#9e9e9e'",[208,11266,1203],{"class":214},[208,11268,11269],{"class":210,"line":1935},[208,11270,292],{"class":214},[208,11272,11273],{"class":210,"line":1940},[208,11274,298],{"class":214},[208,11276,11277],{"class":210,"line":2230},[208,11278,1042],{"class":214},[208,11280,11281,11283,11286,11288,11290],{"class":210,"line":2236},[208,11282,11056],{"class":1190},[208,11284,11285],{"class":1215}," getSentimentEmoji",[208,11287,1727],{"class":214},[208,11289,9990],{"class":1222},[208,11291,11066],{"class":214},[208,11293,11294,11296],{"class":210,"line":2242},[208,11295,11215],{"class":1190},[208,11297,11218],{"class":214},[208,11299,11300,11302,11304,11306,11308,11311],{"class":210,"line":2247},[208,11301,11223],{"class":1190},[208,11303,11226],{"class":245},[208,11305,242],{"class":214},[208,11307,11231],{"class":1190},[208,11309,11310],{"class":245}," '😊'",[208,11312,1203],{"class":214},[208,11314,11315,11317,11319,11321,11323,11326],{"class":210,"line":2253},[208,11316,11223],{"class":1190},[208,11318,11243],{"class":245},[208,11320,242],{"class":214},[208,11322,11231],{"class":1190},[208,11324,11325],{"class":245}," '😟'",[208,11327,1203],{"class":214},[208,11329,11330,11332,11334,11336,11339],{"class":210,"line":2258},[208,11331,11257],{"class":1190},[208,11333,242],{"class":214},[208,11335,11231],{"class":1190},[208,11337,11338],{"class":245}," '😐'",[208,11340,1203],{"class":214},[208,11342,11343],{"class":210,"line":3213},[208,11344,292],{"class":214},[208,11346,11347],{"class":210,"line":3219},[208,11348,298],{"class":214},[208,11350,11351],{"class":210,"line":5034},[208,11352,1042],{"class":214},[208,11354,11355,11358,11361,11363,11365,11367,11370,11372],{"class":210,"line":5713},[208,11356,11357],{"class":1190},"  if",[208,11359,11360],{"class":214}," (loading) ",[208,11362,11231],{"class":1190},[208,11364,5984],{"class":214},[208,11366,1772],{"class":1771},[208,11368,11369],{"class":214},">Loading...\u003C\u002F",[208,11371,1772],{"class":1771},[208,11373,11374],{"class":214},">;\n",[208,11376,11377],{"class":210,"line":5729},[208,11378,1042],{"class":214},[208,11380,11381,11383],{"class":210,"line":5737},[208,11382,1759],{"class":1190},[208,11384,1762],{"class":214},[208,11386,11387,11389,11391,11393,11395,11398],{"class":210,"line":5748},[208,11388,1768],{"class":214},[208,11390,1772],{"class":1771},[208,11392,1775],{"class":1215},[208,11394,1778],{"class":1190},[208,11396,11397],{"class":245},"\"sentiment-dashboard\"",[208,11399,1784],{"class":214},[208,11401,11402,11404,11406,11409,11411],{"class":210,"line":5759},[208,11403,1790],{"class":214},[208,11405,2482],{"class":1771},[208,11407,11408],{"class":214},">News Sentiment Analysis\u003C\u002F",[208,11410,2482],{"class":1771},[208,11412,1784],{"class":214},[208,11414,11415,11417,11419,11421,11423,11426,11429,11431],{"class":210,"line":5770},[208,11416,1790],{"class":214},[208,11418,12],{"class":1771},[208,11420,1775],{"class":1215},[208,11422,1778],{"class":1190},[208,11424,11425],{"class":245},"\"subtitle\"",[208,11427,11428],{"class":214},">Powered by AllNewsAPI's built-in AI sentiment analysis\u003C\u002F",[208,11430,12],{"class":1771},[208,11432,1784],{"class":214},[208,11434,11435],{"class":210,"line":5781},[208,11436,7580],{"class":214},[208,11438,11439,11442,11444],{"class":210,"line":5786},[208,11440,11441],{"class":214},"      {stats ",[208,11443,4066],{"class":1190},[208,11445,1762],{"class":214},[208,11447,11448,11450,11452,11454,11456,11459],{"class":210,"line":5791},[208,11449,2548],{"class":214},[208,11451,1772],{"class":1771},[208,11453,1775],{"class":1215},[208,11455,1778],{"class":1190},[208,11457,11458],{"class":245},"\"stats-panel\"",[208,11460,1784],{"class":214},[208,11462,11463,11465,11467,11469,11471,11474],{"class":210,"line":5817},[208,11464,1861],{"class":214},[208,11466,1772],{"class":1771},[208,11468,1775],{"class":1215},[208,11470,1778],{"class":1190},[208,11472,11473],{"class":245},"\"stat\"",[208,11475,1784],{"class":214},[208,11477,11478,11480,11482,11484,11486,11489,11492,11494],{"class":210,"line":5825},[208,11479,4742],{"class":214},[208,11481,208],{"class":1771},[208,11483,1775],{"class":1215},[208,11485,1778],{"class":1190},[208,11487,11488],{"class":245},"\"stat-label\"",[208,11490,11491],{"class":214},">Total Articles\u003C\u002F",[208,11493,208],{"class":1771},[208,11495,1784],{"class":214},[208,11497,11498,11500,11502,11504,11506,11509,11512,11514],{"class":210,"line":5836},[208,11499,4742],{"class":214},[208,11501,208],{"class":1771},[208,11503,1775],{"class":1215},[208,11505,1778],{"class":1190},[208,11507,11508],{"class":245},"\"stat-value\"",[208,11510,11511],{"class":214},">{stats.total}\u003C\u002F",[208,11513,208],{"class":1771},[208,11515,1784],{"class":214},[208,11517,11518,11520,11522],{"class":210,"line":5847},[208,11519,1892],{"class":214},[208,11521,1772],{"class":1771},[208,11523,1784],{"class":214},[208,11525,11526,11528,11530,11532,11534,11537],{"class":210,"line":5858},[208,11527,1861],{"class":214},[208,11529,1772],{"class":1771},[208,11531,1775],{"class":1215},[208,11533,1778],{"class":1190},[208,11535,11536],{"class":245},"\"stat positive\"",[208,11538,1784],{"class":214},[208,11540,11541,11543,11545,11547,11549,11551,11554,11556],{"class":210,"line":5879},[208,11542,4742],{"class":214},[208,11544,208],{"class":1771},[208,11546,1775],{"class":1215},[208,11548,1778],{"class":1190},[208,11550,11488],{"class":245},[208,11552,11553],{"class":214},">Positive\u003C\u002F",[208,11555,208],{"class":1771},[208,11557,1784],{"class":214},[208,11559,11560,11562,11564,11566,11568,11570,11573,11575],{"class":210,"line":5890},[208,11561,4742],{"class":214},[208,11563,208],{"class":1771},[208,11565,1775],{"class":1215},[208,11567,1778],{"class":1190},[208,11569,11508],{"class":245},[208,11571,11572],{"class":214},">{stats.positive}\u003C\u002F",[208,11574,208],{"class":1771},[208,11576,1784],{"class":214},[208,11578,11579,11581,11583],{"class":210,"line":5896},[208,11580,1892],{"class":214},[208,11582,1772],{"class":1771},[208,11584,1784],{"class":214},[208,11586,11587,11589,11591,11593,11595,11598],{"class":210,"line":5921},[208,11588,1861],{"class":214},[208,11590,1772],{"class":1771},[208,11592,1775],{"class":1215},[208,11594,1778],{"class":1190},[208,11596,11597],{"class":245},"\"stat neutral\"",[208,11599,1784],{"class":214},[208,11601,11602,11604,11606,11608,11610,11612,11615,11617],{"class":210,"line":5927},[208,11603,4742],{"class":214},[208,11605,208],{"class":1771},[208,11607,1775],{"class":1215},[208,11609,1778],{"class":1190},[208,11611,11488],{"class":245},[208,11613,11614],{"class":214},">Neutral\u003C\u002F",[208,11616,208],{"class":1771},[208,11618,1784],{"class":214},[208,11620,11621,11623,11625,11627,11629,11631,11634,11636],{"class":210,"line":5936},[208,11622,4742],{"class":214},[208,11624,208],{"class":1771},[208,11626,1775],{"class":1215},[208,11628,1778],{"class":1190},[208,11630,11508],{"class":245},[208,11632,11633],{"class":214},">{stats.neutral}\u003C\u002F",[208,11635,208],{"class":1771},[208,11637,1784],{"class":214},[208,11639,11640,11642,11644],{"class":210,"line":5945},[208,11641,1892],{"class":214},[208,11643,1772],{"class":1771},[208,11645,1784],{"class":214},[208,11647,11648,11650,11652,11654,11656,11659],{"class":210,"line":5954},[208,11649,1861],{"class":214},[208,11651,1772],{"class":1771},[208,11653,1775],{"class":1215},[208,11655,1778],{"class":1190},[208,11657,11658],{"class":245},"\"stat negative\"",[208,11660,1784],{"class":214},[208,11662,11663,11665,11667,11669,11671,11673,11676,11678],{"class":210,"line":5959},[208,11664,4742],{"class":214},[208,11666,208],{"class":1771},[208,11668,1775],{"class":1215},[208,11670,1778],{"class":1190},[208,11672,11488],{"class":245},[208,11674,11675],{"class":214},">Negative\u003C\u002F",[208,11677,208],{"class":1771},[208,11679,1784],{"class":214},[208,11681,11682,11684,11686,11688,11690,11692,11695,11697],{"class":210,"line":5976},[208,11683,4742],{"class":214},[208,11685,208],{"class":1771},[208,11687,1775],{"class":1215},[208,11689,1778],{"class":1190},[208,11691,11508],{"class":245},[208,11693,11694],{"class":214},">{stats.negative}\u003C\u002F",[208,11696,208],{"class":1771},[208,11698,1784],{"class":214},[208,11700,11701,11703,11705],{"class":210,"line":6004},[208,11702,1892],{"class":214},[208,11704,1772],{"class":1771},[208,11706,1784],{"class":214},[208,11708,11709,11711,11713],{"class":210,"line":6010},[208,11710,4258],{"class":214},[208,11712,1772],{"class":1771},[208,11714,1784],{"class":214},[208,11716,11717],{"class":210,"line":6036},[208,11718,2639],{"class":214},[208,11720,11721],{"class":210,"line":6041},[208,11722,7580],{"class":214},[208,11724,11725,11727,11729,11731,11733,11735],{"class":210,"line":6074},[208,11726,1790],{"class":214},[208,11728,1772],{"class":1771},[208,11730,1775],{"class":1215},[208,11732,1778],{"class":1190},[208,11734,4630],{"class":245},[208,11736,1784],{"class":214},[208,11738,11739,11741,11743],{"class":210,"line":6095},[208,11740,2548],{"class":214},[208,11742,5901],{"class":1771},[208,11744,1796],{"class":214},[208,11746,11747,11749,11751,11754,11756,11759,11761,11764,11767,11769],{"class":210,"line":6101},[208,11748,4102],{"class":1215},[208,11750,1778],{"class":1190},[208,11752,11753],{"class":214},"{filter ",[208,11755,11159],{"class":1190},[208,11757,11758],{"class":245}," 'all'",[208,11760,2588],{"class":1190},[208,11762,11763],{"class":245}," 'active'",[208,11765,11766],{"class":1190}," :",[208,11768,4853],{"class":245},[208,11770,304],{"class":214},[208,11772,11773,11776,11778,11781,11783,11786,11788,11790],{"class":210,"line":6106},[208,11774,11775],{"class":1215},"          onClick",[208,11777,1778],{"class":1190},[208,11779,11780],{"class":214},"{() ",[208,11782,1712],{"class":1190},[208,11784,11785],{"class":1215}," setFilter",[208,11787,1727],{"class":214},[208,11789,10802],{"class":245},[208,11791,4884],{"class":214},[208,11793,11794],{"class":210,"line":6136},[208,11795,4316],{"class":214},[208,11797,11798],{"class":210,"line":6152},[208,11799,11800],{"class":214},"          All\n",[208,11802,11803,11805,11807],{"class":210,"line":6176},[208,11804,4258],{"class":214},[208,11806,5901],{"class":1771},[208,11808,1784],{"class":214},[208,11810,11811,11813,11815],{"class":210,"line":6199},[208,11812,2548],{"class":214},[208,11814,5901],{"class":1771},[208,11816,1796],{"class":214},[208,11818,11819,11821,11823,11825,11827,11829,11831,11833,11835,11837],{"class":210,"line":6205},[208,11820,4102],{"class":1215},[208,11822,1778],{"class":1190},[208,11824,11753],{"class":214},[208,11826,11159],{"class":1190},[208,11828,11226],{"class":245},[208,11830,2588],{"class":1190},[208,11832,11763],{"class":245},[208,11834,11766],{"class":1190},[208,11836,4853],{"class":245},[208,11838,304],{"class":214},[208,11840,11841,11843,11845,11847,11849,11851,11853,11856],{"class":210,"line":6214},[208,11842,11775],{"class":1215},[208,11844,1778],{"class":1190},[208,11846,11780],{"class":214},[208,11848,1712],{"class":1190},[208,11850,11785],{"class":1215},[208,11852,1727],{"class":214},[208,11854,11855],{"class":245},"'positive'",[208,11857,4884],{"class":214},[208,11859,11860],{"class":210,"line":6219},[208,11861,4316],{"class":214},[208,11863,11864],{"class":210,"line":6228},[208,11865,11866],{"class":214},"          😊 Positive\n",[208,11868,11869,11871,11873],{"class":210,"line":6237},[208,11870,4258],{"class":214},[208,11872,5901],{"class":1771},[208,11874,1784],{"class":214},[208,11876,11877,11879,11881],{"class":210,"line":6242},[208,11878,2548],{"class":214},[208,11880,5901],{"class":1771},[208,11882,1796],{"class":214},[208,11884,11885,11887,11889,11891,11893,11896,11898,11900,11902,11904],{"class":210,"line":6247},[208,11886,4102],{"class":1215},[208,11888,1778],{"class":1190},[208,11890,11753],{"class":214},[208,11892,11159],{"class":1190},[208,11894,11895],{"class":245}," 'neutral'",[208,11897,2588],{"class":1190},[208,11899,11763],{"class":245},[208,11901,11766],{"class":1190},[208,11903,4853],{"class":245},[208,11905,304],{"class":214},[208,11907,11908,11910,11912,11914,11916,11918,11920,11923],{"class":210,"line":6252},[208,11909,11775],{"class":1215},[208,11911,1778],{"class":1190},[208,11913,11780],{"class":214},[208,11915,1712],{"class":1190},[208,11917,11785],{"class":1215},[208,11919,1727],{"class":214},[208,11921,11922],{"class":245},"'neutral'",[208,11924,4884],{"class":214},[208,11926,11927],{"class":210,"line":7238},[208,11928,4316],{"class":214},[208,11930,11931],{"class":210,"line":7244},[208,11932,11933],{"class":214},"          😐 Neutral\n",[208,11935,11936,11938,11940],{"class":210,"line":7250},[208,11937,4258],{"class":214},[208,11939,5901],{"class":1771},[208,11941,1784],{"class":214},[208,11943,11944,11946,11948],{"class":210,"line":7256},[208,11945,2548],{"class":214},[208,11947,5901],{"class":1771},[208,11949,1796],{"class":214},[208,11951,11952,11954,11956,11958,11960,11962,11964,11966,11968,11970],{"class":210,"line":7262},[208,11953,4102],{"class":1215},[208,11955,1778],{"class":1190},[208,11957,11753],{"class":214},[208,11959,11159],{"class":1190},[208,11961,11243],{"class":245},[208,11963,2588],{"class":1190},[208,11965,11763],{"class":245},[208,11967,11766],{"class":1190},[208,11969,4853],{"class":245},[208,11971,304],{"class":214},[208,11973,11974,11976,11978,11980,11982,11984,11986,11989],{"class":210,"line":7267},[208,11975,11775],{"class":1215},[208,11977,1778],{"class":1190},[208,11979,11780],{"class":214},[208,11981,1712],{"class":1190},[208,11983,11785],{"class":1215},[208,11985,1727],{"class":214},[208,11987,11988],{"class":245},"'negative'",[208,11990,4884],{"class":214},[208,11992,11993],{"class":210,"line":7273},[208,11994,4316],{"class":214},[208,11996,11997],{"class":210,"line":7279},[208,11998,11999],{"class":214},"          😟 Negative\n",[208,12001,12002,12004,12006],{"class":210,"line":7285},[208,12003,4258],{"class":214},[208,12005,5901],{"class":1771},[208,12007,1784],{"class":214},[208,12009,12010,12012,12014],{"class":210,"line":7291},[208,12011,1908],{"class":214},[208,12013,1772],{"class":1771},[208,12015,1784],{"class":214},[208,12017,12018],{"class":210,"line":7296},[208,12019,7580],{"class":214},[208,12021,12022,12024,12026,12028,12030,12033],{"class":210,"line":7301},[208,12023,1790],{"class":214},[208,12025,1772],{"class":1771},[208,12027,1775],{"class":1215},[208,12029,1778],{"class":1190},[208,12031,12032],{"class":245},"\"articles-grid\"",[208,12034,1784],{"class":214},[208,12036,12037,12040,12042,12044,12046,12048,12050,12052,12054],{"class":210,"line":7306},[208,12038,12039],{"class":214},"        {filteredArticles.",[208,12041,1845],{"class":1215},[208,12043,6160],{"class":214},[208,12045,4035],{"class":1222},[208,12047,1226],{"class":214},[208,12049,6167],{"class":1222},[208,12051,1709],{"class":214},[208,12053,1712],{"class":1190},[208,12055,1762],{"class":214},[208,12057,12058,12060,12062,12064,12066,12068,12070,12072,12075],{"class":210,"line":7311},[208,12059,1861],{"class":214},[208,12061,1772],{"class":1771},[208,12063,1867],{"class":1215},[208,12065,1778],{"class":1190},[208,12067,6189],{"class":214},[208,12069,5807],{"class":1215},[208,12071,1778],{"class":1190},[208,12073,12074],{"class":245},"\"article-card\"",[208,12076,1784],{"class":214},[208,12078,12079,12081,12083],{"class":210,"line":7317},[208,12080,4742],{"class":214},[208,12082,1772],{"class":1771},[208,12084,1796],{"class":214},[208,12086,12087,12090,12092],{"class":210,"line":7322},[208,12088,12089],{"class":1215},"              className",[208,12091,1778],{"class":1190},[208,12093,12094],{"class":245},"\"sentiment-badge\"\n",[208,12096,12097,12100,12102,12105,12108],{"class":210,"line":7328},[208,12098,12099],{"class":1215},"              style",[208,12101,1778],{"class":1190},[208,12103,12104],{"class":214},"{{ backgroundColor: ",[208,12106,12107],{"class":1215},"getSentimentColor",[208,12109,12110],{"class":214},"(article.sentiment) }}\n",[208,12112,12113],{"class":210,"line":7334},[208,12114,12115],{"class":214},"            >\n",[208,12117,12118,12121,12124],{"class":210,"line":7340},[208,12119,12120],{"class":214},"              {",[208,12122,12123],{"class":1215},"getSentimentEmoji",[208,12125,12126],{"class":214},"(article.sentiment)}\n",[208,12128,12129],{"class":210,"line":7345},[208,12130,12131],{"class":214},"              {article.sentiment}\n",[208,12133,12134,12136,12138],{"class":210,"line":7351},[208,12135,4987],{"class":214},[208,12137,1772],{"class":1771},[208,12139,1784],{"class":214},[208,12141,12143],{"class":210,"line":12142},125,[208,12144,12145],{"class":214},"            \n",[208,12147,12149,12151,12154],{"class":210,"line":12148},126,[208,12150,4226],{"class":214},[208,12152,12153],{"class":2419},"\u002F* Show confidence scores *\u002F",[208,12155,304],{"class":214},[208,12157,12159,12161,12163,12165,12167,12170],{"class":210,"line":12158},127,[208,12160,4742],{"class":214},[208,12162,1772],{"class":1771},[208,12164,1775],{"class":1215},[208,12166,1778],{"class":1190},[208,12168,12169],{"class":245},"\"sentiment-scores\"",[208,12171,1784],{"class":214},[208,12173,12175,12177,12179,12181,12183,12186],{"class":210,"line":12174},128,[208,12176,6179],{"class":214},[208,12178,1772],{"class":1771},[208,12180,1775],{"class":1215},[208,12182,1778],{"class":1190},[208,12184,12185],{"class":245},"\"score-bar\"",[208,12187,1784],{"class":214},[208,12189,12191,12194,12196,12199,12202,12205,12207,12210,12212,12214,12217,12219],{"class":210,"line":12190},129,[208,12192,12193],{"class":214},"                \u003C",[208,12195,208],{"class":1771},[208,12197,12198],{"class":214},">Positive: {(article.sentimentScores.positive ",[208,12200,12201],{"class":1190},"*",[208,12203,12204],{"class":221}," 100",[208,12206,4960],{"class":214},[208,12208,12209],{"class":1215},"toFixed",[208,12211,1727],{"class":214},[208,12213,2784],{"class":221},[208,12215,12216],{"class":214},")}%\u003C\u002F",[208,12218,208],{"class":1771},[208,12220,1784],{"class":214},[208,12222,12224,12226,12228,12230,12232,12235,12238,12240,12243,12246,12248,12250,12252,12254,12257,12260,12262,12265,12268,12271],{"class":210,"line":12223},130,[208,12225,12193],{"class":214},[208,12227,1772],{"class":1771},[208,12229,1775],{"class":1215},[208,12231,1778],{"class":1190},[208,12233,12234],{"class":245},"\"bar\"",[208,12236,12237],{"class":1215}," style",[208,12239,1778],{"class":1190},[208,12241,12242],{"class":214},"{{ width: ",[208,12244,12245],{"class":245},"`${",[208,12247,4035],{"class":214},[208,12249,823],{"class":245},[208,12251,9996],{"class":214},[208,12253,823],{"class":245},[208,12255,12256],{"class":214},"positive",[208,12258,12259],{"class":1190}," *",[208,12261,12204],{"class":221},[208,12263,12264],{"class":245},"}%`",[208,12266,12267],{"class":214},", backgroundColor: ",[208,12269,12270],{"class":245},"'#4caf50'",[208,12272,12273],{"class":214}," }} \u002F>\n",[208,12275,12277,12280,12282],{"class":210,"line":12276},131,[208,12278,12279],{"class":214},"              \u003C\u002F",[208,12281,1772],{"class":1771},[208,12283,1784],{"class":214},[208,12285,12287,12289,12291,12293,12295,12297],{"class":210,"line":12286},132,[208,12288,6179],{"class":214},[208,12290,1772],{"class":1771},[208,12292,1775],{"class":1215},[208,12294,1778],{"class":1190},[208,12296,12185],{"class":245},[208,12298,1784],{"class":214},[208,12300,12302,12304,12306,12309,12311,12313,12315,12317,12319,12321,12323,12325],{"class":210,"line":12301},133,[208,12303,12193],{"class":214},[208,12305,208],{"class":1771},[208,12307,12308],{"class":214},">Neutral: {(article.sentimentScores.neutral ",[208,12310,12201],{"class":1190},[208,12312,12204],{"class":221},[208,12314,4960],{"class":214},[208,12316,12209],{"class":1215},[208,12318,1727],{"class":214},[208,12320,2784],{"class":221},[208,12322,12216],{"class":214},[208,12324,208],{"class":1771},[208,12326,1784],{"class":214},[208,12328,12330,12332,12334,12336,12338,12340,12342,12344,12346,12348,12350,12352,12354,12356,12359,12361,12363,12365,12367,12370],{"class":210,"line":12329},134,[208,12331,12193],{"class":214},[208,12333,1772],{"class":1771},[208,12335,1775],{"class":1215},[208,12337,1778],{"class":1190},[208,12339,12234],{"class":245},[208,12341,12237],{"class":1215},[208,12343,1778],{"class":1190},[208,12345,12242],{"class":214},[208,12347,12245],{"class":245},[208,12349,4035],{"class":214},[208,12351,823],{"class":245},[208,12353,9996],{"class":214},[208,12355,823],{"class":245},[208,12357,12358],{"class":214},"neutral",[208,12360,12259],{"class":1190},[208,12362,12204],{"class":221},[208,12364,12264],{"class":245},[208,12366,12267],{"class":214},[208,12368,12369],{"class":245},"'#9e9e9e'",[208,12371,12273],{"class":214},[208,12373,12375,12377,12379],{"class":210,"line":12374},135,[208,12376,12279],{"class":214},[208,12378,1772],{"class":1771},[208,12380,1784],{"class":214},[208,12382,12384,12386,12388,12390,12392,12394],{"class":210,"line":12383},136,[208,12385,6179],{"class":214},[208,12387,1772],{"class":1771},[208,12389,1775],{"class":1215},[208,12391,1778],{"class":1190},[208,12393,12185],{"class":245},[208,12395,1784],{"class":214},[208,12397,12399,12401,12403,12406,12408,12410,12412,12414,12416,12418,12420,12422],{"class":210,"line":12398},137,[208,12400,12193],{"class":214},[208,12402,208],{"class":1771},[208,12404,12405],{"class":214},">Negative: {(article.sentimentScores.negative ",[208,12407,12201],{"class":1190},[208,12409,12204],{"class":221},[208,12411,4960],{"class":214},[208,12413,12209],{"class":1215},[208,12415,1727],{"class":214},[208,12417,2784],{"class":221},[208,12419,12216],{"class":214},[208,12421,208],{"class":1771},[208,12423,1784],{"class":214},[208,12425,12427,12429,12431,12433,12435,12437,12439,12441,12443,12445,12447,12449,12451,12453,12456,12458,12460,12462,12464,12467],{"class":210,"line":12426},138,[208,12428,12193],{"class":214},[208,12430,1772],{"class":1771},[208,12432,1775],{"class":1215},[208,12434,1778],{"class":1190},[208,12436,12234],{"class":245},[208,12438,12237],{"class":1215},[208,12440,1778],{"class":1190},[208,12442,12242],{"class":214},[208,12444,12245],{"class":245},[208,12446,4035],{"class":214},[208,12448,823],{"class":245},[208,12450,9996],{"class":214},[208,12452,823],{"class":245},[208,12454,12455],{"class":214},"negative",[208,12457,12259],{"class":1190},[208,12459,12204],{"class":221},[208,12461,12264],{"class":245},[208,12463,12267],{"class":214},[208,12465,12466],{"class":245},"'#f44336'",[208,12468,12273],{"class":214},[208,12470,12472,12474,12476],{"class":210,"line":12471},139,[208,12473,12279],{"class":214},[208,12475,1772],{"class":1771},[208,12477,1784],{"class":214},[208,12479,12481,12483,12485],{"class":210,"line":12480},140,[208,12482,4987],{"class":214},[208,12484,1772],{"class":1771},[208,12486,1784],{"class":214},[208,12488,12490],{"class":210,"line":12489},141,[208,12491,12145],{"class":214},[208,12493,12495,12497,12499,12501,12503],{"class":210,"line":12494},142,[208,12496,4742],{"class":214},[208,12498,94],{"class":1771},[208,12500,4147],{"class":214},[208,12502,94],{"class":1771},[208,12504,1784],{"class":214},[208,12506,12508,12510,12512,12514,12516],{"class":210,"line":12507},143,[208,12509,4742],{"class":214},[208,12511,12],{"class":1771},[208,12513,4167],{"class":214},[208,12515,12],{"class":1771},[208,12517,1784],{"class":214},[208,12519,12521],{"class":210,"line":12520},144,[208,12522,12145],{"class":214},[208,12524,12526,12528,12530,12532,12534,12537],{"class":210,"line":12525},145,[208,12527,4742],{"class":214},[208,12529,1772],{"class":1771},[208,12531,1775],{"class":1215},[208,12533,1778],{"class":1190},[208,12535,12536],{"class":245},"\"article-meta\"",[208,12538,1784],{"class":214},[208,12540,12542,12544,12546,12548,12550],{"class":210,"line":12541},146,[208,12543,6179],{"class":214},[208,12545,208],{"class":1771},[208,12547,4202],{"class":214},[208,12549,208],{"class":1771},[208,12551,1784],{"class":214},[208,12553,12555,12557,12559,12561,12563,12565,12568,12571,12574,12576],{"class":210,"line":12554},147,[208,12556,6179],{"class":214},[208,12558,208],{"class":1771},[208,12560,2485],{"class":214},[208,12562,4234],{"class":1190},[208,12564,4237],{"class":1215},[208,12566,12567],{"class":214},"(article.publishedAt).",[208,12569,12570],{"class":1215},"toLocaleDateString",[208,12572,12573],{"class":214},"()}\u003C\u002F",[208,12575,208],{"class":1771},[208,12577,1784],{"class":214},[208,12579,12581,12583,12585],{"class":210,"line":12580},148,[208,12582,4987],{"class":214},[208,12584,1772],{"class":1771},[208,12586,1784],{"class":214},[208,12588,12590],{"class":210,"line":12589},149,[208,12591,12145],{"class":214},[208,12593,12595,12597,12599,12601,12603,12606,12609,12611,12613,12615,12617,12620],{"class":210,"line":12594},150,[208,12596,4742],{"class":214},[208,12598,182],{"class":1771},[208,12600,3312],{"class":1215},[208,12602,1778],{"class":1190},[208,12604,12605],{"class":214},"{article.url} ",[208,12607,12608],{"class":1215},"target",[208,12610,1778],{"class":1190},[208,12612,4290],{"class":245},[208,12614,3296],{"class":1215},[208,12616,1778],{"class":1190},[208,12618,12619],{"class":245},"\"noopener noreferrer\"",[208,12621,1784],{"class":214},[208,12623,12625],{"class":210,"line":12624},151,[208,12626,12627],{"class":214},"              Read More →\n",[208,12629,12631,12633,12635],{"class":210,"line":12630},152,[208,12632,4987],{"class":214},[208,12634,182],{"class":1771},[208,12636,1784],{"class":214},[208,12638,12640,12642,12644],{"class":210,"line":12639},153,[208,12641,1892],{"class":214},[208,12643,1772],{"class":1771},[208,12645,1784],{"class":214},[208,12647,12649],{"class":210,"line":12648},154,[208,12650,1902],{"class":214},[208,12652,12654,12656,12658],{"class":210,"line":12653},155,[208,12655,1908],{"class":214},[208,12657,1772],{"class":1771},[208,12659,1784],{"class":214},[208,12661,12663,12665,12667],{"class":210,"line":12662},156,[208,12664,1918],{"class":214},[208,12666,1772],{"class":1771},[208,12668,1784],{"class":214},[208,12670,12672],{"class":210,"line":12671},157,[208,12673,1130],{"class":214},[208,12675,12677],{"class":210,"line":12676},158,[208,12678,304],{"class":214},[208,12680,12682],{"class":210,"line":12681},159,[208,12683,1092],{"emptyLinePlaceholder":866},[208,12685,12687,12689,12691],{"class":210,"line":12686},160,[208,12688,1943],{"class":1190},[208,12690,1946],{"class":1190},[208,12692,12693],{"class":214}," SentimentDashboard;\n",[21,12695,12697],{"id":12696},"step-6-visualizing-sentiment-trends","Step 6: Visualizing Sentiment Trends",[12,12699,12700],{},"Create a sentiment timeline chart using AllNewsAPI's sentiment data:",[198,12702,12704],{"className":1013,"code":12703,"language":1015,"meta":203,"style":203},"import { Line } from 'react-chartjs-2';\n\nfunction SentimentTrendChart({ articles }) {\n  \u002F\u002F Group articles by date using built-in sentiment\n  const sentimentByDate = articles.reduce((acc, article) => {\n    const date = new Date(article.publishedAt).toLocaleDateString();\n    \n    if (!acc[date]) {\n      acc[date] = { positive: 0, negative: 0, neutral: 0, total: 0 };\n    }\n    \n    \u002F\u002F Use the built-in sentiment classification\n    acc[date][article.sentiment]++;\n    acc[date].total++;\n    \n    return acc;\n  }, {});\n  \n  const dates = Object.keys(sentimentByDate).sort();\n  \n  const data = {\n    labels: dates,\n    datasets: [\n      {\n        label: 'Positive',\n        data: dates.map(date => \n          (sentimentByDate[date].positive \u002F sentimentByDate[date].total) * 100\n        ),\n        borderColor: '#4caf50',\n        backgroundColor: 'rgba(76, 175, 80, 0.1)'\n      },\n      {\n        label: 'Negative',\n        data: dates.map(date => \n          (sentimentByDate[date].negative \u002F sentimentByDate[date].total) * 100\n        ),\n        borderColor: '#f44336',\n        backgroundColor: 'rgba(244, 67, 54, 0.1)'\n      },\n      {\n        label: 'Neutral',\n        data: dates.map(date => \n          (sentimentByDate[date].neutral \u002F sentimentByDate[date].total) * 100\n        ),\n        borderColor: '#9e9e9e',\n        backgroundColor: 'rgba(158, 158, 158, 0.1)'\n      }\n    ]\n  };\n  \n  const options = {\n    responsive: true,\n    plugins: {\n      title: {\n        display: true,\n        text: 'Sentiment Trends Over Time (AllNewsAPI Data)'\n      }\n    },\n    scales: {\n      y: {\n        beginAtZero: true,\n        max: 100,\n        ticks: {\n          callback: value => value + '%'\n        }\n      }\n    }\n  };\n  \n  return \u003CLine data={data} options={options} \u002F>;\n}\n",[205,12705,12706,12711,12715,12720,12725,12730,12735,12739,12744,12749,12753,12757,12762,12767,12772,12776,12781,12786,12790,12795,12799,12804,12809,12814,12819,12824,12829,12834,12839,12844,12849,12854,12858,12863,12867,12872,12876,12881,12886,12890,12894,12899,12903,12908,12912,12917,12922,12926,12931,12935,12939,12944,12949,12954,12959,12964,12969,12973,12978,12983,12988,12993,12998,13003,13008,13013,13017,13021,13025,13029,13034],{"__ignoreMap":203},[208,12707,12708],{"class":210,"line":211},[208,12709,12710],{},"import { Line } from 'react-chartjs-2';\n",[208,12712,12713],{"class":210,"line":218},[208,12714,1092],{"emptyLinePlaceholder":866},[208,12716,12717],{"class":210,"line":228},[208,12718,12719],{},"function SentimentTrendChart({ articles }) {\n",[208,12721,12722],{"class":210,"line":236},[208,12723,12724],{},"  \u002F\u002F Group articles by date using built-in sentiment\n",[208,12726,12727],{"class":210,"line":252},[208,12728,12729],{},"  const sentimentByDate = articles.reduce((acc, article) => {\n",[208,12731,12732],{"class":210,"line":261},[208,12733,12734],{},"    const date = new Date(article.publishedAt).toLocaleDateString();\n",[208,12736,12737],{"class":210,"line":269},[208,12738,3543],{},[208,12740,12741],{"class":210,"line":277},[208,12742,12743],{},"    if (!acc[date]) {\n",[208,12745,12746],{"class":210,"line":283},[208,12747,12748],{},"      acc[date] = { positive: 0, negative: 0, neutral: 0, total: 0 };\n",[208,12750,12751],{"class":210,"line":289},[208,12752,292],{},[208,12754,12755],{"class":210,"line":295},[208,12756,3543],{},[208,12758,12759],{"class":210,"line":301},[208,12760,12761],{},"    \u002F\u002F Use the built-in sentiment classification\n",[208,12763,12764],{"class":210,"line":1078},[208,12765,12766],{},"    acc[date][article.sentiment]++;\n",[208,12768,12769],{"class":210,"line":1084},[208,12770,12771],{},"    acc[date].total++;\n",[208,12773,12774],{"class":210,"line":1089},[208,12775,3543],{},[208,12777,12778],{"class":210,"line":1095},[208,12779,12780],{},"    return acc;\n",[208,12782,12783],{"class":210,"line":1481},[208,12784,12785],{},"  }, {});\n",[208,12787,12788],{"class":210,"line":1501},[208,12789,1042],{},[208,12791,12792],{"class":210,"line":1521},[208,12793,12794],{},"  const dates = Object.keys(sentimentByDate).sort();\n",[208,12796,12797],{"class":210,"line":1541},[208,12798,1042],{},[208,12800,12801],{"class":210,"line":1561},[208,12802,12803],{},"  const data = {\n",[208,12805,12806],{"class":210,"line":1581},[208,12807,12808],{},"    labels: dates,\n",[208,12810,12811],{"class":210,"line":1601},[208,12812,12813],{},"    datasets: [\n",[208,12815,12816],{"class":210,"line":1621},[208,12817,12818],{},"      {\n",[208,12820,12821],{"class":210,"line":1641},[208,12822,12823],{},"        label: 'Positive',\n",[208,12825,12826],{"class":210,"line":1661},[208,12827,12828],{},"        data: dates.map(date => \n",[208,12830,12831],{"class":210,"line":1682},[208,12832,12833],{},"          (sentimentByDate[date].positive \u002F sentimentByDate[date].total) * 100\n",[208,12835,12836],{"class":210,"line":1688},[208,12837,12838],{},"        ),\n",[208,12840,12841],{"class":210,"line":1693},[208,12842,12843],{},"        borderColor: '#4caf50',\n",[208,12845,12846],{"class":210,"line":1718},[208,12847,12848],{},"        backgroundColor: 'rgba(76, 175, 80, 0.1)'\n",[208,12850,12851],{"class":210,"line":1736},[208,12852,12853],{},"      },\n",[208,12855,12856],{"class":210,"line":1745},[208,12857,12818],{},[208,12859,12860],{"class":210,"line":1751},[208,12861,12862],{},"        label: 'Negative',\n",[208,12864,12865],{"class":210,"line":1756},[208,12866,12828],{},[208,12868,12869],{"class":210,"line":1765},[208,12870,12871],{},"          (sentimentByDate[date].negative \u002F sentimentByDate[date].total) * 100\n",[208,12873,12874],{"class":210,"line":1787},[208,12875,12838],{},[208,12877,12878],{"class":210,"line":1799},[208,12879,12880],{},"        borderColor: '#f44336',\n",[208,12882,12883],{"class":210,"line":1810},[208,12884,12885],{},"        backgroundColor: 'rgba(244, 67, 54, 0.1)'\n",[208,12887,12888],{"class":210,"line":1833},[208,12889,12853],{},[208,12891,12892],{"class":210,"line":1839},[208,12893,12818],{},[208,12895,12896],{"class":210,"line":1858},[208,12897,12898],{},"        label: 'Neutral',\n",[208,12900,12901],{"class":210,"line":1883},[208,12902,12828],{},[208,12904,12905],{"class":210,"line":1889},[208,12906,12907],{},"          (sentimentByDate[date].neutral \u002F sentimentByDate[date].total) * 100\n",[208,12909,12910],{"class":210,"line":1899},[208,12911,12838],{},[208,12913,12914],{"class":210,"line":1905},[208,12915,12916],{},"        borderColor: '#9e9e9e',\n",[208,12918,12919],{"class":210,"line":1915},[208,12920,12921],{},"        backgroundColor: 'rgba(158, 158, 158, 0.1)'\n",[208,12923,12924],{"class":210,"line":1925},[208,12925,7600],{},[208,12927,12928],{"class":210,"line":1930},[208,12929,12930],{},"    ]\n",[208,12932,12933],{"class":210,"line":1935},[208,12934,1748],{},[208,12936,12937],{"class":210,"line":1940},[208,12938,1042],{},[208,12940,12941],{"class":210,"line":2230},[208,12942,12943],{},"  const options = {\n",[208,12945,12946],{"class":210,"line":2236},[208,12947,12948],{},"    responsive: true,\n",[208,12950,12951],{"class":210,"line":2242},[208,12952,12953],{},"    plugins: {\n",[208,12955,12956],{"class":210,"line":2247},[208,12957,12958],{},"      title: {\n",[208,12960,12961],{"class":210,"line":2253},[208,12962,12963],{},"        display: true,\n",[208,12965,12966],{"class":210,"line":2258},[208,12967,12968],{},"        text: 'Sentiment Trends Over Time (AllNewsAPI Data)'\n",[208,12970,12971],{"class":210,"line":3213},[208,12972,7600],{},[208,12974,12975],{"class":210,"line":3219},[208,12976,12977],{},"    },\n",[208,12979,12980],{"class":210,"line":5034},[208,12981,12982],{},"    scales: {\n",[208,12984,12985],{"class":210,"line":5713},[208,12986,12987],{},"      y: {\n",[208,12989,12990],{"class":210,"line":5729},[208,12991,12992],{},"        beginAtZero: true,\n",[208,12994,12995],{"class":210,"line":5737},[208,12996,12997],{},"        max: 100,\n",[208,12999,13000],{"class":210,"line":5748},[208,13001,13002],{},"        ticks: {\n",[208,13004,13005],{"class":210,"line":5759},[208,13006,13007],{},"          callback: value => value + '%'\n",[208,13009,13010],{"class":210,"line":5770},[208,13011,13012],{},"        }\n",[208,13014,13015],{"class":210,"line":5781},[208,13016,7600],{},[208,13018,13019],{"class":210,"line":5786},[208,13020,292],{},[208,13022,13023],{"class":210,"line":5791},[208,13024,1748],{},[208,13026,13027],{"class":210,"line":5817},[208,13028,1042],{},[208,13030,13031],{"class":210,"line":5825},[208,13032,13033],{},"  return \u003CLine data={data} options={options} \u002F>;\n",[208,13035,13036],{"class":210,"line":5836},[208,13037,304],{},[21,13039,13041],{"id":13040},"step-7-advanced-features","Step 7: Advanced Features",[94,13043,13045],{"id":13044},"topic-based-sentiment","Topic-Based Sentiment",[12,13047,13048],{},"Analyze sentiment for specific topics:",[198,13050,13052],{"className":1013,"code":13051,"language":1015,"meta":203,"style":203},"function analyzeTopicSentiment(articles, topic) {\n  const relevantArticles = articles.filter(article => {\n    const text = `${article.title} ${article.description}`.toLowerCase();\n    return text.includes(topic.toLowerCase());\n  });\n  \n  const sentiments = relevantArticles.map(a => a.sentiment.score);\n  const averageSentiment = sentiments.reduce((a, b) => a + b, 0) \u002F sentiments.length;\n  \n  return {\n    topic,\n    articleCount: relevantArticles.length,\n    averageSentiment,\n    classification: classifySentiment(averageSentiment)\n  };\n}\n\n\u002F\u002F Usage\nconst topics = ['economy', 'technology', 'politics', 'health'];\nconst topicSentiments = topics.map(topic => \n  analyzeTopicSentiment(articles, topic)\n);\n",[205,13053,13054,13059,13064,13069,13074,13078,13082,13087,13092,13096,13101,13106,13111,13116,13121,13125,13129,13133,13137,13142,13147,13152],{"__ignoreMap":203},[208,13055,13056],{"class":210,"line":211},[208,13057,13058],{},"function analyzeTopicSentiment(articles, topic) {\n",[208,13060,13061],{"class":210,"line":218},[208,13062,13063],{},"  const relevantArticles = articles.filter(article => {\n",[208,13065,13066],{"class":210,"line":228},[208,13067,13068],{},"    const text = `${article.title} ${article.description}`.toLowerCase();\n",[208,13070,13071],{"class":210,"line":236},[208,13072,13073],{},"    return text.includes(topic.toLowerCase());\n",[208,13075,13076],{"class":210,"line":252},[208,13077,2250],{},[208,13079,13080],{"class":210,"line":261},[208,13081,1042],{},[208,13083,13084],{"class":210,"line":269},[208,13085,13086],{},"  const sentiments = relevantArticles.map(a => a.sentiment.score);\n",[208,13088,13089],{"class":210,"line":277},[208,13090,13091],{},"  const averageSentiment = sentiments.reduce((a, b) => a + b, 0) \u002F sentiments.length;\n",[208,13093,13094],{"class":210,"line":283},[208,13095,1042],{},[208,13097,13098],{"class":210,"line":289},[208,13099,13100],{},"  return {\n",[208,13102,13103],{"class":210,"line":295},[208,13104,13105],{},"    topic,\n",[208,13107,13108],{"class":210,"line":301},[208,13109,13110],{},"    articleCount: relevantArticles.length,\n",[208,13112,13113],{"class":210,"line":1078},[208,13114,13115],{},"    averageSentiment,\n",[208,13117,13118],{"class":210,"line":1084},[208,13119,13120],{},"    classification: classifySentiment(averageSentiment)\n",[208,13122,13123],{"class":210,"line":1089},[208,13124,1748],{},[208,13126,13127],{"class":210,"line":1095},[208,13128,304],{},[208,13130,13131],{"class":210,"line":1481},[208,13132,1092],{"emptyLinePlaceholder":866},[208,13134,13135],{"class":210,"line":1501},[208,13136,2912],{},[208,13138,13139],{"class":210,"line":1521},[208,13140,13141],{},"const topics = ['economy', 'technology', 'politics', 'health'];\n",[208,13143,13144],{"class":210,"line":1541},[208,13145,13146],{},"const topicSentiments = topics.map(topic => \n",[208,13148,13149],{"class":210,"line":1561},[208,13150,13151],{},"  analyzeTopicSentiment(articles, topic)\n",[208,13153,13154],{"class":210,"line":1581},[208,13155,2377],{},[21,13157,13041],{"id":13158},"step-7-advanced-features-1",[94,13160,13162],{"id":13161},"topic-based-sentiment-analysis","Topic-Based Sentiment Analysis",[12,13164,13165],{},"Analyze sentiment for specific topics using AllNewsAPI's search:",[198,13167,13169],{"className":1013,"code":13168,"language":1015,"meta":203,"style":203},"async function analyzeTopicSentiment(topic, apiKey) {\n  const response = await fetch(\n    `https:\u002F\u002Fapi.allnewsapi.com\u002Fsearch?apikey=${apiKey}&q=${encodeURIComponent(topic)}`\n  );\n  \n  const data = await response.json();\n  const articles = data.articles;\n  \n  \u002F\u002F Calculate sentiment distribution\n  const stats = {\n    topic,\n    total: articles.length,\n    positive: 0,\n    negative: 0,\n    neutral: 0,\n    avgPositiveScore: 0,\n    avgNegativeScore: 0\n  };\n  \n  let totalPos = 0, totalNeg = 0;\n  \n  articles.forEach(article => {\n    stats[article.sentiment]++;\n    totalPos += article.sentimentScores.positive;\n    totalNeg += article.sentimentScores.negative;\n  });\n  \n  stats.avgPositiveScore = totalPos \u002F articles.length;\n  stats.avgNegativeScore = totalNeg \u002F articles.length;\n  \n  return stats;\n}\n\n\u002F\u002F Usage\nconst topics = ['economy', 'technology', 'climate change', 'healthcare'];\nconst topicSentiments = await Promise.all(\n  topics.map(topic => analyzeTopicSentiment(topic, API_KEY))\n);\n\ntopicSentiments.forEach(stat => {\n  console.log(`${stat.topic}: ${stat.positive} positive, ${stat.negative} negative`);\n});\n",[205,13170,13171,13176,13180,13185,13189,13193,13197,13202,13206,13211,13216,13220,13225,13230,13235,13240,13245,13250,13254,13258,13263,13267,13272,13277,13282,13287,13291,13295,13300,13305,13309,13314,13318,13322,13326,13331,13336,13341,13345,13349,13354,13359],{"__ignoreMap":203},[208,13172,13173],{"class":210,"line":211},[208,13174,13175],{},"async function analyzeTopicSentiment(topic, apiKey) {\n",[208,13177,13178],{"class":210,"line":218},[208,13179,1120],{},[208,13181,13182],{"class":210,"line":228},[208,13183,13184],{},"    `https:\u002F\u002Fapi.allnewsapi.com\u002Fsearch?apikey=${apiKey}&q=${encodeURIComponent(topic)}`\n",[208,13186,13187],{"class":210,"line":236},[208,13188,1130],{},[208,13190,13191],{"class":210,"line":252},[208,13192,1042],{},[208,13194,13195],{"class":210,"line":261},[208,13196,10130],{},[208,13198,13199],{"class":210,"line":269},[208,13200,13201],{},"  const articles = data.articles;\n",[208,13203,13204],{"class":210,"line":277},[208,13205,1042],{},[208,13207,13208],{"class":210,"line":283},[208,13209,13210],{},"  \u002F\u002F Calculate sentiment distribution\n",[208,13212,13213],{"class":210,"line":289},[208,13214,13215],{},"  const stats = {\n",[208,13217,13218],{"class":210,"line":295},[208,13219,13105],{},[208,13221,13222],{"class":210,"line":301},[208,13223,13224],{},"    total: articles.length,\n",[208,13226,13227],{"class":210,"line":1078},[208,13228,13229],{},"    positive: 0,\n",[208,13231,13232],{"class":210,"line":1084},[208,13233,13234],{},"    negative: 0,\n",[208,13236,13237],{"class":210,"line":1089},[208,13238,13239],{},"    neutral: 0,\n",[208,13241,13242],{"class":210,"line":1095},[208,13243,13244],{},"    avgPositiveScore: 0,\n",[208,13246,13247],{"class":210,"line":1481},[208,13248,13249],{},"    avgNegativeScore: 0\n",[208,13251,13252],{"class":210,"line":1501},[208,13253,1748],{},[208,13255,13256],{"class":210,"line":1521},[208,13257,1042],{},[208,13259,13260],{"class":210,"line":1541},[208,13261,13262],{},"  let totalPos = 0, totalNeg = 0;\n",[208,13264,13265],{"class":210,"line":1561},[208,13266,1042],{},[208,13268,13269],{"class":210,"line":1581},[208,13270,13271],{},"  articles.forEach(article => {\n",[208,13273,13274],{"class":210,"line":1601},[208,13275,13276],{},"    stats[article.sentiment]++;\n",[208,13278,13279],{"class":210,"line":1621},[208,13280,13281],{},"    totalPos += article.sentimentScores.positive;\n",[208,13283,13284],{"class":210,"line":1641},[208,13285,13286],{},"    totalNeg += article.sentimentScores.negative;\n",[208,13288,13289],{"class":210,"line":1661},[208,13290,2250],{},[208,13292,13293],{"class":210,"line":1682},[208,13294,1042],{},[208,13296,13297],{"class":210,"line":1688},[208,13298,13299],{},"  stats.avgPositiveScore = totalPos \u002F articles.length;\n",[208,13301,13302],{"class":210,"line":1693},[208,13303,13304],{},"  stats.avgNegativeScore = totalNeg \u002F articles.length;\n",[208,13306,13307],{"class":210,"line":1718},[208,13308,1042],{},[208,13310,13311],{"class":210,"line":1736},[208,13312,13313],{},"  return stats;\n",[208,13315,13316],{"class":210,"line":1745},[208,13317,304],{},[208,13319,13320],{"class":210,"line":1751},[208,13321,1092],{"emptyLinePlaceholder":866},[208,13323,13324],{"class":210,"line":1756},[208,13325,2912],{},[208,13327,13328],{"class":210,"line":1765},[208,13329,13330],{},"const topics = ['economy', 'technology', 'climate change', 'healthcare'];\n",[208,13332,13333],{"class":210,"line":1787},[208,13334,13335],{},"const topicSentiments = await Promise.all(\n",[208,13337,13338],{"class":210,"line":1799},[208,13339,13340],{},"  topics.map(topic => analyzeTopicSentiment(topic, API_KEY))\n",[208,13342,13343],{"class":210,"line":1810},[208,13344,2377],{},[208,13346,13347],{"class":210,"line":1833},[208,13348,1092],{"emptyLinePlaceholder":866},[208,13350,13351],{"class":210,"line":1839},[208,13352,13353],{},"topicSentiments.forEach(stat => {\n",[208,13355,13356],{"class":210,"line":1858},[208,13357,13358],{},"  console.log(`${stat.topic}: ${stat.positive} positive, ${stat.negative} negative`);\n",[208,13360,13361],{"class":210,"line":1883},[208,13362,3868],{},[94,13364,13366],{"id":13365},"sentiment-alerts","Sentiment Alerts",[12,13368,13369],{},"Monitor sentiment shifts over time:",[198,13371,13373],{"className":1013,"code":13372,"language":1015,"meta":203,"style":203},"class SentimentAlertSystem {\n  constructor(threshold = 0.2) {\n    this.threshold = threshold;\n    this.baseline = null;\n  }\n  \n  setBaseline(articles) {\n    const positiveCount = articles.filter(a => a.sentiment === 'positive').length;\n    this.baseline = positiveCount \u002F articles.length;\n  }\n  \n  checkForAlerts(articles) {\n    const positiveCount = articles.filter(a => a.sentiment === 'positive').length;\n    const currentRatio = positiveCount \u002F articles.length;\n    \n    if (!this.baseline) {\n      this.setBaseline(articles);\n      return null;\n    }\n    \n    const change = currentRatio - this.baseline;\n    \n    if (Math.abs(change) > this.threshold) {\n      return {\n        type: change > 0 ? 'positive_shift' : 'negative_shift',\n        magnitude: Math.abs(change),\n        message: `Sentiment has shifted ${change > 0 ? 'more positive' : 'more negative'} by ${(Math.abs(change) * 100).toFixed(1)}%`\n      };\n    }\n    \n    return null;\n  }\n}\n\n\u002F\u002F Usage\nconst alertSystem = new SentimentAlertSystem();\nconst alert = alertSystem.checkForAlerts(articles);\nif (alert) {\n  console.log('Alert:', alert.message);\n}\n",[205,13374,13375,13380,13385,13390,13395,13399,13403,13408,13413,13418,13422,13426,13431,13435,13440,13444,13449,13454,13459,13463,13467,13472,13476,13481,13486,13491,13496,13501,13506,13510,13514,13518,13522,13526,13530,13534,13539,13544,13549,13554],{"__ignoreMap":203},[208,13376,13377],{"class":210,"line":211},[208,13378,13379],{},"class SentimentAlertSystem {\n",[208,13381,13382],{"class":210,"line":218},[208,13383,13384],{},"  constructor(threshold = 0.2) {\n",[208,13386,13387],{"class":210,"line":228},[208,13388,13389],{},"    this.threshold = threshold;\n",[208,13391,13392],{"class":210,"line":236},[208,13393,13394],{},"    this.baseline = null;\n",[208,13396,13397],{"class":210,"line":252},[208,13398,298],{},[208,13400,13401],{"class":210,"line":261},[208,13402,1042],{},[208,13404,13405],{"class":210,"line":269},[208,13406,13407],{},"  setBaseline(articles) {\n",[208,13409,13410],{"class":210,"line":277},[208,13411,13412],{},"    const positiveCount = articles.filter(a => a.sentiment === 'positive').length;\n",[208,13414,13415],{"class":210,"line":283},[208,13416,13417],{},"    this.baseline = positiveCount \u002F articles.length;\n",[208,13419,13420],{"class":210,"line":289},[208,13421,298],{},[208,13423,13424],{"class":210,"line":295},[208,13425,1042],{},[208,13427,13428],{"class":210,"line":301},[208,13429,13430],{},"  checkForAlerts(articles) {\n",[208,13432,13433],{"class":210,"line":1078},[208,13434,13412],{},[208,13436,13437],{"class":210,"line":1084},[208,13438,13439],{},"    const currentRatio = positiveCount \u002F articles.length;\n",[208,13441,13442],{"class":210,"line":1089},[208,13443,3543],{},[208,13445,13446],{"class":210,"line":1095},[208,13447,13448],{},"    if (!this.baseline) {\n",[208,13450,13451],{"class":210,"line":1481},[208,13452,13453],{},"      this.setBaseline(articles);\n",[208,13455,13456],{"class":210,"line":1501},[208,13457,13458],{},"      return null;\n",[208,13460,13461],{"class":210,"line":1521},[208,13462,292],{},[208,13464,13465],{"class":210,"line":1541},[208,13466,3543],{},[208,13468,13469],{"class":210,"line":1561},[208,13470,13471],{},"    const change = currentRatio - this.baseline;\n",[208,13473,13474],{"class":210,"line":1581},[208,13475,3543],{},[208,13477,13478],{"class":210,"line":1601},[208,13479,13480],{},"    if (Math.abs(change) > this.threshold) {\n",[208,13482,13483],{"class":210,"line":1621},[208,13484,13485],{},"      return {\n",[208,13487,13488],{"class":210,"line":1641},[208,13489,13490],{},"        type: change > 0 ? 'positive_shift' : 'negative_shift',\n",[208,13492,13493],{"class":210,"line":1661},[208,13494,13495],{},"        magnitude: Math.abs(change),\n",[208,13497,13498],{"class":210,"line":1682},[208,13499,13500],{},"        message: `Sentiment has shifted ${change > 0 ? 'more positive' : 'more negative'} by ${(Math.abs(change) * 100).toFixed(1)}%`\n",[208,13502,13503],{"class":210,"line":1688},[208,13504,13505],{},"      };\n",[208,13507,13508],{"class":210,"line":1693},[208,13509,292],{},[208,13511,13512],{"class":210,"line":1718},[208,13513,3543],{},[208,13515,13516],{"class":210,"line":1736},[208,13517,3566],{},[208,13519,13520],{"class":210,"line":1745},[208,13521,298],{},[208,13523,13524],{"class":210,"line":1751},[208,13525,304],{},[208,13527,13528],{"class":210,"line":1756},[208,13529,1092],{"emptyLinePlaceholder":866},[208,13531,13532],{"class":210,"line":1765},[208,13533,2912],{},[208,13535,13536],{"class":210,"line":1787},[208,13537,13538],{},"const alertSystem = new SentimentAlertSystem();\n",[208,13540,13541],{"class":210,"line":1799},[208,13542,13543],{},"const alert = alertSystem.checkForAlerts(articles);\n",[208,13545,13546],{"class":210,"line":1810},[208,13547,13548],{},"if (alert) {\n",[208,13550,13551],{"class":210,"line":1833},[208,13552,13553],{},"  console.log('Alert:', alert.message);\n",[208,13555,13556],{"class":210,"line":1839},[208,13557,304],{},[21,13559,3421],{"id":3420},[693,13561,13562,13568,13574,13580,13586,13592,13598],{},[35,13563,13564,13567],{},[16,13565,13566],{},"Use the built-in data"," - AllNewsAPI's sentiment is already AI-powered and accurate",[35,13569,13570,13573],{},[16,13571,13572],{},"Show confidence scores"," - Display sentimentScores to show certainty",[35,13575,13576,13579],{},[16,13577,13578],{},"Filter intelligently"," - Let users choose their preferred sentiment",[35,13581,13582,13585],{},[16,13583,13584],{},"Track trends"," - Monitor sentiment changes over time",[35,13587,13588,13591],{},[16,13589,13590],{},"Combine with categories"," - Analyze sentiment by topic or category",[35,13593,13594,13597],{},[16,13595,13596],{},"Consider thresholds"," - Use high-confidence articles for critical decisions",[35,13599,13600,13603],{},[16,13601,13602],{},"Provide context"," - Show why an article has a certain sentiment",[21,13605,13607],{"id":13606},"when-to-build-custom-sentiment-analysis","When to Build Custom Sentiment Analysis",[12,13609,13610],{},"While AllNewsAPI provides excellent built-in sentiment analysis, you might want custom analysis for:",[32,13612,13613,13619,13625,13631],{},[35,13614,13615,13618],{},[16,13616,13617],{},"Domain-specific sentiment"," - Industry-specific terminology",[35,13620,13621,13624],{},[16,13622,13623],{},"Multi-aspect analysis"," - Analyzing different aspects of an article separately",[35,13626,13627,13630],{},[16,13628,13629],{},"Custom scoring"," - Your own sentiment scoring methodology",[35,13632,13633,13635],{},[16,13634,3716],{}," - Analyzing user comments or social media reactions",[12,13637,13638],{},"For these cases, you can use libraries like:",[32,13640,13641,13652],{},[35,13642,13643,13644,1226,13646,1226,13649],{},"JavaScript: ",[205,13645,9990],{},[205,13647,13648],{},"natural",[205,13650,13651],{},"compromise",[35,13653,13654,13655,1226,13658,1226,13661],{},"Python: ",[205,13656,13657],{},"textblob",[205,13659,13660],{},"transformers",[205,13662,13663],{},"vader",[21,13665,779],{"id":778},[12,13667,13668],{},"AllNewsAPI's built-in sentiment analysis makes it incredibly easy to add sentiment-aware features to your news applications. No ML setup, no training data, no infrastructure - just instant access to AI-powered sentiment data for every article.",[12,13670,13671,13672,3632],{},"Ready to build sentiment-aware news apps? ",[182,13673,9167],{"href":184},[21,13675,719],{"id":718},[32,13677,13678,13682,13689],{},[35,13679,13680],{},[182,13681,3641],{"href":741},[35,13683,13684],{},[182,13685,13688],{"href":13686,"rel":13687},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSentiment_analysis",[732],"Understanding Sentiment Scores",[35,13690,13691],{},[182,13692,13693],{"href":6697},"Building News Dashboards Tutorial",[825,13695,13696],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":203,"searchDepth":218,"depth":218,"links":13698},[13699,13700,13701,13702,13703,13704,13705,13706,13707,13710,13714,13715,13716,13717],{"id":9958,"depth":218,"text":9959},{"id":9979,"depth":218,"text":9980},{"id":10085,"depth":218,"text":10086},{"id":10197,"depth":218,"text":10198},{"id":10284,"depth":218,"text":10285},{"id":10367,"depth":218,"text":10368},{"id":10713,"depth":218,"text":10714},{"id":12696,"depth":218,"text":12697},{"id":13040,"depth":218,"text":13041,"children":13708},[13709],{"id":13044,"depth":228,"text":13045},{"id":13158,"depth":218,"text":13041,"children":13711},[13712,13713],{"id":13161,"depth":228,"text":13162},{"id":13365,"depth":228,"text":13366},{"id":3420,"depth":218,"text":3421},{"id":13606,"depth":218,"text":13607},{"id":778,"depth":218,"text":779},{"id":718,"depth":218,"text":719},"2024-10-05","Learn how to leverage AllNewsAPI's built-in AI-powered sentiment analysis to understand the emotional tone of news articles","\u002Fblog\u002Fadding-sentiment-analysis-to-your-news-app.webp",{},"\u002Fblog\u002Fnews-sentiment-analysis",{"title":9950,"description":13719},{"loc":13722},"blog\u002Fnews-sentiment-analysis","machine-learning, tutorial","4FdI-5HdgrETuz18pzwbKqXTNsEoBoQYe7cTfaM9Qoo",{"id":13729,"title":9904,"author":7,"body":13730,"date":14301,"description":14302,"draft":862,"extension":863,"image":14303,"meta":14304,"navigation":866,"path":9903,"seo":14305,"sitemap":14306,"stem":14307,"tags":14308,"__hash__":14309},"blog\u002Fblog\u002Fgetting-started-with-allnewsapi.md",{"type":9,"value":13731,"toc":14285},[13732,13735,13739,13742,13746,13750,13753,13771,13775,13778,13828,13832,13835,14111,14113,14117,14120,14149,14153,14156,14185,14189,14192,14207,14209,14235,14237,14240,14258,14262,14265,14279,14282],[12,13733,13734],{},"Welcome to AllNewsAPI! This guide will help you get started with our news aggregation API in just a few minutes.",[21,13736,13738],{"id":13737},"what-is-allnewsapi","What is AllNewsAPI?",[12,13740,13741],{},"AllNewsAPI is a powerful news aggregation platform that provides programmatic access to news articles from 244 countries worldwide. Whether you're building a news app, conducting research, or monitoring media coverage, AllNewsAPI makes it easy to access the news data you need.",[21,13743,13745],{"id":13744},"quick-start","Quick Start",[94,13747,13749],{"id":13748},"_1-sign-up-for-an-api-key","1. Sign Up for an API Key",[12,13751,13752],{},"First, you'll need to create an account and get your API key:",[693,13754,13755,13762,13765,13768],{},[35,13756,6635,13757],{},[182,13758,13761],{"href":13759,"rel":13760},"https:\u002F\u002Fallnewsapi.com\u002Fsignup",[732],"allnewsapi.com\u002Fsignup",[35,13763,13764],{},"Create your free account",[35,13766,13767],{},"Verify your email address",[35,13769,13770],{},"Get your API key from the dashboard",[94,13772,13774],{"id":13773},"_2-make-your-first-request","2. Make Your First Request",[12,13776,13777],{},"Once you have your API key, you can start making requests. Here's a simple example using JavaScript:",[198,13779,13781],{"className":1013,"code":13780,"language":1015,"meta":203,"style":203},"const API_KEY = 'your_api_key_here';\nconst API_URL = 'https:\u002F\u002Fapi.allnewsapi.com\u002Fv1\u002Fheadlines';\n\nasync function getHeadlines() {\n  const response = await fetch(`${API_URL}?apikey=${API_KEY}&country=us`);\n  const data = await response.json();\n  console.log(data);\n}\n\ngetHeadlines();\n",[205,13782,13783,13787,13792,13796,13801,13806,13810,13815,13819,13823],{"__ignoreMap":203},[208,13784,13785],{"class":210,"line":211},[208,13786,10099],{},[208,13788,13789],{"class":210,"line":218},[208,13790,13791],{},"const API_URL = 'https:\u002F\u002Fapi.allnewsapi.com\u002Fv1\u002Fheadlines';\n",[208,13793,13794],{"class":210,"line":228},[208,13795,1092],{"emptyLinePlaceholder":866},[208,13797,13798],{"class":210,"line":236},[208,13799,13800],{},"async function getHeadlines() {\n",[208,13802,13803],{"class":210,"line":252},[208,13804,13805],{},"  const response = await fetch(`${API_URL}?apikey=${API_KEY}&country=us`);\n",[208,13807,13808],{"class":210,"line":261},[208,13809,10130],{},[208,13811,13812],{"class":210,"line":269},[208,13813,13814],{},"  console.log(data);\n",[208,13816,13817],{"class":210,"line":277},[208,13818,304],{},[208,13820,13821],{"class":210,"line":283},[208,13822,1092],{"emptyLinePlaceholder":866},[208,13824,13825],{"class":210,"line":289},[208,13826,13827],{},"getHeadlines();\n",[94,13829,13831],{"id":13830},"_3-explore-the-response","3. Explore the Response",[12,13833,13834],{},"The API returns a JSON response with the following structure:",[198,13836,13838],{"className":200,"code":13837,"language":202,"meta":203,"style":203},"{\n  \"totalArticles\": 7199232,\n  \"currentPage\": 1,\n  \"articles\": [\n    {\n      \"title\": \"Breaking News Title\",\n      \"description\": \"Article description...\",\n      \"category\": \"technology\",\n      \"content\": \"Full article content...\",\n      \"country\": \"us\",\n      \"region\": \"americas\",\n      \"lang\": \"en\",\n      \"sentiment\": \"neutral\",\n      \"sentimentScores\": {\n        \"negative\": 0.03,\n        \"neutral\": 0.95,\n        \"positive\": 0.02\n      },\n      \"url\": \"https:\u002F\u002Fexample.com\u002Farticle\",\n      \"image\": \"https:\u002F\u002Fexample.com\u002Fimage.jpg\",\n      \"publishedAt\": \"2024-12-01T10:00:00Z\",\n      \"source\": {\n        \"name\": \"News Source\",\n        \"url\": \"https:\u002F\u002Fexample.com\"\n      }\n    }\n  ],\n  \"nextPage\": 2\n}\n",[205,13839,13840,13844,13856,13867,13874,13879,13891,13903,13915,13927,13939,13951,13962,13974,13981,13993,14005,14015,14019,14031,14043,14055,14062,14074,14084,14088,14092,14097,14107],{"__ignoreMap":203},[208,13841,13842],{"class":210,"line":211},[208,13843,215],{"class":214},[208,13845,13846,13849,13851,13854],{"class":210,"line":218},[208,13847,13848],{"class":221},"  \"totalArticles\"",[208,13850,242],{"class":214},[208,13852,13853],{"class":221},"7199232",[208,13855,249],{"class":214},[208,13857,13858,13861,13863,13865],{"class":210,"line":228},[208,13859,13860],{"class":221},"  \"currentPage\"",[208,13862,242],{"class":214},[208,13864,4980],{"class":221},[208,13866,249],{"class":214},[208,13868,13869,13872],{"class":210,"line":236},[208,13870,13871],{"class":221},"  \"articles\"",[208,13873,258],{"class":214},[208,13875,13876],{"class":210,"line":252},[208,13877,13878],{"class":214},"    {\n",[208,13880,13881,13884,13886,13889],{"class":210,"line":261},[208,13882,13883],{"class":221},"      \"title\"",[208,13885,242],{"class":214},[208,13887,13888],{"class":245},"\"Breaking News Title\"",[208,13890,249],{"class":214},[208,13892,13893,13896,13898,13901],{"class":210,"line":269},[208,13894,13895],{"class":221},"      \"description\"",[208,13897,242],{"class":214},[208,13899,13900],{"class":245},"\"Article description...\"",[208,13902,249],{"class":214},[208,13904,13905,13908,13910,13913],{"class":210,"line":277},[208,13906,13907],{"class":221},"      \"category\"",[208,13909,242],{"class":214},[208,13911,13912],{"class":245},"\"technology\"",[208,13914,249],{"class":214},[208,13916,13917,13920,13922,13925],{"class":210,"line":283},[208,13918,13919],{"class":221},"      \"content\"",[208,13921,242],{"class":214},[208,13923,13924],{"class":245},"\"Full article content...\"",[208,13926,249],{"class":214},[208,13928,13929,13932,13934,13937],{"class":210,"line":289},[208,13930,13931],{"class":221},"      \"country\"",[208,13933,242],{"class":214},[208,13935,13936],{"class":245},"\"us\"",[208,13938,249],{"class":214},[208,13940,13941,13944,13946,13949],{"class":210,"line":295},[208,13942,13943],{"class":221},"      \"region\"",[208,13945,242],{"class":214},[208,13947,13948],{"class":245},"\"americas\"",[208,13950,249],{"class":214},[208,13952,13953,13956,13958,13960],{"class":210,"line":301},[208,13954,13955],{"class":221},"      \"lang\"",[208,13957,242],{"class":214},[208,13959,3309],{"class":245},[208,13961,249],{"class":214},[208,13963,13964,13967,13969,13972],{"class":210,"line":1078},[208,13965,13966],{"class":221},"      \"sentiment\"",[208,13968,242],{"class":214},[208,13970,13971],{"class":245},"\"neutral\"",[208,13973,249],{"class":214},[208,13975,13976,13979],{"class":210,"line":1084},[208,13977,13978],{"class":221},"      \"sentimentScores\"",[208,13980,225],{"class":214},[208,13982,13983,13986,13988,13991],{"class":210,"line":1089},[208,13984,13985],{"class":221},"        \"negative\"",[208,13987,242],{"class":214},[208,13989,13990],{"class":221},"0.03",[208,13992,249],{"class":214},[208,13994,13995,13998,14000,14003],{"class":210,"line":1095},[208,13996,13997],{"class":221},"        \"neutral\"",[208,13999,242],{"class":214},[208,14001,14002],{"class":221},"0.95",[208,14004,249],{"class":214},[208,14006,14007,14010,14012],{"class":210,"line":1481},[208,14008,14009],{"class":221},"        \"positive\"",[208,14011,242],{"class":214},[208,14013,14014],{"class":221},"0.02\n",[208,14016,14017],{"class":210,"line":1501},[208,14018,12853],{"class":214},[208,14020,14021,14024,14026,14029],{"class":210,"line":1521},[208,14022,14023],{"class":221},"      \"url\"",[208,14025,242],{"class":214},[208,14027,14028],{"class":245},"\"https:\u002F\u002Fexample.com\u002Farticle\"",[208,14030,249],{"class":214},[208,14032,14033,14036,14038,14041],{"class":210,"line":1541},[208,14034,14035],{"class":221},"      \"image\"",[208,14037,242],{"class":214},[208,14039,14040],{"class":245},"\"https:\u002F\u002Fexample.com\u002Fimage.jpg\"",[208,14042,249],{"class":214},[208,14044,14045,14048,14050,14053],{"class":210,"line":1561},[208,14046,14047],{"class":221},"      \"publishedAt\"",[208,14049,242],{"class":214},[208,14051,14052],{"class":245},"\"2024-12-01T10:00:00Z\"",[208,14054,249],{"class":214},[208,14056,14057,14060],{"class":210,"line":1581},[208,14058,14059],{"class":221},"      \"source\"",[208,14061,225],{"class":214},[208,14063,14064,14067,14069,14072],{"class":210,"line":1601},[208,14065,14066],{"class":221},"        \"name\"",[208,14068,242],{"class":214},[208,14070,14071],{"class":245},"\"News Source\"",[208,14073,249],{"class":214},[208,14075,14076,14079,14081],{"class":210,"line":1621},[208,14077,14078],{"class":221},"        \"url\"",[208,14080,242],{"class":214},[208,14082,14083],{"class":245},"\"https:\u002F\u002Fexample.com\"\n",[208,14085,14086],{"class":210,"line":1641},[208,14087,7600],{"class":214},[208,14089,14090],{"class":210,"line":1661},[208,14091,292],{"class":214},[208,14093,14094],{"class":210,"line":1682},[208,14095,14096],{"class":214},"  ],\n",[208,14098,14099,14102,14104],{"class":210,"line":1688},[208,14100,14101],{"class":221},"  \"nextPage\"",[208,14103,242],{"class":214},[208,14105,14106],{"class":221},"2\n",[208,14108,14109],{"class":210,"line":1693},[208,14110,304],{"class":214},[21,14112,92],{"id":91},[94,14114,14116],{"id":14115},"multi-country-support","Multi-Country Support",[12,14118,14119],{},"Access news from 244 countries:",[198,14121,14123],{"className":1013,"code":14122,"language":1015,"meta":203,"style":203},"\u002F\u002F Get news from France\nfetch(`${API_URL}?apikey=${API_KEY}&country=fr`)\n\n\u002F\u002F Get news from Japan\nfetch(`${API_URL}?apikey=${API_KEY}&country=jp`)\n",[205,14124,14125,14130,14135,14139,14144],{"__ignoreMap":203},[208,14126,14127],{"class":210,"line":211},[208,14128,14129],{},"\u002F\u002F Get news from France\n",[208,14131,14132],{"class":210,"line":218},[208,14133,14134],{},"fetch(`${API_URL}?apikey=${API_KEY}&country=fr`)\n",[208,14136,14137],{"class":210,"line":228},[208,14138,1092],{"emptyLinePlaceholder":866},[208,14140,14141],{"class":210,"line":236},[208,14142,14143],{},"\u002F\u002F Get news from Japan\n",[208,14145,14146],{"class":210,"line":252},[208,14147,14148],{},"fetch(`${API_URL}?apikey=${API_KEY}&country=jp`)\n",[94,14150,14152],{"id":14151},"category-filtering","Category Filtering",[12,14154,14155],{},"Filter news by category:",[198,14157,14159],{"className":1013,"code":14158,"language":1015,"meta":203,"style":203},"\u002F\u002F Get technology news\nfetch(`${API_URL}?apikey=${API_KEY}&category=technology`)\n\n\u002F\u002F Get sports news\nfetch(`${API_URL}?apikey=${API_KEY}&category=sports`)\n",[205,14160,14161,14166,14171,14175,14180],{"__ignoreMap":203},[208,14162,14163],{"class":210,"line":211},[208,14164,14165],{},"\u002F\u002F Get technology news\n",[208,14167,14168],{"class":210,"line":218},[208,14169,14170],{},"fetch(`${API_URL}?apikey=${API_KEY}&category=technology`)\n",[208,14172,14173],{"class":210,"line":228},[208,14174,1092],{"emptyLinePlaceholder":866},[208,14176,14177],{"class":210,"line":236},[208,14178,14179],{},"\u002F\u002F Get sports news\n",[208,14181,14182],{"class":210,"line":252},[208,14183,14184],{},"fetch(`${API_URL}?apikey=${API_KEY}&category=sports`)\n",[94,14186,14188],{"id":14187},"search-functionality","Search Functionality",[12,14190,14191],{},"Search for specific topics:",[198,14193,14195],{"className":1013,"code":14194,"language":1015,"meta":203,"style":203},"\u002F\u002F Search for articles about AI\nfetch(`${API_URL}?apikey=${API_KEY}&q=artificial+intelligence`)\n",[205,14196,14197,14202],{"__ignoreMap":203},[208,14198,14199],{"class":210,"line":211},[208,14200,14201],{},"\u002F\u002F Search for articles about AI\n",[208,14203,14204],{"class":210,"line":218},[208,14205,14206],{},"fetch(`${API_URL}?apikey=${API_KEY}&q=artificial+intelligence`)\n",[21,14208,3421],{"id":3420},[693,14210,14211,14217,14223,14229],{},[35,14212,14213,14216],{},[16,14214,14215],{},"Cache responses"," - Store API responses to reduce unnecessary requests",[35,14218,14219,14222],{},[16,14220,14221],{},"Handle errors gracefully"," - Always check for error responses",[35,14224,14225,14228],{},[16,14226,14227],{},"Respect rate limits"," - Monitor your usage to stay within your plan limits",[35,14230,14231,14234],{},[16,14232,14233],{},"Use pagination"," - For large result sets, use pagination parameters",[21,14236,6643],{"id":6642},[12,14238,14239],{},"Now that you've made your first request, here are some things to explore:",[32,14241,14242,14248,14255],{},[35,14243,6671,14244,14247],{},[182,14245,14246],{"href":741},"API Documentation"," for detailed endpoint information",[35,14249,14250,14251,14254],{},"Explore different ",[182,14252,14253],{"href":686},"pricing plans"," to find the right fit",[35,14256,14257],{},"Join our community to share tips and get support",[21,14259,14261],{"id":14260},"need-help","Need Help?",[12,14263,14264],{},"If you have questions or need assistance:",[32,14266,14267,14273,14276],{},[35,14268,14269,14270],{},"Visit our ",[182,14271,14272],{"href":741},"documentation",[35,14274,14275],{},"Contact our support team",[35,14277,14278],{},"Check out our other blog posts for tips and tutorials",[12,14280,14281],{},"Happy coding! 🚀",[825,14283,14284],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":203,"searchDepth":218,"depth":218,"links":14286},[14287,14288,14293,14298,14299,14300],{"id":13737,"depth":218,"text":13738},{"id":13744,"depth":218,"text":13745,"children":14289},[14290,14291,14292],{"id":13748,"depth":228,"text":13749},{"id":13773,"depth":228,"text":13774},{"id":13830,"depth":228,"text":13831},{"id":91,"depth":218,"text":92,"children":14294},[14295,14296,14297],{"id":14115,"depth":228,"text":14116},{"id":14151,"depth":228,"text":14152},{"id":14187,"depth":228,"text":14188},{"id":3420,"depth":218,"text":3421},{"id":6642,"depth":218,"text":6643},{"id":14260,"depth":218,"text":14261},"2021-12-01","Learn how to integrate AllNewsAPI into your application in just a few minutes and start accessing news data from around the world","\u002Fblog\u002Fgetting-started-with-allnewsapi.webp",{},{"title":9904,"description":14302},{"loc":9903},"blog\u002Fgetting-started-with-allnewsapi","guide","D0-g-cmTylQrhL_UoknFAMRCI1Ofdm8olt4JyHzencM",1783882207699]