chore: rename references to open-rank back to open-seo (#35)

* docs: move project docs into docs directory

* docs: rebrand landing site as OpenSEO

* fix: update remaining OpenSEO backlinks links

* Change landing page copy + format

* website: add www custom domain route

* Tweak README

* save
This commit is contained in:
Ben Senescu 2026-03-16 18:58:44 -04:00 committed by GitHub
parent a51112d877
commit 23fb595755
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 97 additions and 97 deletions

View File

@ -91,21 +91,16 @@ printf '%s' 'YOUR_LOGIN:YOUR_PASSWORD' | base64
OpenSEO supports two self-hosting paths: OpenSEO supports two self-hosting paths:
- Docker for your homelab or local use. - Docker for your homelab or local use (Recommended).
- Cloudflare for use across multiple devices or for your team. - Cloudflare for use across multiple devices or for your team.
If you already have Docker installed (or are willing to install it), that is the quickest way to test OpenSEO. _Docker_
Use this quick guide: Docker is recommended for getting started. It's super easy to get up and running once you install Docker.
- Choose Docker when: _Cloudflare_
- You already have Docker installed and want to get set up quickly.
- You have a homelab setup. If you love OpenSEO and want to use it across multiple devices or with your team, you can host it on Cloudflare which we'll be a SaaS-like experience. Also, this will have automatic database backups and other nice convenience features. It's just a bit more effort to get started if you're unfamiliar with Cloudflare.
- You only want to use OpenSEO locally on one device.
- Choose Cloudflare when:
- You want a more SaaS like experience.
- You want to use it from multiple devices or with teammates.
- You want support for more powerful future features, such as sharing public links to reports or running site audits that render your website's JavaScript.
## Docker Self Hosting ## Docker Self Hosting
@ -120,8 +115,6 @@ Quickstart:
3. `docker compose up -d` 3. `docker compose up -d`
4. Open `http://localhost:<PORT>` (default `3001`) 4. Open `http://localhost:<PORT>` (default `3001`)
Docker Compose passes `.env` values into the container, and the Docker self-host flow enables `CLOUDFLARE_INCLUDE_PROCESS_ENV=true` so the Cloudflare Vite runtime can read them as Worker bindings.
By default, `compose.yaml` pulls the published image from GHCR: By default, `compose.yaml` pulls the published image from GHCR:
- `ghcr.io/every-app/open-seo:latest` - `ghcr.io/every-app/open-seo:latest`

View File

@ -225,11 +225,11 @@ function InlineMailingListLink() {
return ( return (
<a <a
className="underline underline-offset-2 hover:text-base-content/70" className="underline underline-offset-2 hover:text-base-content/70"
href="https://openrank.io" href="https://openseo.so"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
> >
join the openrank.io mailing list join the OpenSEO mailing list
</a> </a>
); );
} }

View File

@ -1 +1 @@
web/open-rank web/open-seo

View File

@ -1,5 +1,5 @@
{ {
"name": "open-rank-landing", "name": "open-seo-landing",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,4 +1,4 @@
# https://www.robotstxt.org/robotstxt.html # https://www.robotstxt.org/robotstxt.html
User-agent: * User-agent: *
Disallow: Disallow:
Sitemap: https://openrank.io/sitemap.xml Sitemap: https://openseo.so/sitemap.xml

View File

@ -9,7 +9,7 @@ const __dirname = dirname(__filename);
const DIST_DIR = join(__dirname, "../dist/client"); const DIST_DIR = join(__dirname, "../dist/client");
const DEFAULT_SITE_URL = "https://openrank.io"; const DEFAULT_SITE_URL = "https://openseo.so";
const SITE_URL = (process.env.SITE_URL ?? DEFAULT_SITE_URL).replace(/\/+$/, ""); const SITE_URL = (process.env.SITE_URL ?? DEFAULT_SITE_URL).replace(/\/+$/, "");
const STATIC_PATHS = new Set(["/", "/privacy"]); const STATIC_PATHS = new Set(["/", "/privacy"]);

View File

@ -3,7 +3,7 @@ import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
export function baseOptions(): BaseLayoutProps { export function baseOptions(): BaseLayoutProps {
return { return {
nav: { nav: {
title: <span className="font-semibold">OpenRank</span>, title: <span className="font-semibold">OpenSEO</span>,
}, },
links: [ links: [
{ {

View File

@ -1,4 +1,4 @@
const DEFAULT_SITE_URL = "https://openrank.io"; const DEFAULT_SITE_URL = "https://openseo.so";
export const SITE_URL = ( export const SITE_URL = (
process.env.SITE_URL ?? process.env.SITE_URL ??

View File

@ -43,7 +43,7 @@ function RootDocument({ children }: { children: React.ReactNode }) {
<script <script
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: __html:
"(function(){function loadAnalytics(){if(window.__openrankAnalyticsLoaded)return;window.__openrankAnalyticsLoaded=true;window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)};plausible.init=plausible.init||function(i){plausible.o=i||{}};plausible.init({endpoint:'/api/event'});var script=document.createElement('script');script.defer=true;script.src='/js/script.js';document.head.appendChild(script)}function schedule(){if('requestIdleCallback'in window){window.requestIdleCallback(loadAnalytics,{timeout:2000});return}window.setTimeout(loadAnalytics,2000)}if(document.readyState==='complete'){schedule();return}window.addEventListener('load',schedule,{once:true})})();", "(function(){function loadAnalytics(){if(window.__openSeoAnalyticsLoaded)return;window.__openSeoAnalyticsLoaded=true;window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)};plausible.init=plausible.init||function(i){plausible.o=i||{}};plausible.init({endpoint:'/api/event'});var script=document.createElement('script');script.defer=true;script.src='/js/script.js';document.head.appendChild(script)}function schedule(){if('requestIdleCallback'in window){window.requestIdleCallback(loadAnalytics,{timeout:2000});return}window.setTimeout(loadAnalytics,2000)}if(document.readyState==='complete'){schedule();return}window.addEventListener('load',schedule,{once:true})})();",
}} }}
/> />
</head> </head>

View File

@ -41,7 +41,7 @@ export const Route = createFileRoute("/api/subscribe")({
}, },
body: JSON.stringify({ body: JSON.stringify({
email: parsed.data.email, email: parsed.data.email,
source: "openrank-waitlist", source: "openseo-waitlist",
}), }),
}, },
); );

View File

@ -20,13 +20,13 @@ export const Route = createFileRoute("/blogs/$")({
const data = loaderData as const data = loaderData as
| { title?: string; description?: string; url?: string } | { title?: string; description?: string; url?: string }
| undefined; | undefined;
const title = data?.title ?? "OpenRank Blog"; const title = data?.title ?? "OpenSEO Blog";
const description = data?.description; const description = data?.description;
return buildPageSeo({ return buildPageSeo({
title, title,
description, description,
path: data?.url ?? "/blogs", path: data?.url ?? "/blogs",
titleSuffix: "OpenRank Blog", titleSuffix: "OpenSEO Blog",
ogType: "article", ogType: "article",
}); });
}, },

View File

@ -4,13 +4,12 @@ import { baseOptions } from "@/lib/layout.shared";
import { getBlogPosts } from "@/lib/content.functions"; import { getBlogPosts } from "@/lib/content.functions";
import { buildPageSeo } from "@/lib/seo"; import { buildPageSeo } from "@/lib/seo";
const blogIndexDescription = const blogIndexDescription = "Updates and guides from OpenSEO.";
"Updates and guides from OpenRank.";
export const Route = createFileRoute("/blogs/")({ export const Route = createFileRoute("/blogs/")({
head: () => head: () =>
buildPageSeo({ buildPageSeo({
title: "OpenRank Blog", title: "OpenSEO Blog",
description: blogIndexDescription, description: blogIndexDescription,
path: "/blogs", path: "/blogs",
}), }),

View File

@ -2,7 +2,7 @@ import { createFileRoute, Link } from "@tanstack/react-router";
import { useState } from "react"; import { useState } from "react";
import { toCanonicalUrl } from "@/lib/seo"; import { toCanonicalUrl } from "@/lib/seo";
const homeTitle = "OpenRank - Own Your SEO"; const homeTitle = "OpenSEO - Own Your SEO";
const homeDescription = const homeDescription =
"Own your SEO. Pay only for what you use. No subscriptions. Open source alternative to Semrush and Ahrefs."; "Own your SEO. Pay only for what you use. No subscriptions. Open source alternative to Semrush and Ahrefs.";
@ -107,7 +107,7 @@ function Home() {
<div className="max-w-3xl mx-auto px-6 py-16 md:py-24"> <div className="max-w-3xl mx-auto px-6 py-16 md:py-24">
{/* Nav */} {/* Nav */}
<nav className="flex items-center justify-between mb-20"> <nav className="flex items-center justify-between mb-20">
<span className="text-sm font-semibold">OpenRank</span> <span className="text-sm font-semibold">OpenSEO</span>
<a <a
href="https://github.com/every-app/open-seo" href="https://github.com/every-app/open-seo"
target="_blank" target="_blank"
@ -133,9 +133,10 @@ function Home() {
<ul className="mt-5 space-y-3"> <ul className="mt-5 space-y-3">
{[ {[
"Keyword Research", "Keyword Research",
"Competitor Domain Insights", "Backlink Analysis",
"Competitor Insights",
"Site Audits", "Site Audits",
"Backlinks, Rank Tracking and more (Coming soon)", "Rank Tracking and more (Coming soon)",
].map((item) => ( ].map((item) => (
<li key={item} className="flex gap-2.5 text-sm text-neutral-800"> <li key={item} className="flex gap-2.5 text-sm text-neutral-800">
<span className="text-neutral-500 mt-[2px]">&mdash;</span> <span className="text-neutral-500 mt-[2px]">&mdash;</span>
@ -219,13 +220,13 @@ function Home() {
loop loop
playsInline playsInline
preload="none" preload="none"
aria-label="OpenRank product demo" aria-label="OpenSEO product demo"
> >
<source src="/demo.webm" type="video/webm" /> <source src="/demo.webm" type="video/webm" />
<source src="/demo.mp4" type="video/mp4" /> <source src="/demo.mp4" type="video/mp4" />
<img <img
src="/demo-poster.webp" src="/demo-poster.webp"
alt="OpenRank product demo" alt="OpenSEO product demo"
width={1280} width={1280}
height={808} height={808}
className="w-full rounded-md border border-neutral-200" className="w-full rounded-md border border-neutral-200"
@ -234,7 +235,7 @@ function Home() {
/> />
</video> </video>
<p className="text-[11px] text-neutral-600 mt-2"> <p className="text-[11px] text-neutral-600 mt-2">
Keyword research in OpenRank Keyword research in OpenSEO
</p> </p>
</div> </div>

View File

@ -1,6 +1,7 @@
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
const PLAUSIBLE_SCRIPT_URL = "https://plausible.io/js/pa-DllmchvGzcNdY2jEy1-Hc.js"; const PLAUSIBLE_SCRIPT_URL =
"https://plausible.io/js/pa-DllmchvGzcNdY2jEy1-Hc.js";
export const Route = createFileRoute("/js/script.js")({ export const Route = createFileRoute("/js/script.js")({
server: { server: {

View File

@ -5,9 +5,9 @@ export const Route = createFileRoute("/privacy")({
head: () => head: () =>
buildPageSeo({ buildPageSeo({
title: "Privacy Policy", title: "Privacy Policy",
description: "OpenRank privacy policy", description: "OpenSEO privacy policy",
path: "/privacy", path: "/privacy",
titleSuffix: "OpenRank", titleSuffix: "OpenSEO",
}), }),
component: Privacy, component: Privacy,
}); });
@ -16,8 +16,11 @@ function Privacy() {
return ( return (
<div className="bg-fd-background text-fd-foreground min-h-screen"> <div className="bg-fd-background text-fd-foreground min-h-screen">
<header className="px-6 py-4 border-b border-fd-border"> <header className="px-6 py-4 border-b border-fd-border">
<Link to="/" className="font-semibold text-fd-foreground hover:opacity-80"> <Link
OpenRank to="/"
className="font-semibold text-fd-foreground hover:opacity-80"
>
OpenSEO
</Link> </Link>
</header> </header>
@ -33,30 +36,31 @@ function Privacy() {
<h2>How we use it</h2> <h2>How we use it</h2>
<p> <p>
We use your email address to send launch announcements, product updates, We use your email address to send launch announcements, product
and related OpenRank marketing emails. You can unsubscribe at any time updates, and related OpenSEO marketing emails. You can unsubscribe at
using the unsubscribe link in any email. We do not sell your data or any time using the unsubscribe link in any email. We do not sell your
share it with third parties beyond our service providers. data or share it with third parties beyond our service providers.
</p> </p>
<h2>Website analytics</h2> <h2>Website analytics</h2>
<p> <p>
We use Plausible Analytics to understand aggregate website traffic and We use Plausible Analytics to understand aggregate website traffic and
usage patterns (for example, page views and referring sites). Plausible usage patterns (for example, page views and referring sites).
is cookie-free and does not use cross-site tracking. We route analytics Plausible is cookie-free and does not use cross-site tracking. We
requests through our own domain before forwarding them to Plausible. route analytics requests through our own domain before forwarding them
to Plausible.
</p> </p>
<h2>Data storage</h2> <h2>Data storage</h2>
<p> <p>
Your email address is stored in Loops.so's infrastructure. You can request Your email address is stored in Loops.so's infrastructure. You can
deletion of your data at any time by emailing{" "} request deletion of your data at any time by emailing{" "}
<a href="mailto:privacy@everyapp.dev">privacy@everyapp.dev</a>. <a href="mailto:privacy@everyapp.dev">privacy@everyapp.dev</a>.
</p> </p>
<h2>Self-hosted usage</h2> <h2>Self-hosted usage</h2>
<p> <p>
If you self-host OpenRank, no data is sent to us. The self-hosted If you self-host OpenSEO, no data is sent to us. The self-hosted
version communicates directly with DataForSEO's APIs using your own version communicates directly with DataForSEO's APIs using your own
credentials. credentials.
</p> </p>

View File

@ -1,10 +1,8 @@
{ {
"$schema": "node_modules/wrangler/config-schema.json", "$schema": "node_modules/wrangler/config-schema.json",
"name": "open-rank-landing", "name": "open-seo-landing",
"compatibility_date": "2026-02-19", "compatibility_date": "2026-02-19",
"compatibility_flags": [ "compatibility_flags": ["nodejs_compat"],
"nodejs_compat"
],
"main": "@tanstack/react-start/server-entry", "main": "@tanstack/react-start/server-entry",
"assets": { "assets": {
"directory": "./dist/client", "directory": "./dist/client",
@ -14,13 +12,17 @@
"preview_urls": true, "preview_urls": true,
"routes": [ "routes": [
{ {
"pattern": "openrank.io", "pattern": "openseo.so",
"custom_domain": true,
},
{
"pattern": "www.openseo.so",
"custom_domain": true, "custom_domain": true,
}, },
], ],
"env": { "env": {
"preview": { "preview": {
"name": "open-rank-landing-preview", "name": "open-seo-landing-preview",
"workers_dev": true, "workers_dev": true,
"preview_urls": true, "preview_urls": true,
}, },