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:
parent
a51112d877
commit
23fb595755
19
README.md
19
README.md
@ -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`
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
web/open-rank
|
web/open-seo
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "open-rank-landing",
|
"name": "open-seo-landing",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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"]);
|
||||||
|
|||||||
@ -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: [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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 ??
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@ -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",
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -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]">—</span>
|
<span className="text-neutral-500 mt-[2px]">—</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>
|
||||||
|
|
||||||
|
|||||||
@ -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: {
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
@ -25,41 +28,42 @@ function Privacy() {
|
|||||||
<h1>Privacy Policy</h1>
|
<h1>Privacy Policy</h1>
|
||||||
<p className="text-fd-muted-foreground">Last updated: March 2026</p>
|
<p className="text-fd-muted-foreground">Last updated: March 2026</p>
|
||||||
|
|
||||||
<h2>What we collect</h2>
|
<h2>What we collect</h2>
|
||||||
<p>
|
|
||||||
When you sign up for our waitlist, we collect your email address. This
|
|
||||||
is stored securely via Loops.so, our email service provider.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>How we use it</h2>
|
|
||||||
<p>
|
|
||||||
We use your email address to send launch announcements, product updates,
|
|
||||||
and related OpenRank marketing emails. You can unsubscribe at any time
|
|
||||||
using the unsubscribe link in any email. We do not sell your data or
|
|
||||||
share it with third parties beyond our service providers.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Website analytics</h2>
|
|
||||||
<p>
|
<p>
|
||||||
We use Plausible Analytics to understand aggregate website traffic and
|
When you sign up for our waitlist, we collect your email address. This
|
||||||
usage patterns (for example, page views and referring sites). Plausible
|
is stored securely via Loops.so, our email service provider.
|
||||||
is cookie-free and does not use cross-site tracking. We route analytics
|
|
||||||
requests through our own domain before forwarding them to Plausible.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Data storage</h2>
|
<h2>How we use it</h2>
|
||||||
<p>
|
<p>
|
||||||
Your email address is stored in Loops.so's infrastructure. You can request
|
We use your email address to send launch announcements, product
|
||||||
deletion of your data at any time by emailing{" "}
|
updates, and related OpenSEO marketing emails. You can unsubscribe at
|
||||||
<a href="mailto:privacy@everyapp.dev">privacy@everyapp.dev</a>.
|
any time using the unsubscribe link in any email. We do not sell your
|
||||||
</p>
|
data or share it with third parties beyond our service providers.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2>Self-hosted usage</h2>
|
<h2>Website analytics</h2>
|
||||||
<p>
|
<p>
|
||||||
If you self-host OpenRank, no data is sent to us. The self-hosted
|
We use Plausible Analytics to understand aggregate website traffic and
|
||||||
version communicates directly with DataForSEO's APIs using your own
|
usage patterns (for example, page views and referring sites).
|
||||||
credentials.
|
Plausible is cookie-free and does not use cross-site tracking. We
|
||||||
</p>
|
route analytics requests through our own domain before forwarding them
|
||||||
|
to Plausible.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Data storage</h2>
|
||||||
|
<p>
|
||||||
|
Your email address is stored in Loops.so's infrastructure. You can
|
||||||
|
request deletion of your data at any time by emailing{" "}
|
||||||
|
<a href="mailto:privacy@everyapp.dev">privacy@everyapp.dev</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Self-hosted usage</h2>
|
||||||
|
<p>
|
||||||
|
If you self-host OpenSEO, no data is sent to us. The self-hosted
|
||||||
|
version communicates directly with DataForSEO's APIs using your own
|
||||||
|
credentials.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2>Contact</h2>
|
<h2>Contact</h2>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@ -1,28 +1,30 @@
|
|||||||
{
|
{
|
||||||
"$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",
|
||||||
],
|
"assets": {
|
||||||
"main": "@tanstack/react-start/server-entry",
|
"directory": "./dist/client",
|
||||||
"assets": {
|
"html_handling": "drop-trailing-slash",
|
||||||
"directory": "./dist/client",
|
},
|
||||||
"html_handling": "drop-trailing-slash",
|
"workers_dev": true,
|
||||||
},
|
"preview_urls": true,
|
||||||
"workers_dev": true,
|
"routes": [
|
||||||
"preview_urls": true,
|
{
|
||||||
"routes": [
|
"pattern": "openseo.so",
|
||||||
{
|
"custom_domain": true,
|
||||||
"pattern": "openrank.io",
|
},
|
||||||
"custom_domain": true,
|
{
|
||||||
},
|
"pattern": "www.openseo.so",
|
||||||
],
|
"custom_domain": true,
|
||||||
"env": {
|
},
|
||||||
"preview": {
|
],
|
||||||
"name": "open-rank-landing-preview",
|
"env": {
|
||||||
"workers_dev": true,
|
"preview": {
|
||||||
"preview_urls": true,
|
"name": "open-seo-landing-preview",
|
||||||
},
|
"workers_dev": true,
|
||||||
},
|
"preview_urls": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user