Library
Everything you've made and kept. Drag one onto a studio to use it again.
Nothing saved for this project yet. Anything you make and keep lands here.
Projects
{{ projects.length }}/{{ projectCap }} used on your {{ planLabel }} plan · {{ paidExtraDomains }} add-on{{ paidExtraDomains === 1 ? '' : 's' }} (${{ paidExtraDomains * 15 }}/mo)
{{ p.url || 'No URL set' }}
Preparing brand kit…
{{ projects.length }} of {{ projectCap }} project{{ projectCap === 1 ? '' : 's' }} used · {{ paidExtraDomains }} paid add-on{{ paidExtraDomains === 1 ? '' : 's' }}
You're at your plan's {{ projectCap }} — adding opens an upgrade or a $15/mo add-on.
{{ currentPlan === 'free' ? 'Adding more sites needs Pro or Serial' : "You're at your project limit" }}
{{ currentPlan === 'free' ? 'Your Free plan includes 1 project. Upgrade to add this project.' : ('Your ' + planLabel + ' plan includes ' + projectCap + ' project' + (projectCap === 1 ? '' : 's') + '. Upgrade to a plan with more.') }}
Billed by Stripe. Manage or cancel any time in Settings → Subscription.
This is your {{ ordinal(projects.length + 1) }} project
Your {{ planLabel }} plan includes {{ planBaseDomains }} project{{ planBaseDomains === 1 ? '' : 's' }}. Adding this one is an extra-project add-on — +$15/mo, added to your subscription and prorated from today.
You already have {{ paidExtraDomains }} paid add-on{{ paidExtraDomains === 1 ? '' : 's' }} (${{ paidExtraDomains * 15 }}/mo). This makes {{ paidExtraDomains + 1 }} (${{ (paidExtraDomains + 1) * 15 }}/mo).
Billed by Stripe against the card on your subscription. Remove the project later and the add-on decrements automatically.
Choose a new password for your account.
{{ auth.error }}
{{ auth.notice }}
Your build-in-public sidekick.
Free to start, no card. Create your account and confirm the email we send, opening the link in this same browser. Your update and its drafts are then saved into your project, ready for you to approve. Nothing is posted until you do.
Free to start, no card. You came from the weekly page for {{ shippedIntent.repo }}. Create your account and confirm the email we send, opening the link in this same browser: the next screen has {{ shippedIntent.site ? 'its site filled in' : 'it noted' }}, so FoxPlug can write the same weekly page for your own repository.
Free to start. Once you are in, your new project setup opens{{ launchIntent.name ? ' with ' + launchIntent.name + ' filled in' : (launchIntent.typeLabel ? ' with the ' + launchIntent.typeLabel + ' category noted' : '') }}.
Free to start, no card. Three steps:
or use your email
{{ auth.error }}
{{ auth.notice }}
This is exactly what will appear on your LinkedIn profile. Nothing is posted until you press Post now.
{{ (li.preview && li.preview.name) || 'You' }}
Public post, from your own LinkedIn profile
{{ li.preview ? li.preview.text : (li.draft && li.draft.content) }}
Text only: the image on this draft is not attached.
{{ li.preview.chars }} of 3,000 characters
{{ li.notice }}
Loading the preview…
{{ li.error }}
{{ (li.preview && li.preview.expired) ? 'Your LinkedIn connection has expired. Reconnect to post.' : (li.error || 'Connect your LinkedIn account to post this from your profile. LinkedIn will ask for permission to publish on your profile. Nothing is posted until you press Post now.') }}
Posted as you, from your own LinkedIn profile. FoxPlug never posts on its own or on a schedule.
You came from the weekly page for {{ shippedIntent.repo }}.
That repository is yours, so its site is filled in below. Save it and FoxPlug writes that page for you every week, from your own merged work.
FoxPlug writes that page for your own repository every week. The site of {{ shippedIntent.repo }} is filled in below; change it to your own product's address if that repository is not yours. Connect GitHub so FoxPlug can read your merged work.
You came from the {{ launchIntent.name || launchIntent.typeLabel || 'FoxPlug' }} launch page.
{{ launchIntent.site ? 'Its address is filled in below. Change it if your product lives somewhere else, then save.' : 'Add the address of your product below.' }} Category noted: {{ launchIntent.typeLabel }}.
FoxPlug reads your site to learn what is already there — your pages and the tools it runs on — so it can tell you when something new goes live.
{{ urlGate.problem }}
Wrong account?
{{ urlGate.stage }}…
{{ urlGate.note }}
{{ urlGate.total ? (urlGate.saved + ' of ' + urlGate.total + ' pages saved') : 'Looking for your pages' }}
On your homepage: {{ urlGate.stack.join(', ') }}
{{ urlGate.error }}
Your homepage builds itself after it opens, so we couldn't read its pages yet. We saved nothing as your starting point on purpose — otherwise every page would later look brand new.
This is your starting point. From here on, when a new page or a new tool shows up on your site, FoxPlug notices.
This is your starting point.
Your stack
None of the tools we recognise (payments, live chat, analytics, error tracking, booking, search) showed up on your homepage.
Your first post — a draft, from what we just read
{{ urlGateDraft.content }}
It is saved in your Drafts either way — nothing posts on its own.
We read your site, but couldn't write your first post just now — {{ urlGate.firstPostProblem }}. Nothing was made up to fill the gap. Your pages are saved; try again from Drafts.
{{ banner }}
Your update is saved. Last step: connect {{ tryConnect.repo || 'your repo' }}
Your update and its {{ tryConnect.drafts }} draft{{ tryConnect.drafts === 1 ? '' : 's' }} are in {{ tryConnect.projectName || 'your project' }}, ready for you to approve below. Connect GitHub so every new push writes the next update for you. Nothing is posted until you approve it.
One-click GitHub connect is being switched on. Your public repo is already being read for new updates.
{{ githubConnectMsg }}
Connected. New updates will keep coming.
GitHub is connected to {{ tryConnect.projectName || 'your project' }} for {{ tryConnect.repo }}. When you push, FoxPlug writes the next update and its drafts for you to approve. Nothing is posted until you do.
You're on {{ planLabel }} — nice. 🎉
A few things worth setting up now to get the most out of it:
You've reached your project limit
The {{ planLabel }} plan includes {{ projectCap }} project{{ projectCap === 1 ? '' : 's' }}. Upgrade to run more products from one place.
You came from the {{ launchIntent.name || launchIntent.typeLabel || 'FoxPlug' }} launch page{{ launchIntent.site ? ', so its address is filled in. Change anything that is not yours.' : '.' }} Category noted: {{ launchIntent.typeLabel }}.
Add a project
Each project is its own product — its milestones, drafts and posts stay separate and every post is grounded in that product.
You came to make a promo video — let's set it up. Connect your project and every update you ship becomes ready-to-post content: branded image cards and platform-tailored text now, with narrated videos and GIFs rolling out to you first.
Pick where you write your code. FoxPlug works with all of them — your code already lives on GitHub, and we turn every push into your story.
{{ buildToolBridgeLine }}
One-click GitHub connect is being switched on. For now you can set your product up just below.
{{ githubConnectMsg }}
{{ gitlabConnectMsg }}
{{ bitbucketConnectMsg }}
Read-only access to your code. Your access is encrypted at rest — we never store it in plain text and never write to your repos.
What do you build with?
Optional — it helps us decide what to integrate next.
No GitHub yet? You can paste your product address and we'll read your page to fill in the rest — then connect your code any time in Settings.
{{ WIZARD_STEPS[wizardStep - 1].blurb }}
Paste your product URL
We'll read your page and fill in the rest — name, one-liner, logo and brand colour. Everything stays editable, and you can skip straight to typing it yourself.
{{ wizardDetectNote }}
Looks like you publish on {{ platformLabel(wizard.blog_platform) }}. We've preselected {{ destinationLabel(wizard.publish_destination) }} as your publish destination — change it any time in Drafts. We'll remember this as a hint for where to publish.
Pulling your brand…
Got your logo and colors ✓
Where do you post?
Add the places you share updates and we'll pre-fill your promos later. Optional — skip any you don't use.
Your promo power
{{ completenessMeter.pct }}%The more you connect, the more we can make for you. This never affects your free launch video.
What's your stack?
Pick the tools you build with. We'll only show you the connectors that matter — and use the rest to decide what to build next.
Connect one to begin
Connect a tool and we'll pull your real work in and write the first post on it. You can do this in Settings any time too.
{{ t.scopeHint }}
{{ ITOK_EXISTING_ONLY_NOTE[t.itok] }}
Coming soon for your stack — we know you want these
No tools picked. You can connect a tool in Settings whenever you're ready — or skip ahead and see a sample.
Already have a changelog? We'll pull it in.
Paste your changelog or blog address. We fetch your past entries and add them as history, so your first posts already know your story. WordPress: add /feed. Ghost: add /rss. Substack: add /feed. Not sure? Just paste the page address.
{{ changelogImportResult.text }}
Here's FoxPlug on your work Sample
This is a sample so you can see the shape of it. Connect a tool in Settings and your real milestones replace it.
We turned your shipped work into your first post. Review and use it in Drafts whenever you're ready.
Milestone
{{ payoffMilestone.title }}
{{ payoffMilestone.description }}
Draft post
{{ payoffDraftText }}
You're set up
Connect a tool and your first milestone — with a post waiting on it — shows up in Drafts.
Connect your repo and we'll turn what you've already shipped into ready-to-post updates. Paste a public repo — no token needed.
Checking…
✓ {{ firstRun.check.repo }} · {{ firstRun.check.commits }} recent commits
✓ {{ firstRun.check.repo }} — but no commits in the last 30 days, so there'd be nothing to write up yet.
{{ firstRun.check.error }}
{{ firstRun.msg }}
Private repo?
We only read. Nothing is posted — every draft lands in your queue for you to read first.
How this works
We find your project's advancements and make posts, videos, and images for you to share. Nothing ever posts itself — everything's yours to use.
Choose your voice
By default your posts read “I just released the…”. Switch to “we” if you'd rather they sound like something your team accomplished.
Auto-upload to the FoxSaaS YouTube channel is paused — the access token has expired (these are Testing-mode tokens and lapse about weekly, this is expected).
Fix: re-run the YouTube OAuth consent for the FoxSaaS channel and paste a fresh YOUTUBE_REFRESH_TOKEN into the Supabase Edge Function secrets. New promos still render, get their /v/ page and GIF, and post — they just won't have a YouTube link until this is renewed. Last checked {{ youtubeHealth.checked_at }}.
Let us turn your breakthroughs into visual updates — images, GIFs, even promo clips. Add Pinterest, TikTok, or Instagram (personal or business) in Settings so we know where to make them for.
Four steps from here to a published update. Each ticks off on its own as you go.
All four done — you're shipping.
Quick — what's your product called?
We'll use this in your posts so the first draft sounds like your product, not your repo.
Your kit is saved 🎉
Want this on every release? One step and FoxPlug auto-generates a kit each time you ship.
1 · Generate your first kit
Paste your product's site — FoxPlug builds your launch kit now.
{{ giftFirstRun.gift_lead === 'gif' ? '2' : '1' }} · Auto-generate on every release
Connect GitHub (or your changelog) — each update you ship becomes a kit automatically.
{{ githubConnectMsg }}
{{ approvedBand(ad).line }}
{{ displayContent(ad) }}
Approved. Now post it — that part is yours.
FoxPlug has not sent this and will not. It is written and waiting; copy it, open the platform, and press post there.
{{ displayContent(approvedNowDraft) }}
{{ milestoneHeadline(todayShare.milestone) }}
{{ todayShare.why }}
{{ displayContent(todayShare.draft) }}
{{ displayContent(o) }}
Nothing has been written for this project yet — FoxPlug writes a post when it spots a moment worth one.
When you capture work, a post gets written for it and the best one appears here.
{{ todayNext.headline }}
{{ todayNext.why }}
The rule: a post FoxPlug wrote more than 30 days ago that has not been sent comes off the queue. The text is untouched and any of them can go back.
Nothing retired to show.
{{ r.content }}
{{ diagTop.question }}
{{ diagTop.because }}
{{ fig.value }}
{{ fig.label }}
{{ fig.window }}{{ fig.scope.label }}
{{ diagTop.figures.find(f => !f.scope.site).scope.note }}
That was the only thing your figures raised.
{{ fnd.question }}
{{ fig.value }} {{ fig.label }}{{ fig.scope.label }} ·
Nothing to ask yet — no figures have come in.
Connected, but nothing pulled yet: {{ diagMissing.connectedButNoFigures.join(', ') }}.
No analytics source is connected for this domain yet.
Not connected: ,
{{ diagDrawer.title }}
{{ diagDrawer.question }}
Reading your page…
{{ diagDrawerError }}
It leads with
“{{ diagDrawer.data.leads_with }}”
The page has no heading of its own — a visitor lands with nothing to read first.
…then: “{{ diagDrawer.data.supporting_line }}”
It appears to be addressed to
{{ diagDrawer.data.addressed_to.join(", ") }}
Nobody in particular — the top of the page names no audience.
{{ diagDrawer.data.speaks_to_you_directly ? "It does speak to the reader directly (“you”)." : "It never says “you”." }}
It asks the visitor to
“{{ diagDrawer.data.primary_ask }}”
Nothing — there is no call to action near the top of the page.
Also asks: {{ diagDrawer.data.other_asks.join(", ") }}
Read from {{ diagDrawer.data.host }} just now. Read-only — nothing on your site was changed.
{{ diagDrawer.data.people }}
were people
{{ diagDrawer.data.bots }}
were automated
Of {{ diagDrawer.data.total }} sessions in the window, {{ diagDrawer.data.people }} were people. Judge everything else against that number, not the total.
Cannot be separated
{{ b.label }} ({{ b.value }}), — reported across every session at once, people and automated together. Treat them as a mix, not as what a person did.
Worked out from figures already pulled. Nothing was requested from anyone.
Where arrivals came from in the first half of the window, against the second.
No source was recorded in either half — the arrivals came in without a referrer.
Worked out from figures already pulled. Nothing was requested from anyone.
How {{ (activeProject && activeProject.name) || 'this project' }} is tracking against its plan.
{{ planDrift.plan.plan_text }}
Time frame: {{ planDrift.plan.horizon }}
No plan set for this project yet.
{{ laneEmptyNote(board.filter) }}
{{ sweepNote() }}
{{ deadDestinationCount() }} destination{{ deadDestinationCount() === 1 ? '' : 's' }} no longer resolve, so those cards render without a button.
{{ board.suppressed.count }} item{{ board.suppressed.count === 1 ? '' : 's' }} held back for having nowhere to send you.
Nothing on this board has been generated or posted. It is a list, not a queue.
{{ fsMem.clusters.length }} of {{ fsMem.clusterTotal }} shown.
Nothing is set until you press the button.
You shipped {{ silence.shipped }} thing{{ silence.shipped === 1 ? '' : 's' }} worth talking about in the last {{ silence.window_days }} days. {{ silence.posted }} {{ silence.posted === 1 ? 'has' : 'have' }} been posted so far.
{{ silence.silent }} {{ silence.silent === 1 ? 'has' : 'have' }} not been posted anywhere yet.
Nothing is going unnoticed right now.
Autopilot writes the draft and stops there. Nothing goes out until you read it and press Publish.
{{ q.question }}
What's the reason?
{{ fsMem.questionError }}
{{ a.competitor }} {{ fsAdRunFor(a) }}
name match only{{ a.headline }}
{{ fsAdShort(a.body) }}
{{ fsMem.adGen.error }}
Run them like this
{{ fsMem.adGen.plan.never }}
{{ fsMem.adGen.caveat }}
{{ v.angle }}
{{ v.headline }}
{{ v.subline }}
{{ v.why_this_angle }}
{{ iss.policy }}
{{ iss.quote }}
{{ iss.fix }}
Nothing here trips the common automated-review rules.
Worth doing, not blocking
{{ n.fix }}
{{ fsAdCompliance(v).caveat }}
{{ r.kind === 'generated' ? 'Yours' : (r.source_competitor || 'Competitor') }} · {{ fsAdRunFor(r).replace('has run this ad for ', '') }}
{{ r.headline }}
{{ fsAdShort(r.body) }}
{{ c.visits }} visit{{ c.visits === 1 ? '' : 's' }} · {{ c.conversions }} conversion{{ c.conversions === 1 ? '' : 's' }}
{{ c.conversion_rate }}% {{ c.audience.name }}| Creative | Visits | Conv. | Rate |
|---|---|---|---|
| {{ p.headline }} | {{ p.visits }} | {{ p.conversions }} | {{ p.conversion_rate === null ? '—' : p.conversion_rate + '%' }} |
{{ c.verdict }}
${{ c.cost_per_conversion }} per conversion, against a ${{ c.budget_daily }}/day budget.
Tell us what you have spent and this becomes a cost per conversion.
{{ c.unattributed_visits }} visit{{ c.unattributed_visits === 1 ? '' : 's' }} could not be tied to a specific creative.
Too early to call it
{{ fsMem.results.refine[c.campaign_id].reason }}
Winner: {{ fsMem.results.refine[c.campaign_id].winner.headline }}
{{ fsMem.results.refine[c.campaign_id].reason }}
{{ fsMem.results.refine[c.campaign_id].confidence }}
Drop these
{{ fsMem.results.refine[c.campaign_id].recommendations.kill.why }}
Move ${{ fsMem.results.refine[c.campaign_id].recommendations.budget_shift.move_usd_per_day }}/day to "{{ fsMem.results.refine[c.campaign_id].recommendations.budget_shift.to }}"
{{ fsMem.results.refine[c.campaign_id].recommendations.budget_shift.expected }}
{{ fsMem.results.refine[c.campaign_id].recommendations.budget_shift.never }}
Next round, built on your winner
{{ fsMem.results.refine[c.campaign_id].recommendations.next_round.why }}
{{ fsMem.results.what }}
{{ fsMem.campaign.error }}
✓✗ {{ c.label }}
{{ c.detail }}
{{ c.fix }}
Everything is ready. Here is where it goes.
Open {{ fsMem.campaign.handoff.open_here.label }} →{{ fsMem.campaign.handoff.open_here.note }}
Download the creative
Paste blocks
{{ String(key).replace(/_/g, ' ') }}
{{ val }}
Then, in order
Before you spend anything — install tracking
{{ fsMem.campaign.handoff.tracking.where_to_paste }}
{{ fsMem.campaign.handoff.tracking.snippet }}
{{ fsMem.campaign.handoff.tracking.get_pixel_id.label }} → — {{ fsMem.campaign.handoff.tracking.get_pixel_id.how }}
{{ fsMem.campaign.handoff.tracking.conversion }}
{{ fsMem.campaign.handoff.tracking.what_we_see }}
{{ fsMem.campaign.handoff.never }}
Reading what fits you…
{{ fsMem.error }}
Nothing that fits your constraints right now.
{{ fsMem.constraintCount }} thing{{ fsMem.constraintCount === 1 ? '' : 's' }} you ruled out {{ fsMem.constraintCount === 1 ? 'is' : 'are' }} being honoured. Ask for more when you want a fresh pass.
{{ planDrift.drift.suggested_plan }}
{{ planDrift.drift.note }}
Biggest drop: {{ planDrift.drift.bottleneck }}
Seed posts approved: {{ driftSeedConversion().approved }} of {{ driftSeedConversion().created }}
{{ c.unlocks }}
No drift check yet.
{{ formatDrawer.m ? (formatDrawer.m.title || 'this moment') : 'Reading this moment…' }}
Reading it now…
{{ formatDrawer.error }}
{{ formatDrawer.m.title }}
{{ formatDrawer.m.why_it_matters }}
{{ formatDrawer.m.source || 'your own work' }} · {{ fmt(formatDrawer.m.created_at) }}
Who decides how this is shown
What it should look like
Showing it as
{{ formatChoice(formatDrawer.m).label }} · {{ formatChoice(formatDrawer.m).mine ? 'your call' : 'FoxSense’s call' }}
{{ formatChoice(formatDrawer.m).reason }}
Saved. Writing the reason for this format…
What happens next
Nothing gets made. Held moments stay off the board and no draft is written for them. Choose a format above if you want something made from it.
This one can be made now, from {{ shotAvail[formatDrawer.m.id].source }}. You get the real screenshot with a caption in your own words — and a callout box only where the walkthrough recorded a confident one. No box is invented.
An annotated shot needs a real screenshot of your product, and there isn't one — {{ (shotAvail[formatDrawer.m.id] && shotAvail[formatDrawer.m.id].why) || 'nothing has been captured for this project yet' }}. Nothing will be faked to fill the gap. The branded card is what can be made instead, and the button below makes that.
Nothing downstream reads this choice yet. Two makers exist — the branded card, and the annotated shot for the Annotated shot choice — and neither is driven by {{ formatChoice(formatDrawer.m).label }}. The button below makes the branded card.
Annotated shot
Branded card
Making visuals is on Pro. Your format choice is still recorded.
{{ visualMsg[formatDrawer.m.id] }}
Nothing is posted from here. Choosing a format only decides how it gets shown.
{{ connectDrawer.lead }}
Where your posts go
You have not chosen any channels yet.
{{ chanLabel(ch.key) }}
Connected ✓ You post this one This oneWhere your work comes from
{{ tk.name }}
Connected ✓ Not syncing This one{{ tk.title }}
{{ itokIssue[tk.key].reason }}
{{ itokResult[tk.key].text }}
{{ ITOK_EXISTING_ONLY_NOTE[tk.key] }}
Want somewhere else? — a channel you have not chosen is never posted to.
Close this and you are back on the board, exactly where you were.
{{ foxsense.offer.actionText }}
Writing it now…
{{ foxsense.offer.error }}
One update → a post or thread. Pick a format, generate, edit & post.
Promo + launch films, every ratio.
Shareable images from a win or a Library image.
Looping GIFs from images or a video's ending.
Transparent stickers for Giphy, iMessage, Slack.
One update → a full long-form article.
Write release notes → your public changelog.
This moment looks press-worthy — pitch it?
The moment · {{ pressCardTypeLabel(pressWorthyMilestone) }}
{{ milestoneHeadline(pressWorthyMilestone) || pressWorthyMilestone.title }}
{{ pressCardSubline(pressWorthyMilestone) }}
Weekly shipped pages you follow
{{ currentShareView.tip }}
Connect a source or log a win to begin.
You're shipping — nothing's risen to share-worthy yet. Keep going; we'll glow a card the moment something does.
{{ projectProgressLine }}
{{ milestoneHeadline(m) }}
{{ m.why_it_matters || m.description }}
{{ m.why_it_matters }}
▶ Video ready — open page · also in your Studio
Still rendering — it'll appear in your Studio shortly.
{{ visualMsg[m.id] }}
Text
Visual
Threads
{{ formatDecline(m).headline }}
{{ formatDecline(m).reason }}
GIFs are a Serial feature
Turn your work into branded looping GIFs — from an image, a few images, or a video's ending — ready to share to the GIF networks behind Slack, Discord, Facebook, and iMessage, so people see your product again and again before they ever reach your site.
Serial also gives you:
Make a {{ pickerNoun }} — pick a source.
From your Library
— none yet
From a visual-worthy win
— none yet
{{ projectHasMilestones ? 'Nothing here yet — add an image or clip in your Library, or ship a launch / milestone.' : 'No wins logged yet in this project. Add an asset in your Library, or log a win.' }}
GIF Studio
Turn an image into a typewriter-caption GIF for the pickers in X, Slack, Discord & more.
Why upload your GIF to Giphy?
Uploaded and tagged on Giphy, your GIF gets indexed on Giphy and Tenor — the same libraries that power the GIF pickers in Slack, Discord and LinkedIn. That means it keeps resurfacing in those pickers for months, quietly earning passive reach long after you posted it.
Read the guide →Source
No source yet — make a GIF from a video ending or a Library image.
…or pick one you own
{{ gifStudio.caption.length >= 24 ? 'Max length reached — 24 characters.' : ((24 - gifStudio.caption.length) + ' characters left (max 24).') }}
Every account gets the same 20-tag limit — checking this does not change the count. What verification changes is REACH: only verified Brand/Artist channels get indexed in GIPHY's own search and the Facebook, Instagram & WhatsApp GIF pickers. Apply for a GIPHY channel ↗
Tags appear here automatically once you render the GIF — then add or remove any.
{{ gifTagWarning }}
GIPHY hard-caps tags at 20 — 10-15 accurate ones work best; padding to the max can hurt reach (GIPHY demotes GIFs shown on searches they don't match). Tags upload the same for any account; a verified channel is what gets the GIF indexed in GIPHY search + the Facebook, Instagram & WhatsApp pickers.
Preview
Image Studio
Make a clean, branded card — a metric or milestone that looks valuable, in every ratio your channels need.
Source (optional — text-only works too)
…or pick one you own
{{ imageStudio2.useBranding ? ('On — your logo + colours from ' + ((activeProject && activeProject.name) || 'your domain') + '.') : 'Off — neutral style, no brand logo or colours.' }}
{{ imageStudio2.headline.length >= 48 ? 'Max length reached — 48 characters.' : ((48 - imageStudio2.headline.length) + ' characters left (max 48).') }}
{{ imageStudio2.subline.length >= 80 ? 'Max length reached — 80 characters.' : ((80 - imageStudio2.subline.length) + ' characters left (max 80).') }}
{{ imageStudio2.altText.length >= 120 ? 'Max length reached — 120 characters.' : ((120 - imageStudio2.altText.length) + ' characters left (max 120).') }}
{{ imageStudio2.error }}
Preview
Sticker Studio
A punchy transparent sticker from your image or logo — for the pickers in Slack, Discord, iMessage & Giphy.
What are stickers for?
Two jobs: branded reactions everyone can drop into your Slack and Discord once the pack is installed, so your product shows up in day-to-day chat. And launch-day polish — die-cut, transparent stickers that dress up your launch posts and changelog instead of looking like pasted screenshots.
Read the guide →Source
…or pick one you own
Tip: a transparent PNG or logo gives the cleanest sticker. Background removal lands in a later version.
{{ stickerStudio.caption.length >= 16 ? 'Max length reached — 16 characters.' : ((16 - stickerStudio.caption.length) + ' characters left (max 16).') }}
Tags appear here automatically once you render the sticker — then add or remove any.
{{ stickerTagWarning }}
GIPHY: max 20 tags, ~10 recommended. Tags require a verified Brand/Artist channel to work — and for the sticker to appear in Facebook, Instagram & WhatsApp search.
{{ stickerStudio.error }}
Preview
Log a win
Something you shipped or achieved that we can't see from your code — a first customer, a mention, a milestone.
Win logged ✓
It's in your Milestones. Want to turn it into a post — in your own words?
Longform
Turn one update into a full long-form article — it lands in Drafts to edit & publish.
The article is written only from this update — your own words, notes and proof.
No updates in this project yet — log a win, or paste your own post above.
Already wrote it? Paste it here and we still handle the hard part — publishing to your main, then walking you through each reprint with the canonical tag set, so Google credits your main and the copies don't split your SEO.
Short-form posts
Turn one update into a short post or thread — then edit & use it in Drafts.
No updates in this project yet — log a win first.
Format
{{ f.label }}
{{ f.tip }}
Generated posts land in — edit, copy and post them there. Nothing posts itself.
Share this win
{{ milestoneHeadline(shareSheet) }}
{{ card.heading }} · {{ card.platLabel }}
Posted ✓LinkedIn deserves a proper long write-up, not a tweet — none written yet.
{{ card.text }}
Post these in order — copy {{ card.noun.toLowerCase() }} 1, post it, then reply with {{ card.noun.toLowerCase() }} 2, and so on. Nothing posts on its own.
{{ t }}
Video link
{{ cardState[shareSheet.id].vpage }}
Turn this into a blog post
A full write-up from this moment — yours to publish anywhere.
Optional — leave blank and we generate from the moment itself. Feeds the LinkedIn and blog write-ups.
Your share options
{{ optionsKit.m ? (milestoneHeadline(optionsKit.m) || optionsKit.m.title) : '' }}
Preparing your options…
Writing your posts and making your image, GIF and sticker. The video is a separate button — it doesn't start on its own.
Visuals
Image
GIF
Sticker
{{ optionsKit.visualMsg || 'No visuals prepared for this update.' }}
Saved to your Library and attached to this update — download or refine any of them in its Studio.
Text posts
{{ d.content }}
No posts came back — add a little more detail to this update, then prepare again.
Edit & use the text in . Nothing posts itself.
{{ readyPanel.items.length }} ready to {{ readyPanel.kind === 'short' ? 'post' : 'make' }}
Pick an update — the {{ readyPanel.kind === 'short' ? 'composer' : (readyPanel.kind === 'gif' ? 'GIF Studio' : (readyPanel.kind === 'sticker' ? 'Sticker Studio' : 'Image Studio')) }} opens loaded with it.
{{ milestoneHeadline(m) || m.title }}
{{ milestoneSubtitle(m) }}
{{ todaySummary }}
Your next moves for {{ (activeProject && activeProject.name) || 'this project' }}.
Shipped something, or hit a milestone we can't see from your code — a first paying customer, a press mention? Log it in your own words.
{{ coach.insight }}
{{ reachStats.data.embed_loads.last_30d }} / {{ reachStats.data.embed_loads.all_time }}
GIF-widget loads
{{ reachStats.data.sig_loads.last_30d }} / {{ reachStats.data.sig_loads.all_time }}
Email-signature views
{{ reachStats.data.build_views.last_30d }} / {{ reachStats.data.build_views.all_time }}
Build-log views
{{ reachStats.data.gifs_made }}
GIFs made
{{ reachStats.data.stickers_made }}
Stickers made
{{ reachStats.data.changelog_impressions }}
Changelog impressions
Where two numbers show: last 30 days / all time.
Connect your repo to unlock
Your GitHub or GitLab repo is the ship/commit signal we turn into posts, images and more. Connect one and your shipped work starts flowing in — until then there's nothing for us to turn into content.
You're caught up 🎉
Ship something and it'll show up here, ready to share.
Share to your channels
Push a recent ship into your connected chat.
Finish setting up distribution {{ distributionRemaining }} left
Connect what feeds each output — we only suggest what we can actually deliver for you.
{{ c.label }}
{{ c.names }}
{{ c.why }}
Moments from your work that may be worth sharing.
You're connected — nothing new to share since we last checked your work.
You're connected — pull your work in to get started.
As soon as you ship something new, it shows up here on its own. You don't have to do anything.
A tool is connected. Open Settings and click Pull in latest to bring your recent work in.
Nothing here yet
Captures are the moments from your work that may be worth sharing — pulled in from the tools you build with, or added by hand. Connect a tool in Settings to fill this in.
{{ c.raw_text }}
{{ humanize(c.source) }} · {{ fmt(c.captured_at) }}
Captures rolled up into stories worth telling. Turn one into a short post, or group several into a long-form story.
No milestones in {{ (activeProject && activeProject.name) || 'this project' }} yet
Milestones are your captures grouped into stories worth telling. They appear on their own as new work comes in — we check every 15 minutes. Connect a tool or add a capture to get the first one.
Distribute this ship — {{ milestoneHeadline(m) }}
{{ a.label }} ({{ a.handle }})
{{ platformCaption(m, a.key) }}
Blog cross-post
Canonical points home — search engines still credit your original; you just gain reach.
Get discovered on Giphy
Add a little more detail to this milestone and .
What people type into the GIF box in Slack, Discord, Facebook — not hashtags.
Paste this as the GIF's source link so every use sends people to your site.
Download your GIF, open an uploader, and paste the title, tags, and source link.
Add a little more detail to this milestone and .
Upload the GIF, paste your Source URL, and add these tags — that's how it gets found on Giphy and carries your link.
1. Create an account at https://giphy.com/join ↗ (use your work email/domain if you can).
2. Add your logo, a short bio, and your website.
3. Upload 5 GIFs first — Giphy wants to see real content before it lists your channel.
4. Apply for a Brand Channel: https://support.giphy.com/hc/en-us/articles/360019977992-Apply-For-A-Brand-Channel ↗
5. Giphy's review takes a few days (sometimes up to two weeks). Until it's live, your GIFs won't appear in anyone's GIF picker.
6. Per GIF: paste the title, up to 20 tags (we provide them), and your website as the Source URL. New uploads can take up to 24h to show in search.
Specs we already match: loops, under 15s, under 8MB, 480p. (Stickers need a transparent background — coming soon.)
{{ milestoneHeadline(m) }}
{{ milestoneSubtitle(m) }}
{{ m.title }}
{{ m.description }}
{{ m.why_it_matters }}
Not worth a post on its own — bump it up if it actually matters.
{{ formatChoice(m).isHeld ? formatChoice(m).label : 'Best shown as: ' + formatChoice(m).label }}✍️ This looks significant — want a long-form write-up too?
Here's what I could write:
{{ longFormSuggestion(m).title }}
Primed ✓ — open your product and click your Record bookmarklet to start (titled “{{ walkthroughPrime.title || 'your walkthrough' }}”).
🎬 You shipped something — make a walkthrough of it?
{{ walkthroughQuotaRemaining }} of {{ walkthroughQuota.cap }} walkthrough{{ walkthroughQuota.cap === 1 ? '' : 's' }} left this month. Your free plan keeps one walkthrough, and it is in use. Upgrade to keep more. You've used your walkthroughs this month — upgrade for more.
📎 Lands better with a screenshot or metric — attach one
No assets in this project yet — use “Upload new”, or add some in Settings → Assets.
Image attached — this post is image-primary.
Make visuals
{{ visualMsg[m.id] }}
Add a visual platform to unlock images & videoNot a visual moment — visuals land for launches, big milestones, striking numbers, or a new look, not routine ships and fixes.
Send to chat
Match your latest milestone to the outlets most worth pitching — for {{ (activeProject && activeProject.name) || 'your project' }} — bloggers and podcasters first, journalists when you've got a bigger hook. Every pitch is a draft you review and send yourself. Or answer inbound requests from journalists looking for sources right now.
These are journalists asking for sources right now. Matches for your beats lead the list, then the soonest deadlines. Answer one before it closes — you draft the reply, we never send it for you.
{{ getPress.inbound.error }}
No open requests right now
New journalist requests come in daily once your press-request subscriptions are confirmed. Check back tomorrow, or widen your beats above to catch more.
{{ getPress.inbound.items.length }} open request{{ getPress.inbound.items.length === 1 ? '' : 's' }} — matches for your beats first, then soonest deadline. Each reply is a draft for you to review.
{{ r.outlet }} · {{ r.beat }}
{{ r.query_text }}
Tap Refresh requests to load the open requests journalists have posted. New ones arrive daily once your subscriptions are confirmed.
Reading your site to understand your project…
🔎 {{ getPress.outlets.beats.summary }}
{{ getPress.outlets.error }}
{{ row.outlet || 'Blog' }} · {{ row.name }}
{{ row.outlet || 'Show' }} · {{ row.name }}
Land 2 wins with bloggers or podcasters to unlock. They say yes fastest — a couple of wins builds the track record journalists look for. ({{ getPress.outlets.progress.wins }} of 2)
{{ row.outlet || 'Outlet' }} · {{ row.name }}
To {{ (getPress.press.pitch.jrn && getPress.press.pitch.jrn.name) || 'the journalist' }} · {{ getPress.press.pitch.jrn.outlet }}
🔒 Marked embargoed. Preview only — FoxPlug never sends. Copy it or open it in your own mail app.
Opens your own mail app — nothing is sent from FoxPlug.
To {{ (getPress.reply.req && getPress.reply.req.journalist_name) || 'the journalist' }} · {{ getPress.reply.req.outlet }}
🔒 Preview only. FoxPlug never sends — copy this or open it in your own mail app and send it yourself.
Opens your own mail app — nothing is sent from FoxPlug.
To {{ (getPress.outlets.pitch.row && (getPress.outlets.pitch.row.outlet || getPress.outlets.pitch.row.name)) || 'this outlet' }} · {{ getPress.outlets.pitch.tier }}
🔒 Preview only. FoxPlug never sends — copy this, or open the outlet's form / your mail app and send it yourself.
You review and send it yourself — FoxPlug never sends on your behalf.
Adds to the shared FoxPlug list — it helps every founder here (and you).
Added to the shared FoxPlug list — helps every founder here.
{{ getPress.outlets.add.error }}
{{ getPress.outlets.win.row.outlet || getPress.outlets.win.row.name || 'this outlet' }}
A win needs a public link that mentions your project. We verify it, then it counts toward unlocking Journalists.
Paste the link to the published post / episode / article.
{{ getPress.outlets.win.error }}
One click sends you straight to X or LinkedIn with your post ready to go. Connected channels can post on their own. Nothing ever goes out until you click.
Hang tight — it'll appear right here when it's ready. You can keep working in the meantime.
Your sources are connected. We'll make a video about what you've already shipped.
Connect the tools that show your progress and we'll turn your shipped work into a launch video — {{ welcomeAd.connected_count }} of {{ welcomeAd.needed || 2 }} connected so far.
Make a video for any site
Paste a company's web address and we'll make a short, branded teaser about them — a warm way to open outreach. You get a link to send that plays with their own call-to-action.
{{ prospectAd.error }}
{{ prospectAd.message || ('Tell us what ' + (prospectAd.name || 'they') + ' does and we’ll make the video.') }}
Making your video{{ prospectAd.name ? (' for ' + prospectAd.name) : '' }}…
This takes a moment — it'll appear right here when it's ready. No need to wait around.
Ready to send{{ prospectAd.name ? (' — ' + prospectAd.name) : '' }}
What to offer them
{{ lure.reason }}
This is the safe default, not a recommendation — answer the two questions in your kit and it moves on its own.
{{ t.why_not }}
Why not {{ lure.declining.label }}? It is more useful to us than the choice would have been.
Your message, before it goes anywhere
Nothing sends on its own. Edit any of it, then save and copy — it is written to your outreach log first.
Saved to your outreach log, under this project. Paste it into your own mail when you are ready.
Handed over and opened in a new tab. {{ lure.foundAt }}
Your prospect videos
{{ generatedNotice }}
It's highlighted below. Review it, then click Looks good to choose where it goes — nothing is posted until you do.
No drafts in {{ (activeProject && activeProject.name) || 'this project' }} yet
Drafts are ready-to-post updates written from your milestones. Open a milestone and generate a post, then edit, copy and publish it here.
Milestone
{{ groupHeadline(g) }}
{{ groupCountLabel(g) }}
Text
Visual
Threads
{{ nextStepLine(d) }}
Live preview
{{ displayContent(d) }}
Last attempt: {{ targetOf(d).error }}
Where do you want it?
Nothing posts itself — everything's yours to use. Every link below is a manual copy, open or paste.
Canonical: {{ canonicalValue(d) }}
Post it — pick a destination
LinkedIn pastes manually — it dropped composer pre-fill.
{{ linkedinHint[d.id] }}
Posted it somewhere? Paste the live links.
Once any link is in, use Mark as posted above to finish.
We publish a copy with a canonical link back to your original, so search engines still credit you — you just get the extra reach and backlinks.
Cross-post, guided · main: {{ mainBlogLabel }}
{{ xpDoneCount(d) }} / {{ xpConnectedCount(d) }} done
Publish the original on your main ({{ mainBlogLabel }}) first, then paste its URL into Canonical home above — every reprint will point back to it.
No reprint platforms connected yet — tick the blogs you post to in and they'll queue up here in order.
All cross-posts done ✓ — every reprint points its canonical to your main.
Next: {{ CROSSPOST_META[k].label }} →
{{ CROSSPOST_META[xpNext(d)].label }}
In {{ CROSSPOST_META[xpNext(d)].label }}'s post settings, paste this into the Canonical URL field — Google keeps crediting your main.
On Medium, use Import a story from your main's URL — Medium sets the canonical to your main for you:
{{ CROSSPOST_META[xpNext(d)].label }} can't carry a canonical tag — a full duplicate here could compete with your main. Post an excerpt + a link to your main instead (the body above is already trimmed to that).
{{ crosspostProviderLabel(prov) }}: {{ crosspostResult[d.id][prov].error }}
Want Bluesky, Mastodon or Telegram too? .
Want it on dev.to too? .
Post it yourself — prefilled where the platform allows, copy-and-paste where it doesn't
Review, tweak, post — from your own profile, one click each.
This week's progress ({{ weekMilestones.length }} milestone{{ weekMilestones.length === 1 ? '' : 's' }})
No milestones in the last 7 days yet — connect a tool to start.
Latest digest score: {{ latestDigest.score }} · {{ digestTrend() }}
Per-platform posts are a Pro feature
Free includes the weekly digest above. Pro turns every milestone into ready-to-post LinkedIn, X, and blog drafts with one-click self-posting.
See ProNothing to post yet
Connect a tool and generate a post from a milestone — it shows up here, ready for each platform.
{{ (d.milestone && d.milestone.title) || (d.content || '').split('\n')[0].slice(0, 70) }}
{{ p.tone }}
{{ prepFor(d, p.key) }}
LinkedIn can't fill the text in for you — copy it, open the composer, and paste.
Publish, one place at a time — {{ broadcastSummary(d) }}
Your logo, colours, fonts and voice — used across every video for this project. Switch the active project at the top to set up another.
Pull from my domain
We fetch your logo and pull a colour palette from it automatically. Anything you've set by hand is left untouched.
Logo
Upload a light-background and a dark-background version. We pull your colours from the light one.
Company colours
Auto-filled from your logo — tweak any swatch. Used for captions, callouts and the endcard.
{{ sw.role }}
Ad palette
A separate palette just for ads — starts from your company colours, change any swatch to make ads pop without touching your brand kit.
{{ sw.role }}
Fonts
A display font for headlines and a body font for everything else.
Every video is white-label — only your brand shows, never FoxPlug.
A short, scroll-stopping promo — only your brand on screen. Everything's pre-filled; the simple screen alone is shippable.
Style
Format
Length
{{ (ad.hook_text||'').length >= 80 ? 'Max length reached — 80 characters.' : ((80 - (ad.hook_text||'').length) + ' characters left (max 80).') }}
Endcard
Uses your brand kit only. If your logo is missing it simply shows nothing.
A guided product tour. Pick a style and go — voice and language come from your brand kit. Or generate from your URL →
Style
{{ (createVid.site || '').trim() ? ('Titles the intro: “A walkthrough of ' + createVid.site.trim() + '”.') : 'Blank → the intro just says “A walkthrough”. Type the site you\'re recording to name it.' }}
Every walkthrough is white-label — only your brand, never FoxPlug. You'll add narration (optional) after recording.
You'll pick which tab to demo, then get a 5-second countdown to switch to it. Pause, add callouts and finish from the floating controls.
{{ rec.phase==='uploading' ? 'Saving your recording…' : 'Rendering your video…' }}
{{ rec.phase==='uploading' ? 'Storing the capture securely — this stays open.' : ('Applying your style, narration & brand' + (rec.eta ? ' — about ' + recEtaLabel + ' left' : '') + '.') }}
{{ rec.renderError ? 'Your recording + text are safe — retry the render' : 'Your recording is ready 🎬' }}
Add narration in your own words, or leave it blank for a clean, silent video. Nothing is ever written for you.
{{ rec.callouts.length }} callout{{ rec.callouts.length===1?'':'s' }} kept from your recording.
{{ (createVid.narration || '').trim() ? (createVid.speak ? 'Shown as captions and spoken aloud.' : 'Shown as captions (no voiceover).') : 'Blank → a clean, silent styled video (style + title + end card). No captions, no voiceover.' }}
Your walkthrough is ready 🎬
Shareable page: {{ rec.result.share_url }}
This is why you record in FoxPlug — one recording becomes a whole kit. Nothing generates until you ask.
{{ rec.repurpose.error }}
GIF highlights
Stills
Sticker set
{{ rec.writeup.error }}
Tell us what you showed first
We write the {{ rec.writeup.promptFor === 'blog' ? 'blog post' : 'social posts' }} only from your own words — no invented features or claims. Add the steps you walked through:
Social posts
Recording didn't finish
{{ rec.error || 'Something went wrong.' }}
Make images and GIFs from your breakthroughs, then post them in one tap.
New visual
Pick a milestone, choose an image or animation, and we'll make it.
Suits your connected: {{ postTargetsFor(imageStudio.kind).map(a => a.label).join(', ') || 'your channels' }}
A looping GIF from an image, a few images, or a video's ending — white-label, ends on your logo.
{{ visualMsg[imageStudio.milestone_id] }}
Add a visual platform to unlock the studioSticker pack (Stipop)
A branded reaction pack — ~24 transparent animated stickers from real founder moments, ready for the Stipop keyboard.
Your latest pack — {{ stickerPack.latest.sticker_urls.length }} stickers
Upload to Stipop (one-time):
A pack needs 10–30 stickers (PNG or GIF, transparent). Open https://studio.stipop.io ↗, create a pack, drag all the stickers in, add one bulk tag for the pack, then a few per-sticker tags (the caption words work), and submit for review. Once it's accepted it appears in the Stipop sticker picker.
Embed your latest ship
Drop this on your site — it auto-updates to your newest GIF or sticker, linked to your build log.
The embeddable widget is a Serial feature.
Email signature
An image for your email signature that always shows your newest sticker.
Paste this into your Gmail or Outlook signature settings.
The email-signature image is a Serial feature.
No images or GIFs yet
No visuals yet — hit "Make an image" above or on any breakthrough and it'll appear here.
{{ v.title }}
Add a little more detail to this milestone and .
Giphy GIF
{{ gifMeta[v.id].title }}
Source: {{ ctaLink() || 'add your site in Settings' }}
Giphy Sticker
Make a video — two ways
Pick one. Both render in every ratio your channels need.
Generate a promo video
A short promo from one shipped milestone, or a 30-second product launch video from several — rendered in every ratio your channels need.
Nothing to build a video from yet
Record a walkthrough of your product, log a win, or upload a screenshot or clip — then generate a video from it right here.
No ships logged in the last 7 days yet — your weekly recap appears once you've made progress this week.
Create a launch video for {{ (activeProject && activeProject.name) || 'your product' }}
A ~30-second launch film built from your site — no setup needed. White-label: your brand only, no FoxPlug mark.
No ships in {{ (activeProject && activeProject.name) || 'this project' }} yet — the launch builds from your site.
{{ videoStudio.launchIds.length }} selected
Music
We'll make: 9:16 for Instagram & TikTok · 1:1 for Instagram / LinkedIn · 16:9 for YouTube & LinkedIn
Promo videos are a Pro feature.
Promo videos are a Pro feature.
{{ videoStudio.error }}
{{ renderProgressLine }}
{{ v.title }}
Your videos
Your videos now live in your Library
Generate above — then watch, download and share every video (alongside your GIFs, stickers and more) in your .
{{ videoTitle(videoModal) }}
Share
{{ videoSharePageUrl(videoModal.share_token) }}
Paste this link wherever links are allowed — it has your clickable button, tracks clicks, and shows your cover. Upload the MP4 only where links aren't allowed.
{{ reviewTitle(reviewModal) }}
Save it to your Library, copy the link, download it — or ask for changes.
The raw materials — brand, images and sound — we draw from to make your videos and posts.
Brand
No brand kit yet — add your site in Settings and we'll pull your logo, colours and font, or set them in the tab.
Your words — reused in your posts
“{{ w }}”
Uploads
{{ (activeProject && activeProject.name) || 'This project' }}Your logo, screenshots and brand images for {{ (activeProject && activeProject.name) || 'this project' }}. Attach one to a milestone to make a post image-primary — it lands far better with a picture or a metric.
We found your logo
Add it to your library so it's ready to attach to posts.
A description is incredibly important — it gives us the context to craft better videos, images, and GIFs for you.
No uploads in {{ (activeProject && activeProject.name) || 'this project' }} yet. Upload a screenshot or import your logo above.
Sound
Background music, narration voice and language we use on your videos.
Nothing set yet. Choose a default voice, language and music for this project in the tab, or pick per-video options when you generate in the Library.
Looking for badges, feeds and cross-posting? They live in the tab.
Things you keep on purpose — your company story, repurposing and inspiration — plus everything that has aged out of your active wins or already been shared.
Saved videos
Nothing saved yet — save a walkthrough or launch video from its download and it lands here.
Images
No images here{{ libCampaign ? ' in this campaign' : ' yet' }}.
{{ milestoneHeadline(m) }}
GIFs
No GIFs here{{ libCampaign ? ' in this campaign' : ' yet' }}.
{{ milestoneHeadline(m) }}
Stickers
No stickers here{{ libCampaign ? ' in this campaign' : ' yet' }}.
{{ milestoneHeadline(m) }}
Videos
No videos here{{ libCampaign ? ' in this campaign' : ' yet' }}.
{{ milestoneHeadline(m) }}
Walkthroughs & launch videos
Short-form
No short-form content here{{ libCampaign ? ' in this campaign' : ' yet' }}.
{{ milestoneHeadline(m) }}
{{ m.description || m.why_it_matters }}
Long-form
No long-form content here{{ libCampaign ? ' in this campaign' : ' yet' }}.
{{ milestoneHeadline(m) }}
{{ m.description || m.why_it_matters }}
Saved
Nothing saved yet. Soon you'll be able to keep a win here for your company story, to repurpose, or for inspiration.
Archive
{{ archivedItems.length }}Auto-archived after they age out — small wins after 5 days, major milestones after 15 — and anything you've shared lands here too.
{{ milestoneHeadline(m) }}
{{ m.why_it_matters || m.description }}
Get your ships in front of more people, in more places — set up the doors that fit {{ (activeProject && activeProject.name) || 'this project' }}.
Put your ships on your GitHub profile
Puts a "Recently shipped" list on your GitHub profile page. Where it shows: the top of github.com/your-username — anyone who visits your profile sees your latest ships. Your GitHub may be run by a no-code tool — this is a separate, special repo just for your profile page; set it up by hand once (2 minutes).
Using your connected GitHub: @{{ githubAccountLabel }}
{{ ghReadmeSnippet }}
{{ ghProfileUsername || 'your-username' }}, choose Public, tick “Add a README file”, click Create repository.
Want to refresh it later? Come back, copy again, and re-paste.
List on AlternativeTo
Lists your product on AlternativeTo. Where it shows: AlternativeTo search results when people look for "alternatives to {a tool}" — high-intent strangers discover you. We prep everything; you paste and submit.
Add a little more about your product (name, URL, one-liner) and .
This is an alternative to:
{{ crossPostSectionTitle() }}
Republishes your long-form posts to the writing platforms you have connected, in one tap. Where it shows: those profiles and their feeds — their readers see your write-up, with a canonical link back so your original keeps the SEO credit.
dev.to
Connected{{ crosspostConn('devto').username ? ' (@' + crosspostConn('devto').username + ')' : '' }} ✓ Not connected{{ crosspost.devtoErr }}
Get your key: dev.to → Settings → Extensions → DEV API Keys (dev.to/settings/extensions).
Hashnode
Connected{{ crosspostConn('hashnode').username ? ' (@' + crosspostConn('hashnode').username + ')' : '' }} ✓ Not connected{{ crosspost.hashnodeErr }}
We couldn't find a Hashnode publication on your account — create one on Hashnode first.
Get your token: Hashnode → Settings → Developer → Generate new token (hashnode.com/settings/developer).
Discord / Slack ship feed
Posts each ship straight into a Discord or Slack channel. Where it shows: the channel you pick — your community/team sees the update the moment it ships. Drop a webhook URL, no bot or code needed.
Discord
Connected ✓ Not connected{{ webhooks.discordErr }}
In Discord: your channel → Edit Channel → Integrations → Webhooks → New Webhook → Copy Webhook URL.
Slack
Connected ✓ Not connected{{ webhooks.slackErr }}
Create one at api.slack.com/messaging/webhooks, pick the channel, copy the URL.
RSS feed + embed widget
An always-fresh feed of your published ships. Where it shows: anywhere that reads a feed — RSS readers, Zapier automations, or embedded on your own site so visitors see your updates.
{{ feedRssUrl }}
{{ feedJsonUrl }}
{{ changelogEmbedSnippet }}
Your feed turns on once your build log is live.
“Building in public” badge
This is a small badge you paste on your site or README. It links visitors to your public build log on FoxPlug. Copy it, paste it where you want, and anyone who clicks sees your shipped updates.
The link goes to: {{ spreadBadgeUrl }}
It links to your public build log (live once you publish a changelog entry).
{{ badgeMarkdown }}
{{ badgeHtml }}
{{ spreadBadgeUrl }}
Your badge links to your build log.
Write a release note and publish it to your public changelog page. Nothing goes public until you press Publish.
This project has no public address yet, so there's nowhere to publish. Add one in first.
Your public page: {{ changelogPageUrl }} ↗
Import my existing changelog
Already keep release notes somewhere? We'll read them and bring them in as drafts. Nothing goes public — you keep the ones you want and delete the rest.
{{ clImportResult.text }}
{{ clImported.length }} imported entr{{ clImported.length === 1 ? 'y is' : 'ies are' }} waiting below — none of them are public.
Build it from what you've already shipped
Your milestones are already captured and scored. We'll draft release notes from the ones worth talking about — you read them, tick the ones you want, and publish those. Nothing is published until you do.
{{ clBf.error }}
{{ clBf.eligible }} past release{{ clBf.eligible === 1 ? '' : 's' }} ready to publish, {{ clBf.proposals.length }} drafted below.
{{ clBf.note }}
Nothing on this list is public until you press that button.
Make it yours
ProPut it on your own site
Drop this in your site's HTML and your published entries show up there. Entries limited to a plan stay hidden from anyone who isn't on it.
{{ changelogEmbedSnippet }}
Give this project a public address in Settings and your snippet appears here.
Your changelog page is live and free to use. Pro puts your brand on it — your name, logo and colour instead of the standard look — adds the snippet that drops it onto your own site, and lets you limit an entry to people on a chosen plan.
{{ clForm.id ? 'Edit entry' : 'New entry' }}
Pick at least one plan, or this entry reaches nobody but you.
{{ clMsg }}