Add public product roadmap (#480)

This commit is contained in:
Ben Senescu 2026-08-11 22:38:47 -04:00 committed by GitHub
parent 0a11839a1c
commit bd402844fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 118 additions and 0 deletions

View File

@ -0,0 +1,51 @@
---
title: Roadmap
description: Features we plan to add to OpenSEO over the next three months.
---
Have a feature request that belongs here? [Tell us on Discord](https://discord.gg/c9uGs3cFXr).
## Evergreen
- Fix bugs
- Improve onboarding
- Easy whether your new to SEO or a Pro
- Improve the UX
## Highest Priority
- Add teammates to an account
- Community skill library
- "Advanced" features available in other tools make the tools less approachable to people new to SEO.
- We'll make a community library for these more advanced workflows.
- Web Bot Auth for bot-protected sites for Audit
- Improve In App Agent
- Consistent design across OpenSEO, built on a shared component library
- IndexNow support
## Soon
- Prompt tracking for AI search visibility
- Google Business Profile integration
- Google Maps geo-grid rank tracking
- Support multi-user for Docker self hosting
- Guides for popular platforms like Coolify and Railway.
- Configurable daily and weekly email reports
- Scheduled Site Audits
- GSC Reports
- Rank Tracking Alerts
- Custom reports
- We'll expose a Claude Skill so that you can customize to your company or clients.
- Share reports with clients
- Content writing workflows for Agents
- Agent readiness checks in site audits
- Bing Webmaster Tools integration
## Not planned
- Content Optimization features like "Keyword Density"
- Advanced Site Audit Features like JS Rendering
- Keyword Gap Analysis Page
- We will support this as a skill. You can ask Claude to turn it into a report.
Have a feature request that belongs here? [Tell us on Discord](https://discord.gg/c9uGs3cFXr).

View File

@ -28,6 +28,7 @@ const STATIC_PATHS = [
"/backlink-checker", "/backlink-checker",
"/open-source-seo", "/open-source-seo",
"/google-search-console-mcp", "/google-search-console-mcp",
"/roadmap",
...Object.values(FEATURE_PAGE_SLUGS).map((slug) => `/features/${slug}`), ...Object.values(FEATURE_PAGE_SLUGS).map((slug) => `/features/${slug}`),
]; ];

View File

@ -51,6 +51,7 @@ export function SiteFooter({ className }: { className?: string }) {
<div> <div>
<p className="font-semibold text-neutral-900">Company</p> <p className="font-semibold text-neutral-900">Company</p>
<div className="mt-2 flex flex-col gap-1.5"> <div className="mt-2 flex flex-col gap-1.5">
<Link to="/roadmap">Roadmap</Link>
<Link to="/pricing">Pricing</Link> <Link to="/pricing">Pricing</Link>
<a <a
href="https://github.com/every-app/open-seo" href="https://github.com/every-app/open-seo"

View File

@ -23,6 +23,7 @@ import { Route as BlogsSplatRouteImport } from './routes/blogs/$'
import { Route as ApiSubscribeRouteImport } from './routes/api/subscribe' import { Route as ApiSubscribeRouteImport } from './routes/api/subscribe'
import { Route as ApiEventRouteImport } from './routes/api/event' import { Route as ApiEventRouteImport } from './routes/api/event'
import { Route as ApiBacklinkCheckRouteImport } from './routes/api/backlink-check' import { Route as ApiBacklinkCheckRouteImport } from './routes/api/backlink-check'
import { Route as MarketingRoadmapRouteImport } from './routes/_marketing/roadmap'
import { Route as MarketingPricingRouteImport } from './routes/_marketing/pricing' import { Route as MarketingPricingRouteImport } from './routes/_marketing/pricing'
import { Route as MarketingOpenSourceSeoRouteImport } from './routes/_marketing/open-source-seo' import { Route as MarketingOpenSourceSeoRouteImport } from './routes/_marketing/open-source-seo'
import { Route as MarketingGoogleSearchConsoleMcpRouteImport } from './routes/_marketing/google-search-console-mcp' import { Route as MarketingGoogleSearchConsoleMcpRouteImport } from './routes/_marketing/google-search-console-mcp'
@ -117,6 +118,11 @@ const ApiBacklinkCheckRoute = ApiBacklinkCheckRouteImport.update({
path: '/api/backlink-check', path: '/api/backlink-check',
getParentRoute: () => rootRouteImport, getParentRoute: () => rootRouteImport,
} as any) } as any)
const MarketingRoadmapRoute = MarketingRoadmapRouteImport.update({
id: '/roadmap',
path: '/roadmap',
getParentRoute: () => MarketingRoute,
} as any)
const MarketingPricingRoute = MarketingPricingRouteImport.update({ const MarketingPricingRoute = MarketingPricingRouteImport.update({
id: '/pricing', id: '/pricing',
path: '/pricing', path: '/pricing',
@ -268,6 +274,7 @@ export interface FileRoutesByFullPath {
'/google-search-console-mcp': typeof MarketingGoogleSearchConsoleMcpRoute '/google-search-console-mcp': typeof MarketingGoogleSearchConsoleMcpRoute
'/open-source-seo': typeof MarketingOpenSourceSeoRoute '/open-source-seo': typeof MarketingOpenSourceSeoRoute
'/pricing': typeof MarketingPricingRoute '/pricing': typeof MarketingPricingRoute
'/roadmap': typeof MarketingRoadmapRoute
'/api/backlink-check': typeof ApiBacklinkCheckRoute '/api/backlink-check': typeof ApiBacklinkCheckRoute
'/api/event': typeof ApiEventRoute '/api/event': typeof ApiEventRoute
'/api/subscribe': typeof ApiSubscribeRoute '/api/subscribe': typeof ApiSubscribeRoute
@ -306,6 +313,7 @@ export interface FileRoutesByTo {
'/google-search-console-mcp': typeof MarketingGoogleSearchConsoleMcpRoute '/google-search-console-mcp': typeof MarketingGoogleSearchConsoleMcpRoute
'/open-source-seo': typeof MarketingOpenSourceSeoRoute '/open-source-seo': typeof MarketingOpenSourceSeoRoute
'/pricing': typeof MarketingPricingRoute '/pricing': typeof MarketingPricingRoute
'/roadmap': typeof MarketingRoadmapRoute
'/api/backlink-check': typeof ApiBacklinkCheckRoute '/api/backlink-check': typeof ApiBacklinkCheckRoute
'/api/event': typeof ApiEventRoute '/api/event': typeof ApiEventRoute
'/api/subscribe': typeof ApiSubscribeRoute '/api/subscribe': typeof ApiSubscribeRoute
@ -347,6 +355,7 @@ export interface FileRoutesById {
'/_marketing/google-search-console-mcp': typeof MarketingGoogleSearchConsoleMcpRoute '/_marketing/google-search-console-mcp': typeof MarketingGoogleSearchConsoleMcpRoute
'/_marketing/open-source-seo': typeof MarketingOpenSourceSeoRoute '/_marketing/open-source-seo': typeof MarketingOpenSourceSeoRoute
'/_marketing/pricing': typeof MarketingPricingRoute '/_marketing/pricing': typeof MarketingPricingRoute
'/_marketing/roadmap': typeof MarketingRoadmapRoute
'/api/backlink-check': typeof ApiBacklinkCheckRoute '/api/backlink-check': typeof ApiBacklinkCheckRoute
'/api/event': typeof ApiEventRoute '/api/event': typeof ApiEventRoute
'/api/subscribe': typeof ApiSubscribeRoute '/api/subscribe': typeof ApiSubscribeRoute
@ -389,6 +398,7 @@ export interface FileRouteTypes {
| '/google-search-console-mcp' | '/google-search-console-mcp'
| '/open-source-seo' | '/open-source-seo'
| '/pricing' | '/pricing'
| '/roadmap'
| '/api/backlink-check' | '/api/backlink-check'
| '/api/event' | '/api/event'
| '/api/subscribe' | '/api/subscribe'
@ -427,6 +437,7 @@ export interface FileRouteTypes {
| '/google-search-console-mcp' | '/google-search-console-mcp'
| '/open-source-seo' | '/open-source-seo'
| '/pricing' | '/pricing'
| '/roadmap'
| '/api/backlink-check' | '/api/backlink-check'
| '/api/event' | '/api/event'
| '/api/subscribe' | '/api/subscribe'
@ -467,6 +478,7 @@ export interface FileRouteTypes {
| '/_marketing/google-search-console-mcp' | '/_marketing/google-search-console-mcp'
| '/_marketing/open-source-seo' | '/_marketing/open-source-seo'
| '/_marketing/pricing' | '/_marketing/pricing'
| '/_marketing/roadmap'
| '/api/backlink-check' | '/api/backlink-check'
| '/api/event' | '/api/event'
| '/api/subscribe' | '/api/subscribe'
@ -616,6 +628,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ApiBacklinkCheckRouteImport preLoaderRoute: typeof ApiBacklinkCheckRouteImport
parentRoute: typeof rootRouteImport parentRoute: typeof rootRouteImport
} }
'/_marketing/roadmap': {
id: '/_marketing/roadmap'
path: '/roadmap'
fullPath: '/roadmap'
preLoaderRoute: typeof MarketingRoadmapRouteImport
parentRoute: typeof MarketingRoute
}
'/_marketing/pricing': { '/_marketing/pricing': {
id: '/_marketing/pricing' id: '/_marketing/pricing'
path: '/pricing' path: '/pricing'
@ -792,6 +811,7 @@ interface MarketingRouteChildren {
MarketingGoogleSearchConsoleMcpRoute: typeof MarketingGoogleSearchConsoleMcpRoute MarketingGoogleSearchConsoleMcpRoute: typeof MarketingGoogleSearchConsoleMcpRoute
MarketingOpenSourceSeoRoute: typeof MarketingOpenSourceSeoRoute MarketingOpenSourceSeoRoute: typeof MarketingOpenSourceSeoRoute
MarketingPricingRoute: typeof MarketingPricingRoute MarketingPricingRoute: typeof MarketingPricingRoute
MarketingRoadmapRoute: typeof MarketingRoadmapRoute
MarketingIndexRoute: typeof MarketingIndexRoute MarketingIndexRoute: typeof MarketingIndexRoute
MarketingFeaturesAiBrandVisibilityRoute: typeof MarketingFeaturesAiBrandVisibilityRoute MarketingFeaturesAiBrandVisibilityRoute: typeof MarketingFeaturesAiBrandVisibilityRoute
MarketingFeaturesAiSearchPromptsRoute: typeof MarketingFeaturesAiSearchPromptsRoute MarketingFeaturesAiSearchPromptsRoute: typeof MarketingFeaturesAiSearchPromptsRoute
@ -820,6 +840,7 @@ const MarketingRouteChildren: MarketingRouteChildren = {
MarketingGoogleSearchConsoleMcpRoute: MarketingGoogleSearchConsoleMcpRoute, MarketingGoogleSearchConsoleMcpRoute: MarketingGoogleSearchConsoleMcpRoute,
MarketingOpenSourceSeoRoute: MarketingOpenSourceSeoRoute, MarketingOpenSourceSeoRoute: MarketingOpenSourceSeoRoute,
MarketingPricingRoute: MarketingPricingRoute, MarketingPricingRoute: MarketingPricingRoute,
MarketingRoadmapRoute: MarketingRoadmapRoute,
MarketingIndexRoute: MarketingIndexRoute, MarketingIndexRoute: MarketingIndexRoute,
MarketingFeaturesAiBrandVisibilityRoute: MarketingFeaturesAiBrandVisibilityRoute:
MarketingFeaturesAiBrandVisibilityRoute, MarketingFeaturesAiBrandVisibilityRoute,

View File

@ -52,6 +52,7 @@ function getMobileNavItems(githubStarCount: string) {
label: "Product", label: "Product",
links: [ links: [
{ label: "Features", href: "/features" }, { label: "Features", href: "/features" },
{ label: "Roadmap", href: "/roadmap" },
{ label: "Pricing", href: "/pricing" }, { label: "Pricing", href: "/pricing" },
], ],
}, },
@ -170,6 +171,12 @@ function MarketingLayout() {
<div className="hidden items-center justify-center gap-5 md:flex"> <div className="hidden items-center justify-center gap-5 md:flex">
<FeatureDropdown /> <FeatureDropdown />
<ResourcesDropdown /> <ResourcesDropdown />
<Link
to="/roadmap"
className="text-sm font-semibold text-neutral-600 transition-colors hover:text-neutral-900"
>
Roadmap
</Link>
<Link <Link
to="/pricing" to="/pricing"
className="text-sm font-semibold text-neutral-600 transition-colors hover:text-neutral-900" className="text-sm font-semibold text-neutral-600 transition-colors hover:text-neutral-900"

View File

@ -0,0 +1,37 @@
import { createFileRoute } from "@tanstack/react-router";
import defaultMdxComponents from "fumadocs-ui/mdx";
import { DocsBody } from "fumadocs-ui/page";
import RoadmapContent, {
frontmatter as roadmapFrontmatter,
} from "../../../content/marketing/roadmap.md";
import { buildPageSeo } from "@/lib/seo";
export const Route = createFileRoute("/_marketing/roadmap")({
head: () =>
buildPageSeo({
title: roadmapFrontmatter.title,
description: roadmapFrontmatter.description,
path: "/roadmap",
titleSuffix: "OpenSEO",
}),
component: Roadmap,
});
function Roadmap() {
return (
<article className="mx-auto max-w-3xl text-neutral-900">
<header className="mb-10 border-b border-[var(--color-border-subtle)] pb-8">
<h1 className="text-4xl font-semibold leading-tight tracking-tight text-neutral-950 md:text-6xl">
{roadmapFrontmatter.title}
</h1>
<p className="mt-5 max-w-2xl text-lg leading-8 text-[var(--color-brand-muted)]">
{roadmapFrontmatter.description}
</p>
</header>
<DocsBody className="min-w-0 text-neutral-800 [&_a]:!text-neutral-950 [&_a]:font-medium [&_a]:underline [&_a]:decoration-[var(--color-brand-accent)] [&_a]:underline-offset-4 [&_h2]:!text-neutral-950 [&_h2_a]:!no-underline [&_li]:!text-neutral-700 [&_p]:!text-neutral-700">
<RoadmapContent components={defaultMdxComponents} />
</DocsBody>
</article>
);
}