SEO improvments

This commit is contained in:
Yeghro 2025-01-24 22:43:22 -08:00
parent 584adc8086
commit f9e57d7fb0
3 changed files with 182 additions and 37 deletions

View File

@ -3,20 +3,38 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Awesome Nostr Resources</title> <meta name="description" content="A comprehensive collection of Nostr resources, tools, clients, and protocols for developers and users.">
<meta name="keywords" content="nostr, cryptocurrency, decentralized social, protocols, tools, clients, resources">
<meta name="author" content="Your Name">
<meta name="robots" content="index, follow">
<!-- Open Graph / Social Media Meta Tags -->
<meta property="og:title" content="Awesome Nostr Resources">
<meta property="og:description" content="A comprehensive collection of Nostr resources, tools, clients, and protocols for developers and users.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://your-domain.com">
<meta property="og:image" content="https://your-domain.com/path-to-image.jpg">
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Awesome Nostr Resources">
<meta name="twitter:description" content="A comprehensive collection of Nostr resources, tools, clients, and protocols for developers and users.">
<meta name="twitter:image" content="https://your-domain.com/path-to-image.jpg">
<title>Awesome Nostr Resources | Comprehensive Guide to Nostr Protocol</title>
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<!-- Sidebar Navigation --> <!-- Sidebar Navigation -->
<nav class="sidebar"> <nav class="sidebar" aria-label="Main navigation">
<div class="sidebar-header"> <header class="sidebar-header">
<h1>Nostr Resources</h1> <h1>Nostr Resources</h1>
<button id="menuToggle" class="menu-toggle"> <button id="menuToggle" class="menu-toggle" aria-label="Toggle menu">
<i class="fas fa-bars"></i> <i class="fas fa-bars"></i>
</button> </button>
</div> </header>
<div class="sidebar-content"> <div class="sidebar-content">
<div class="search-box"> <div class="search-box">
<input type="text" id="search" placeholder="Search resources..."> <input type="text" id="search" placeholder="Search resources...">
@ -29,26 +47,30 @@
</nav> </nav>
<!-- Main Content --> <!-- Main Content -->
<main class="main-content"> <main class="main-content" role="main">
<div class="content-header"> <header class="content-header">
<div class="view-controls"> <div class="view-controls">
<button id="darkModeToggle" class="theme-toggle"> <button id="darkModeToggle" class="theme-toggle" aria-label="Toggle dark mode">
<i class="fas fa-moon"></i> <i class="fas fa-moon"></i>
</button> </button>
<div class="sort-controls"> <div class="sort-controls">
<select id="sortSelect"> <label for="sortSelect" class="sr-only">Sort resources by</label>
<select id="sortSelect" aria-label="Sort resources">
<option value="stars">Sort by Stars</option> <option value="stars">Sort by Stars</option>
<option value="name">Sort by Name</option> <option value="name">Sort by Name</option>
<option value="recent">Sort by Recent</option> <option value="recent">Sort by Recent</option>
</select> </select>
</div> </div>
</div> </div>
</div> </header>
<!-- Resource sections will be dynamically populated --> <div id="resources-container" role="region" aria-label="Resource listings"></div>
<div id="resources-container"></div>
</main> </main>
</div> </div>
<footer class="site-footer">
<p>&copy; 2024 Awesome Nostr Resources. All rights reserved.</p>
</footer>
<!-- Add marked.js before your script --> <!-- Add marked.js before your script -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="script.js"></script> <script src="script.js"></script>

View File

@ -304,32 +304,37 @@ function parseResourceLine(line) {
function createResourceCard(resource) { function createResourceCard(resource) {
const card = document.createElement('div'); const card = document.createElement('div');
card.className = 'resource-card'; card.className = 'resource-card';
card.dataset.stars = resource.stars || 0;
const formattedContent = ` // Add schema.org structured data
<div class="resource-title"><strong>${resource.name}</strong></div> card.setAttribute('itemscope', '');
${resource.link ? ` card.setAttribute('itemtype', 'https://schema.org/SoftwareApplication');
<div class="resource-link">
<a href="${resource.link}" target="_blank"> card.innerHTML = `
<i class="fas fa-external-link-alt"></i> <div class="resource-header">
${resource.link} <h3 class="resource-title">
<a href="${resource.link}"
target="_blank"
rel="noopener"
itemprop="name">
${resource.name}
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
</a> </a>
</div> </h3>
` : ''}
${resource.description ? `
<div class="resource-description">
${resource.description}
</div>
` : ''}
${resource.stars ? ` ${resource.stars ? `
<div class="resource-stars"> <div class="resource-stars" itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">
<i class="fas fa-star"></i> <i class="fas fa-star" aria-hidden="true"></i>
${resource.stars} <span itemprop="ratingValue">${resource.stars}</span>
<meta itemprop="ratingCount" content="${resource.stars}">
</div>
` : ''}
</div>
${resource.description ? `
<div class="resource-description" itemprop="description">
${resource.description}
</div> </div>
` : ''} ` : ''}
`; `;
card.innerHTML = formattedContent;
return card; return card;
} }
@ -606,23 +611,31 @@ function createResourceCard(resource) {
const card = document.createElement('div'); const card = document.createElement('div');
card.className = 'resource-card'; card.className = 'resource-card';
// Add schema.org structured data
card.setAttribute('itemscope', '');
card.setAttribute('itemtype', 'https://schema.org/SoftwareApplication');
card.innerHTML = ` card.innerHTML = `
<div class="resource-header"> <div class="resource-header">
<h3 class="resource-title"> <h3 class="resource-title">
<a href="${resource.link}" target="_blank"> <a href="${resource.link}"
target="_blank"
rel="noopener"
itemprop="name">
${resource.name} ${resource.name}
<i class="fas fa-external-link-alt"></i> <i class="fas fa-external-link-alt" aria-hidden="true"></i>
</a> </a>
</h3> </h3>
${resource.stars ? ` ${resource.stars ? `
<div class="resource-stars"> <div class="resource-stars" itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">
<i class="fas fa-star"></i> <i class="fas fa-star" aria-hidden="true"></i>
${resource.stars} <span itemprop="ratingValue">${resource.stars}</span>
<meta itemprop="ratingCount" content="${resource.stars}">
</div> </div>
` : ''} ` : ''}
</div> </div>
${resource.description ? ` ${resource.description ? `
<div class="resource-description"> <div class="resource-description" itemprop="description">
${resource.description} ${resource.description}
</div> </div>
` : ''} ` : ''}

View File

@ -47,6 +47,8 @@ body {
height: 100vh; height: 100vh;
overflow-y: auto; overflow-y: auto;
transition: transform 0.3s ease; transition: transform 0.3s ease;
border-right: 1px solid rgba(110, 84, 148, 0.15);
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
} }
.sidebar-header { .sidebar-header {
@ -107,6 +109,32 @@ body {
text-align: center; text-align: center;
} }
/* Custom Scrollbar Styles */
.sidebar::-webkit-scrollbar {
width: 8px;
}
.sidebar::-webkit-scrollbar-track {
background: var(--sidebar-background);
}
.sidebar::-webkit-scrollbar-thumb {
background: var(--primary-color);
opacity: 0.5;
border-radius: 4px;
transition: background 0.2s ease;
}
.sidebar::-webkit-scrollbar-thumb:hover {
background: var(--hover-color);
}
/* Firefox scrollbar styles */
.sidebar {
scrollbar-width: thin;
scrollbar-color: var(--primary-color) var(--sidebar-background);
}
/* Main Content Styles */ /* Main Content Styles */
.main-content { .main-content {
margin-left: 280px; margin-left: 280px;
@ -335,3 +363,85 @@ body {
[data-theme="dark"] .markdown-content h3 { [data-theme="dark"] .markdown-content h3 {
color: #f1c40f; color: #f1c40f;
} }
/* Main content scrollbar styles */
.main-content::-webkit-scrollbar {
width: 8px;
}
.main-content::-webkit-scrollbar-track {
background: var(--background-color);
}
.main-content::-webkit-scrollbar-thumb {
background: var(--primary-color);
opacity: 0.5;
border-radius: 4px;
transition: background 0.2s ease;
}
.main-content::-webkit-scrollbar-thumb:hover {
background: var(--hover-color);
}
/* Firefox main content scrollbar styles */
.main-content {
scrollbar-width: thin;
scrollbar-color: var(--primary-color) var(--background-color);
}
/* Dark theme scrollbar adjustments */
[data-theme="dark"] .sidebar::-webkit-scrollbar-track,
[data-theme="dark"] .main-content::-webkit-scrollbar-track {
background: var(--sidebar-background);
}
[data-theme="dark"] .sidebar::-webkit-scrollbar-thumb,
[data-theme="dark"] .main-content::-webkit-scrollbar-thumb {
background: rgba(110, 84, 148, 0.6);
}
[data-theme="dark"] .sidebar::-webkit-scrollbar-thumb:hover,
[data-theme="dark"] .main-content::-webkit-scrollbar-thumb:hover {
background: rgba(110, 84, 148, 0.8);
}
/* Screen reader only class */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Improve link accessibility */
a:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Improve button accessibility */
button:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Add focus styles for dark mode */
[data-theme="dark"] a:focus,
[data-theme="dark"] button:focus {
outline-color: var(--link-color);
}
/* Footer styles */
.site-footer {
background-color: var(--sidebar-background);
color: var(--text-color);
text-align: center;
padding: 1rem;
margin-top: auto;
}