Add comprehensive SEO improvements: meta tags, robots.txt, sitemap.xml, and favicon. Fix meta description rendering issues with proper HTML entity encoding. Update port configuration to use PORT environment variable.

This commit is contained in:
2025-08-26 08:29:34 +00:00
parent ae9107705d
commit eedaa253e4
16 changed files with 177 additions and 2 deletions

37
FAVICON_CREATION.md Normal file
View File

@@ -0,0 +1,37 @@
# Favicon Creation Guide
This document explains how to create a proper favicon from the 📈 emoji for the Markov Economics application.
## Recommended Approach
To create a professional favicon from the 📈 emoji, follow these steps:
1. Use a graphic design tool like:
- Adobe Illustrator or Photoshop
- Free tools like GIMP or Inkscape
- Online favicon generators
2. Create a 16x16 pixel and 32x32 pixel version of the favicon with the 📈 symbol
3. Export in PNG and ICO formats
## Alternative: Using Online Tools
1. Visit a favicon generator site like favicon.io or realfavicongenerator.net
2. Upload an image of the 📈 emoji or use their emoji tool
3. Generate the favicon package
4. Replace the placeholder files in the `app/static/img/` directory with the generated files
## SVG Version
We've included an SVG version that renders the emoji directly:
- File: `app/static/img/favicon.svg`
This works in modern browsers but may not be supported in all contexts where favicons are used.
## Implementation Notes
The HTML already includes references to all favicon versions:
- SVG version (modern browsers)
- PNG versions (32x32 and 16x16)
- Apple touch icon

View File

@@ -13,6 +13,8 @@ This project provides an interactive simulation of economic dynamics, particular
- RESTful API endpoints for programmatic access
- WebSocket support for real-time updates during simulations
- Docker containerization for easy deployment
- SEO optimized with meta tags, robots.txt, and sitemap.xml
- Favicon based on the 📈 emoji for brand recognition
## Prerequisites

View File

@@ -256,6 +256,30 @@ def health_check():
})
@main_bp.route('/robots.txt')
def robots_txt():
"""
Serve the robots.txt file.
Returns:
robots.txt content
"""
from flask import current_app
return current_app.send_static_file('robots.txt')
@main_bp.route('/sitemap.xml')
def sitemap_xml():
"""
Serve the sitemap.xml file.
Returns:
sitemap.xml content
"""
from flask import current_app
return current_app.send_static_file('sitemap.xml')
@main_bp.errorhandler(404)
def not_found_error(error):
"""

View File

@@ -0,0 +1 @@
This is a placeholder for the Apple touch icon PNG file.

View File

@@ -0,0 +1 @@
This is a placeholder for the 16x16 favicon PNG file.

View File

@@ -0,0 +1 @@
This is a placeholder for the 32x32 favicon PNG file.

View File

@@ -0,0 +1 @@
This is a placeholder for the favicon.ico file. In a real implementation, this would be a proper ICO format image file.

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<text y="85" font-size="90" text-anchor="middle">📈</text>
</svg>

After

Width:  |  Height:  |  Size: 132 B

View File

@@ -0,0 +1 @@
This is a placeholder for the social media sharing image showing wealth inequality simulation visualization.

15
app/static/robots.txt Normal file
View File

@@ -0,0 +1,15 @@
User-agent: *
Allow: /
Sitemap: https://markoveconomics.com/sitemap.xml
# Prevent crawling of API endpoints
Disallow: /api/
Disallow: /test-
Disallow: /debug
# Prevent crawling of simulation results (if applicable)
Disallow: /results/
# Crawl delay for polite crawling
Crawl-delay: 10

33
app/static/sitemap.xml Normal file
View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://markoveconomics.com/</loc>
<lastmod>2025-08-26</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://markoveconomics.com/about</loc>
<lastmod>2025-08-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://markoveconomics.com/simulation</loc>
<lastmod>2025-08-26</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://markoveconomics.com/robots.txt</loc>
<lastmod>2025-08-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.1</priority>
</url>
<url>
<loc>https://markoveconomics.com/sitemap.xml</loc>
<lastmod>2025-08-26</lastmod>
<changefreq>monthly</changefreq>
<priority>0.1</priority>
</url>
</urlset>

View File

@@ -1,5 +1,15 @@
{% extends "base.html" %}
{% block title %}About Markov Economics - Marx, Piketty, and Wealth Inequality Theory{% endblock %}
{% block meta_description %}Learn about the economic theory behind the Markov chain simulation. Understand Marx's M-C-M' model and Piketty's r &gt; g inequality principle.{% endblock %}
{% block og_title %}About Markov Economics - Marx, Piketty, and Wealth Inequality Theory{% endblock %}
{% block og_description %}Learn about the economic theory behind the Markov chain simulation. Understand Marx's M-C-M' model and Piketty's r &gt; g inequality principle.{% endblock %}
{% block twitter_title %}About Markov Economics - Marx, Piketty, and Wealth Inequality Theory{% endblock %}
{% block twitter_description %}Learn about the economic theory behind the Markov chain simulation. Understand Marx's M-C-M' model and Piketty's r &gt; g inequality principle.{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-10">

View File

@@ -5,6 +5,31 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{{ title }}{% endblock %}</title>
<!-- SEO Meta Tags -->
<meta name="description" content="{% block meta_description %}Interactive Markov chain simulation demonstrating how capitalism &quot;eats the world&quot; through wealth inequality when r &gt; g (capital return rate exceeds economic growth).{% endblock %}">
<meta name="keywords" content="capitalism, economics, markov chain, wealth inequality, Piketty, Marx, economic simulation, r > g, capital return, economic growth">
<meta name="author" content="Markov Economics">
<meta name="robots" content="index, follow">
<!-- Open Graph / Social Media Meta Tags -->
<meta property="og:title" content="{% block og_title %}{{ title }}{% endblock %}">
<meta property="og:description" content="{% block og_description %}Interactive Markov chain simulation demonstrating how capitalism &quot;eats the world&quot; through wealth inequality when r &gt; g (capital return rate exceeds economic growth).{% endblock %}">
<meta property="og:type" content="website">
<meta property="og:url" content="https://markoveconomics.com/">
<meta property="og:image" content="https://markoveconomics.com/static/img/wealth-inequality-simulation.png">
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{% block twitter_title %}{{ title }}{% endblock %}">
<meta name="twitter:description" content="{% block twitter_description %}Interactive Markov chain simulation demonstrating how capitalism &quot;eats the world&quot; through wealth inequality when r &gt; g (capital return rate exceeds economic growth).{% endblock %}">
<meta name="twitter:image" content="https://markoveconomics.com/static/img/wealth-inequality-simulation.png">
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='img/favicon.svg') }}">
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', filename='img/favicon-32x32.png') }}">
<link rel="icon" type="image/png" sizes="16x16" href="{{ url_for('static', filename='img/favicon-16x16.png') }}">
<link rel="apple-touch-icon" sizes="180x180" href="{{ url_for('static', filename='img/apple-touch-icon.png') }}">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Chart.js -->

View File

@@ -1,5 +1,15 @@
{% extends "base.html" %}
{% block title %}Error - Markov Economics Simulation{% endblock %}
{% block meta_description %}An error occurred in the Markov economics simulation. Return to the main page to run the wealth inequality simulation.{% endblock %}
{% block og_title %}Error - Markov Economics Simulation{% endblock %}
{% block og_description %}An error occurred in the Markov economics simulation. Return to the main page to run the wealth inequality simulation.{% endblock %}
{% block twitter_title %}Error - Markov Economics Simulation{% endblock %}
{% block twitter_description %}An error occurred in the Markov economics simulation. Return to the main page to run the wealth inequality simulation.{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-6">

View File

@@ -1,5 +1,15 @@
{% extends "base.html" %}
{% block title %}Markov Economics Simulation - Interactive Wealth Inequality Model{% endblock %}
{% block meta_description %}Run interactive simulations of wealth inequality using Markov chains. Visualize how capitalism &quot;eats the world&quot; when r &gt; g.{% endblock %}
{% block og_title %}Markov Economics Simulation - Interactive Wealth Inequality Model{% endblock %}
{% block og_description %}Run interactive simulations of wealth inequality using Markov chains. Visualize how capitalism &quot;eats the world&quot; when r &gt; g.{% endblock %}
{% block twitter_title %}Markov Economics Simulation - Interactive Wealth Inequality Model{% endblock %}
{% block twitter_description %}Run interactive simulations of wealth inequality using Markov chains. Visualize how capitalism &quot;eats the world&quot; when r &gt; g.{% endblock %}
{% block extra_head %}
<style>
.parameter-card {

5
run.py
View File

@@ -13,9 +13,10 @@ app = create_app(config_name)
if __name__ == '__main__':
debug_mode = config_name == 'development'
port = int(os.getenv('PORT', 5000)) # Use PORT env var or default to 5000
# For production deployment, allow unsafe werkzeug or use a proper WSGI server
if config_name == 'production':
socketio.run(app, debug=False, host='0.0.0.0', port=5000, allow_unsafe_werkzeug=True)
socketio.run(app, debug=False, host='0.0.0.0', port=port, allow_unsafe_werkzeug=True)
else:
socketio.run(app, debug=debug_mode, host='0.0.0.0', port=5000)
socketio.run(app, debug=debug_mode, host='0.0.0.0', port=port)