fix(seo): comprehensive SEO improvements per expert audit #4
No files matched your search
@@ -2,7 +2,7 @@ name: CI Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop, feature/tests-and-ci, feature/multi-admin-roles]
|
||||
branches: [main, develop, feature/tests-and-ci, feature/multi-admin-roles, fix/seo-improvements]
|
||||
|
kfj001 marked this conversation as resolved
Outdated
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -78,6 +78,11 @@ def _migrate_add_missing_columns(sync_conn):
|
||||
("station_config", "color_black", sa.String(7), "#1a1816"),
|
||||
# Multi-admin support: password_hash (nullable — existing rows stay NULL)
|
||||
("users", "password_hash", sa.String(255), None),
|
||||
# Social media columns
|
||||
("station_config", "social_facebook", sa.String(500), ""),
|
||||
("station_config", "social_twitter", sa.String(500), ""),
|
||||
("station_config", "social_instagram", sa.String(500), ""),
|
||||
("station_config", "social_youtube", sa.String(500), ""),
|
||||
]
|
||||
|
||||
# Determine dialect
|
||||
|
||||
@@ -97,6 +97,12 @@ class StationConfig(Base):
|
||||
# Donation
|
||||
donation_url = Column(String(500), nullable=False, default="")
|
||||
|
||||
# Social media
|
||||
social_facebook = Column(String(500), nullable=False, default="")
|
||||
social_twitter = Column(String(500), nullable=False, default="")
|
||||
social_instagram = Column(String(500), nullable=False, default="")
|
||||
social_youtube = Column(String(500), nullable=False, default="")
|
||||
|
||||
# Stream
|
||||
stream_url = Column(String(500), nullable=False, default="")
|
||||
stream_metadata_url = Column(String(500), nullable=False, default="")
|
||||
|
||||
@@ -78,6 +78,11 @@ class StationConfigResponse(BaseModel):
|
||||
play_store_icon_url: str
|
||||
play_store_url: str
|
||||
app_store_embed_html: str
|
||||
# Social media
|
||||
social_facebook: str
|
||||
social_twitter: str
|
||||
social_instagram: str
|
||||
social_youtube: str
|
||||
# Page content
|
||||
hero_subtitle: str
|
||||
about_intro: str
|
||||
@@ -129,6 +134,11 @@ class StationConfigUpdate(BaseModel):
|
||||
play_store_icon_url: Optional[str] = None
|
||||
play_store_url: Optional[str] = None
|
||||
app_store_embed_html: Optional[str] = None
|
||||
# Social media
|
||||
social_facebook: Optional[str] = None
|
||||
social_twitter: Optional[str] = None
|
||||
social_instagram: Optional[str] = None
|
||||
social_youtube: Optional[str] = None
|
||||
# Page content
|
||||
hero_subtitle: Optional[str] = None
|
||||
about_intro: Optional[str] = None
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Disallow: /admin
|
||||
Disallow: /login
|
||||
|
||||
Sitemap: https://kmountainflower.org/sitemap.xml
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
kfj001
commented
This is a whitelabel app - this file may need to be dynaimcally generated... This is a whitelabel app - this file may need to be dynaimcally generated...
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://kmountainflower.org/</loc>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kmountainflower.org/about</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kmountainflower.org/schedule</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kmountainflower.org/events</loc>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kmountainflower.org/contact</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- Intro -->
|
||||
<div class="about-intro">
|
||||
<img [src]="resolveImageUrl(config().hero_icon_url)" alt="" class="about-flower-decor" aria-hidden="true">
|
||||
<h2>About <span class="text-accent">{{ config().name_primary }} {{ config().name_secondary }}</span></h2>
|
||||
<h1>About <span class="text-accent">{{ config().name_primary }} {{ config().name_secondary }}</span></h1>
|
||||
<p class="section-intro">{{ config().about_intro }}</p>
|
||||
</div>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
@if (config().donation_url) {
|
||||
<div class="about-cta">
|
||||
<div class="about-flower-divider" aria-hidden="true">
|
||||
<img [src]="resolveImageUrl(config().logo_url)" alt="">
|
||||
<img [src]="resolveImageUrl(config().logo_url)" alt="" aria-hidden="true">
|
||||
</div>
|
||||
<h3>Become a Member</h3>
|
||||
<p class="section-intro">{{ config().about_donation_text }}</p>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="container">
|
||||
<div class="contact-header">
|
||||
<img src="svg/small-flower.svg" alt="" class="contact-flower" aria-hidden="true">
|
||||
<h2>Get in <span class="text-accent">Touch</span></h2>
|
||||
<h1>Get in <span class="text-accent">Touch</span></h1>
|
||||
<p class="section-intro">
|
||||
Have a song request, want to volunteer, or just want to say hello?
|
||||
We'd love to hear from you.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="container">
|
||||
<div class="events-header">
|
||||
<img src="svg/small-flower.svg" alt="" class="events-flower" aria-hidden="true">
|
||||
<h2>Upcoming <span class="text-accent">Events</span></h2>
|
||||
<h1>Upcoming <span class="text-accent">Events</span></h1>
|
||||
<p class="section-intro">{{ config().events_intro }}</p>
|
||||
</div>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
@if (event.rsvp_url) {
|
||||
<a [href]="event.rsvp_url" class="event-rsvp" target="_blank" rel="noopener">RSVP →</a>
|
||||
} @else {
|
||||
<a href="#" class="event-rsvp">Learn More →</a>
|
||||
<a routerLink="/contact" [queryParams]="{subject: 'general'}" class="event-rsvp">Learn More →</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,18 +35,26 @@
|
||||
@if (config().donation_url) {
|
||||
<li><a [href]="config().donation_url" target="_blank" rel="noopener noreferrer">Become a Member</a></li>
|
||||
}
|
||||
<li><a href="#">Volunteer</a></li>
|
||||
<li><a href="#">Corporate Giving</a></li>
|
||||
<li><a href="#">Planned Giving</a></li>
|
||||
<li><a routerLink="/contact" [queryParams]="{subject: 'volunteer'}">Volunteer</a></li>
|
||||
<li><a routerLink="/contact" [queryParams]="{subject: 'advertising'}">Corporate Giving</a></li>
|
||||
<li><a routerLink="/contact" [queryParams]="{subject: 'general'}">Planned Giving</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>Follow Us</h4>
|
||||
<div class="social-links">
|
||||
<a href="#" aria-label="Facebook" class="social-link">📘</a>
|
||||
<a href="#" aria-label="Twitter" class="social-link">🐦</a>
|
||||
<a href="#" aria-label="Instagram" class="social-link">📷</a>
|
||||
<a href="#" aria-label="YouTube" class="social-link">📺</a>
|
||||
@if (config().social_facebook) {
|
||||
<a [href]="config().social_facebook" target="_blank" rel="noopener noreferrer" aria-label="Facebook" class="social-link">📘</a>
|
||||
}
|
||||
@if (config().social_twitter) {
|
||||
<a [href]="config().social_twitter" target="_blank" rel="noopener noreferrer" aria-label="Twitter" class="social-link">🐦</a>
|
||||
}
|
||||
@if (config().social_instagram) {
|
||||
<a [href]="config().social_instagram" target="_blank" rel="noopener noreferrer" aria-label="Instagram" class="social-link">📷</a>
|
||||
}
|
||||
@if (config().social_youtube) {
|
||||
<a [href]="config().social_youtube" target="_blank" rel="noopener noreferrer" aria-label="YouTube" class="social-link">📺</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,11 @@ export interface StationConfig {
|
||||
play_store_icon_url: string;
|
||||
play_store_url: string;
|
||||
app_store_embed_html: string;
|
||||
// Social media
|
||||
|
kfj001 marked this conversation as resolved
kfj001
commented
I don't think we've added any admin UI to set these values. I don't think we've added any admin UI to set these values.
|
||||
social_facebook: string;
|
||||
social_twitter: string;
|
||||
social_instagram: string;
|
||||
social_youtube: string;
|
||||
// Page content
|
||||
hero_subtitle: string;
|
||||
about_intro: string;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="container">
|
||||
<div class="schedule-header">
|
||||
<img [src]="resolveImageUrl(config().logo_url)" alt="" class="schedule-flower" aria-hidden="true">
|
||||
<h2>Program <span class="text-accent">Schedule</span></h2>
|
||||
<h1>Program <span class="text-accent">Schedule</span></h1>
|
||||
<p class="section-intro">{{ config().schedule_intro }}</p>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in new issue
Block a user
There has got to be a more general way to ensure this runs on any branch on push.