{{ toast.msg }} βœ•

Domains

{{ projects.length }}/{{ projectCap }} used on your {{ planLabel }} plan Β· {{ paidExtraDomains }} add-on{{ paidExtraDomains === 1 ? '' : 's' }} (${{ paidExtraDomains * 15 }}/mo)

Current

{{ p.url || 'No URL set' }}

Preparing brand kit…

{{ projects.length }} of {{ projectCap }} domain{{ 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 Broadcast' : "You're at your domain limit" }}

{{ currentPlan === 'free' ? 'Your Free plan includes 1 domain. Upgrade to add this domain.' : ('Your ' + planLabel + ' plan includes ' + projectCap + ' domain' + (projectCap === 1 ? '' : 's') + '. Upgrade to a plan with more.') }}

See all plans β†’

Billed by Stripe. Manage or cancel any time in Settings β†’ Subscription.

This is your {{ ordinal(projects.length + 1) }} domain

Your {{ planLabel }} plan includes {{ planBaseDomains }} domain{{ planBaseDomains === 1 ? '' : 's' }}. Adding this one is an extra-domain 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 domain later and the add-on decrements automatically.

Set a new password

Choose a new password for your account.

{{ (newPassword.length > 0 && newPassword.length < 6) ? ('Too short β€” at least 6 characters (' + newPassword.length + '/6).') : 'At least 6 characters.' }}

{{ auth.error }}

{{ auth.notice }}

{{ auth.mode==='password' && auth.intent==='signin' ? 'Welcome back' : 'Create your account' }}

Your build-in-public sidekick.

{{ (auth.password.length > 0 && auth.password.length < 6) ? ('Too short β€” at least 6 characters (' + auth.password.length + '/6).') : 'At least 6 characters.' }}

Enter your email and we'll send a link to set a new password.

{{ auth.error }}

{{ auth.notice }}

{{ projects.length }}/{{ projectCap }}
Voice:
Launch stage:
Nothing posts itself

{{ banner }}

You're on {{ planLabel }} β€” nice. πŸŽ‰

A few things worth setting up now to get the most out of it:

  • 1. Run another product from the same place β€” your {{ planLabel }} plan includes {{ projectCap }} project{{ projectCap === 1 ? '' : 's' }}.
  • {{ atProjectCap ? '1' : '2' }}. Set up your passive, easy pipelines to massive exposure. Read more
  • {{ atProjectCap ? '2' : '3' }}. Set up your Walkthrough CTA end screen in Settings β€” it's per project, so each product gets its own call-to-action.

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.

What are you building in?

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 }}

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.

Or set up by pasting your product address instead

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.

Let's get FoxPlug telling your story

{{ WIZARD_STEPS[wizardStep - 1].blurb }}

Step {{ wizardStep }}/4

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 }}

Prefilled from your page Review and edit anything below.
Detected logo {{ wizard.logo_url ? 'Logo' : '' }}{{ wizard.logo_url && wizard.brand_color ? ' + ' : '' }}{{ wizard.brand_color ? ('brand colour ' + wizard.brand_color) : '' }} detected.

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.

  • β€œ{{ ex }}”

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.

{{ u.done ? 'βœ“' : 'β—‹' }} {{ u.label }} {{ u.need }} Unlocked

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.name }} Connected βœ“

{{ t.scopeHint }}

Coming soon for your stack β€” we know you want these

{{ t.name }} Β· soon

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 }}

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.

β–Ά YouTube connection needs re-authorization

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 }}.

Get the most out of FoxPlug

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.

Get your first post out

Four steps from here to a published update. Each ticks off on its own as you go.

{{ obDoneCount }}/4
  1. βœ“{{ s.n }} {{ s.label }}

All four done β€” you're shipping.

Setup {{ obDoneCount }}/4 Β· next: {{ (onboardingSteps.find(s => !s.done) || {}).label }} Β· all done

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 πŸŽ‰

{{ (giftFirstRun.kit && giftFirstRun.kit.product_name) || 'Your' }} launch kit

Your story GIF

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 }}

What do you want to do?

{{ studioSignals.stale }} ready

Going Stale

Unshared wins about to age out β€” share before they're old news.

{{ studioSignals.short }} ready

Short Form

One update β†’ a post or thread. Pick a format, generate, edit & post.

Distribute

Send a finished post to every platform at once β€” plus your GitHub badge and build log.

Milestones

Your big shipped moments β€” prep & share far and wide.

Library

Saved assets & aged-out wins to repurpose.

{{ studioSignals.video }} ready

Video Studio

Promo + launch films, every ratio.

{{ studioSignals.image }} ready

Image Studio

Shareable images from a win or a Library image.

{{ studioSignals.gif }} ready

GIF Studio

Looping GIFs from images or a video's ending.

{{ studioSignals.sticker }} ready

Sticker Studio

Transparent stickers for Giphy, iMessage, Slack.

{{ studioSignals.long }} ready

Longform

One update β†’ a full long-form article.

{{ currentShareView.title }}

{{ currentShareView.tip }}

{{ itemBig(m) ? 'Big' : 'Small' }} {{ itemAgeDays(m) === 0 ? 'today' : itemAgeDays(m) + 'd old' }} {{ itemArchiveDays(m) }}d to archive Shared Γ—{{ m.share_count }}

{{ milestoneHeadline(m) }}

{{ m.why_it_matters || m.description }}

{{ marketingScore(m).score }} {{ marketingScore(m).verdict }}
{{ r }}

β–Ά Video ready β€” open page Β· also in your Studio

Still rendering β€” it'll appear in your Studio shortly.

{{ visualMsg[m.id] }}

Text

Visual

Threads

Got it β€” we'll show fewer like this.

Today

{{ todaySummary }}

Your next moves for {{ (activeProject && activeProject.name) || 'this project' }}.

Log a win

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

{{ coach.insight }}

Reach

{{ 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.

{{ milestoneHeadline(m) }}
{{ shipPostMsg[m.id] }}

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 }}

Connected βœ“

Captures

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) }}

{{ c.processed ? 'Used' : 'Waiting' }}

Milestones

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.

Ready to share on your visual platforms
Add a visual platform Save image

Distribute this ship β€” {{ milestoneHeadline(m) }}

{{ a.label }} ({{ a.handle }})

{{ platformCaption(m, a.key) }}

Finding hashtags…
{{ tag }}

Your channels

{{ shipPostMsg[m.id] }}
Connect Discord/Slack first β†’

Get discovered on Giphy

Writing your title, tags and description…

Add a little more detail to this milestone and .

What people type into the GIF box in Slack, Discord, Facebook β€” not hashtags.

{{ tag }}

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.

Writing your Short title, description and tags…

Add a little more detail to this milestone and .

YouTube Short

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.)

Writing venue-tailored posts…

Couldn't write the posts β€” add a little more detail and .

Open β†—

{{ milestoneHeadline(m) }}

{{ milestoneSubtitle(m) }}

{{ m.title }}

{{ m.description }}

Call: {{ milestoneCall(m).label }} your call provisional Re-routing…

{{ m.why_it_matters }}

Not worth a post on its own β€” bump it up if it actually matters.

{{ m.format_verdict === 'do_not_post' ? formatVerdictLabel(m.format_verdict) : 'Best shown as: ' + formatVerdictLabel(m.format_verdict) }}

✍️ This looks significant β€” want a long-form write-up too?

Here's what I could write:

{{ longFormSuggestion(m).title }}

  • {{ b }}

Primed βœ“ β€” open your product and click your Record bookmarklet to start (titled β€œ{{ walkthroughPrime.title || 'your walkthrough' }}”).

🎬 You shipped something β€” make a walkthrough of it?

Upgrade for more walkthroughs

πŸ“Ž Lands better with a screenshot or metric β€” attach one

No assets in this project yet β€” use β€œUpload new”, or add some in Settings β†’ Assets.

Attached proof

Image attached β€” this post is image-primary.

Not a visual moment β€” visuals land for launches, big milestones, striking numbers, or a new look, not routine ships and fixes.

Send to chat

{{ shipPostMsg[m.id] }}

Drafts

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.

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) : '' }}

Open page

Your prospect videos

{{ videoTitle(v) }}

{{ videoDate(v) }}

Open page Share to X Share to LinkedIn Download
βœ“

{{ 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) }}

{{ g.drafts.length }} platform{{ g.drafts.length === 1 ? '' : 's' }}

Text

Visual

Threads

Page {{ draftPage + 1 }} / {{ draftGroupPageCount }}

We turned your shipped work into posts.

Review, tweak, post β€” from your own profile, one click each.

This week's progress ({{ weekMilestones.length }} milestone{{ weekMilestones.length === 1 ? '' : 's' }})

  • β€’{{ milestoneHeadline(m) }}

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 Pro

Brand Kit {{ (activeProject && activeProject.name) || 'This project' }}

Your logo, colours, fonts and voice β€” used across every video for this project. Switch the active project at the top to set up another.

Loading…
Set up your brand kit β€” pull from your domain or upload your logo below, then pick a voice. It's used across every video for this project.

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.

Light logo No light logo yet
Dark logo No dark logo yet

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.

{{ brandKitMsg }}

Make an Ad

A short, scroll-stopping promo β€” only your brand on screen. Everything's pre-filled; the simple screen alone is shippable.

Style

Format

Length

Advanced

{{ (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.

{{ ad.msg }}

Create a Walkthrough

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.

{{ createVid.msg }}

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.

Image / Animation Studio

{{ allVisuals.length }} made

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.

Add a visual platform to unlock the studio

Sticker 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 Broadcast feature.

Email signature

An image for your email signature that always shows your newest sticker.

The email-signature image is a Broadcast 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 }}

{{ gifMeta[v.id] && gifMeta[v.id].loading ? 'Writing title, tags, description…' : 'Loading…' }}

Add a little more detail to this milestone and .

Giphy GIF

{{ gifMeta[v.id].title }}

{{ tag }}

Source: {{ ctaLink() || 'add your site in Settings' }}

Giphy Sticker

YouTube Short

Writing Short details… Add a little more detail and .

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.

Add a visual platform to unlock the Video Studio

{{ v.title }}

Save video

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 .

Your assets

The raw materials β€” brand, images and sound β€” we draw from to make your videos and posts.

Brand

Your logo
Font: {{ materialFont }}

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.

Detected logo

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.

  • {{ u.name }} uploading… added {{ u.error }}
{{ assetKindLabel(a.kind) }} {{ a.meta.aspect }} Add description

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.

Library

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.

Campaign No campaigns yet β€” group items with the campaign picker on any card below.

Saved videos

Nothing saved yet β€” save a walkthrough or launch video from its download and it lands here.

{{ v.title || 'Saved video' }}

Images

No images here{{ libCampaign ? ' in this campaign' : ' yet' }}.

{{ milestoneHeadline(m) }}

Open β†—

GIFs

No GIFs here{{ libCampaign ? ' in this campaign' : ' yet' }}.

{{ milestoneHeadline(m) }}

Open β†—

Stickers

No stickers here{{ libCampaign ? ' in this campaign' : ' yet' }}.

{{ milestoneHeadline(m) }}

Open β†—

Videos

No videos here{{ libCampaign ? ' in this campaign' : ' yet' }}.

{{ milestoneHeadline(m) }}

Open β†—

Walkthroughs & launch videos

{{ videoTitle(v) }}

{{ videoDate(v) }}

Download

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.

Nothing archived yet β€” shared and aged-out wins will collect here.
{{ itemBig(m) ? 'Big' : 'Small' }}

{{ milestoneHeadline(m) }}

{{ m.why_it_matters || m.description }}

{{ itemAgeDays(m) }}d old Shared{{ m.share_count ? ' Γ—' + m.share_count : '' }} Aged out

Infiltrate

Distribution

Get your ships in front of more people, in more places β€” set up the doors that fit {{ (activeProject && activeProject.name) || 'this project' }}.

Distribute

Send a finished post to every platform you've connected, and put your shipped work where people already look β€” your GitHub profile and your public build log. Nothing posts itself; you click Post.

Where your posts can go

The open platforms you've connected. Add more in .

Bluesky βœ“ Mastodon βœ“ dev.to βœ“ Telegram βœ“{{ telegramAutopost ? ' auto' : '' }}

No open platforms connected yet. Until then, use Copy on any post and paste it wherever you like.

Cross-post a finished post

Pick a post you've made and send it to every connected platform at once.

{{ (d.content || '').slice(0, 240) }}{{ (d.content || '').length > 240 ? '…' : '' }}

{{ broadcastSummary(d) }}

You don't have any finished posts yet.

β€œRecently shipped” for your GitHub profile

Put your latest ships on your GitHub profile page (github.com/{{ ghUsername || 'your-username' }}) so every visitor sees you building.

Your badge builds from your published ships.

Your public build log

Your build log goes live once you publish a changelog entry.

Brand

We pulled your logo and colours from your site β€” give them a quick once-over and save. This is what shows up on your videos, share pages, and end screens.

{{ brandCard.pulling ? 'Pulling your brand…' : 'Loading…' }}

One moment β€” filling everything in for you.

Logo

Your logo No logo yet

Colours

{{ sw.role }}

Saved βœ“

Re-making your launch video… it'll update in your Videos tab shortly.

Your share pulse

Founders who share daily get noticed.

Make your first share to start your streak.

Progress

No progress digest yet

This scores what you got done over a period and writes a shareable summary. Generate one once you have a few captures and posts.

β˜… Best {{ latestDigest.period_type }} yet
{{ Math.round(latestDigest.score || 0) }}

progress points Β· {{ digestTrend() }}

{{ (latestDigest.metrics && latestDigest.metrics[mk[1]]) || 0 }}
{{ mk[0] }}

{{ latestDigest.metrics.held_back.nudge }}

{{ latestDigest.summary }}

{{ v[0] }}

{{ (latestDigest.audience_variants && latestDigest.audience_variants[v[1]]) || '' }}

Settings

Your account

Settings for your whole account, used across every domain.

Your promo power

{{ completenessMeter.pct }}%

The more you connect, the more we can make for you. This never affects your free launch video.

{{ u.done ? 'βœ“' : 'β—‹' }} {{ u.label }} {{ u.need }} Unlocked

Subscription

{{ billingPlanLabel(billing.plan) }}

Checking your subscription…

Publishing & integrations

Connect the tools you build with and the channels you post to.

Connecting dev.to, Hashnode, Discord and Slack now lives in the tab.

Where you post

Tailors what we make

Tick the places you actually post. We'll generate one native variant for each β€” in that platform's real voice and length. Nothing here connects an account or posts for you.

{{ g.title }}

{{ g.hint }}

Main blog

Canonical home

Where your original long-form lives. When you cross-post, every copy's canonical points back here β€” so Google credits your main and never treats the reprints as duplicates.

Tick a blog above to add it here. No blog platform? FoxPlug hosts your canonical page.

Connectors

One-click

Connect the things you build with and your real moments turn into posts on their own. Read-only β€” we never change anything.

GitHub

every push β†’ posts

Connected{{ githubAccountLabel ? ' Β· ' + githubAccountLabel : '' }} βœ“ Not set up yet

Stripe

first customer β†’ posts

Connected βœ“

Vercel

shipped β†’ posts

Connected βœ“

GitLab

every push β†’ posts

Connected βœ“

Bitbucket

every push β†’ posts

Connected βœ“

Your launch & update videos live in the

Connect platforms for automatic posting

Connect dev.to, Bluesky and Mastodon so your posts go out when you click Share. What you enter is encrypted and never shown again after you save.

dev.to β€” API key for auto-posting Connected βœ“
Bluesky Connected βœ“
Mastodon Connected βœ“

Connect the tools you build with

Connect a tool and we pull in the moments worth sharing β€” work you shipped, first payments, issues you closed β€” straight in as milestones, each with a post waiting. We only ever read; we never change anything. Your connection is encrypted and never shown again after you save.

{{ t.name }} Connected βœ“

{{ t.scopeHint }}

{{ itokResult[t.key].text }} Last brought in: {{ itokSyncedLabel(t.key) || 'not yet' }}

Connect Claude Code

Real-time

When a Claude Code session ends, a short scrubbed summary of what you shipped flows in β€” and a post is waiting on each. Only a short summary ever leaves your machine, never a full transcript, and secret-shaped text is stripped before it sends.

  1. Click Generate key (done β€” it's in the command below).
  2. Copy this one line.
  3. Paste it into the window where Claude Code runs and press Enter.

That's it β€” your work will start flowing in.

{{ ccOneLiner }}

This line carries your key and is shown only once. Copy it now.

Your keys

No keys yet. Generate one above to connect Claude Code.

  • {{ k.label || 'Ingest key' }}

    Added {{ fmt(k.created_at) }} Β· last used {{ fmt(k.last_used_at) }}

    Active Revoked

Revoke is instant. To rotate, revoke the old key, then run Generate key again and paste the fresh line.

Connect your code on GitHub

Step 1 β€” start here

We pull in your recent changes and releases, group them into milestones, and write a post for each. Connect once and every push writes a post on its own.

{{ githubConnectMsg }}

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.

One-click GitHub connect is being switched on. For now you can connect by project name just below.

Or connect by project name

{{ repoSyncResult.text }}

We remember your project, so each time only the new work since last time comes in.

Connect your payments on Stripe

Connected βœ“

Your first customer becomes a post. Connect once and every payment after writes its own post β€” celebrating your revenue, never the maths behind it.

  1. {{ i+1 }} {{ s }}
{{ (CONNECT_GUIDES.stripe||{}).linkLabel || 'Open key page' }}

Read-only access to your payments. Encrypted at rest. We run one read-only check before connecting, and never show the key again β€” and never move your money.

Or connect in one click instead

{{ stripeConnectMsg }}

Stripe is connected. Your next customer payment writes its own post.

Last brought in: {{ itokSyncedLabel('stripe') || 'not yet' }}

Connect your patrons on Patreon

Connected βœ“

A new patron becomes a post. Authorise once and every new patron β€” and milestones like passing 50 patrons β€” writes its own post, celebrating the support behind your work.

One-click Patreon connect is being switched on β€” please check back soon.

{{ patreonConnectMsg }}

Patreon is connected. Your next patron writes its own post.

Reconnect YouTube (FoxSaaS channel)

Admin {{ ytTokenLabel }} No token stored

The upload token expires every 7 days. Press this, pick the FoxSaaS Google account, and a fresh one is stored β€” takes seconds.

⏳ Reconnect YouTube β€” {{ yt.tokenAgeDays >= 7 ? 'the token has expired' : ('expires in ~' + (7 - yt.tokenAgeDays) + ' day' + ((7 - yt.tokenAgeDays) === 1 ? '' : 's')) }}.

Heads up: a YOUTUBE_REFRESH_TOKEN environment variable is set on the project. The uploader reads it before the stored token, so reconnecting won't take effect until that env var is removed.

YouTube connect isn't configured yet.

{{ yt.msg }}

Connect your deploys on Vercel

Connected βœ“

When you ship, the world hears about it. Connect once and every production release writes its own post β€” celebrating that your work is live.

  1. {{ i+1 }} {{ s }}
{{ (CONNECT_GUIDES.vercel||{}).linkLabel || 'Open token page' }}

Read-only access to your deploys. Encrypted at rest. We run one read-only check before connecting, and never show the token again.

Or connect in one click instead

{{ vercelConnectMsg }}

Vercel is connected. Your next production release writes its own post.

Last brought in: {{ itokSyncedLabel('vercel') || 'not yet' }}

Connect your code on GitLab

Connected βœ“

Your code on GitLab becomes your story. Connect once and every push writes its own post β€” celebrating what you shipped.

  1. {{ i+1 }} {{ s }}
{{ (CONNECT_GUIDES.gitlab||{}).linkLabel || 'Open token page' }}

Read-only access to your code. Encrypted at rest. We run one read-only check before connecting, and never show the token again.

Or connect in one click instead

{{ gitlabConnectMsg }}

GitLab is connected. Your next push writes its own post.

Last brought in: {{ itokSyncedLabel('gitlab') || 'not yet' }}

Connect your code on Bitbucket

Connected βœ“

Your code on Bitbucket becomes your story. Connect once and every push writes its own post β€” celebrating what you shipped.

  1. {{ i+1 }} {{ s }}
{{ (CONNECT_GUIDES.bitbucket||{}).linkLabel || 'Open token page' }}

Read-only access to your code. Encrypted at rest. We run one read-only check before connecting, and never show the token again.

Or connect in one click instead

{{ bitbucketConnectMsg }}

Bitbucket is connected. Your next push writes its own post.

Last brought in: {{ itokSyncedLabel('bitbucket') || 'not yet' }}

Telegram

Telegram is the one channel that can post on its own β€” or share to it manually like the others, your choice. Add your bot to the target channel as an admin, then paste the channel id or @username below.

Public channel: use @username. Private channel/group: use the numeric chat id (starts with -100). Leave blank and Save to disconnect.

Channels

Where your posts can go. Telegram can auto-post if you switch it on below; everything else is one-click share.

  • {{ p.name }} {{ p.connected ? 'Connected' : (p.name === 'Telegram' ? 'Not connected' : 'Manual share') }}

This domain: {{ (activeProject && activeProject.name) || 'this domain' }}

Settings just for the domain you're editing.

Product website

Your product's web address. This is the keystone β€” your logo, colours, and where-you-post all start from here.

Saved βœ“

{{ siteExtractMsg }}

βœ“ Verified

We couldn't find that account β€” check the exact spelling, or paste the profile URL from the platform.

Saved β€” we couldn't auto-verify this one, double-check the handle.

Video settings

How videos for {{ activeProject.name || 'this domain' }} sound. These are per-domain and save as you change them.

Saved βœ“

{{ videoSettingsMsg }}

Posting profiles

The places you share updates. Your own profiles carry across projects; this project's accounts are pre-filled from your site where we can find them. Optional.

Already have a changelog? We'll pull it in.

History

Paste the web address of your changelog or blog. We fetch your past entries ourselves and add them as history β€” so future posts already know your product's story. You never paste entries by hand.

Where's my feed?

  • WordPress: add /feed to the end of your blog address.
  • Ghost: add /rss to the end.
  • Substack: add /feed to the end.
  • Not sure? Just paste your changelog page address and we'll find the feed for you.

{{ changelogImportResult.text }}

Name each codebase

Per codebase

You run more than one product from this project. Give each codebase its own product name and one-liner, and every post written from its work uses that β€” so an Acme codebase says "Acme", not the project name. Leave blank to fall back to the project name.

{{ r.repo_key }} Labeled βœ“

Changelog

{{ (activeProject && activeProject.name) || 'This project' }}

Your "What's new" page, an embeddable widget for your own site, and an RSS feed β€” all scoped to {{ (activeProject && activeProject.name) || 'this project' }}. Switch the active project at the top to manage another one.

The changelog page, widget and RSS are a Pro feature

Upgrade to publish a hosted changelog, drop a whitelabel "What's new" widget on your own site, and offer an RSS feed.

See Pro

Walkthroughs

No install

A one-time setup: add the Walkthroughs button to your browser's bookmark bar. Later, open your product and click it whenever you want to record a clickable walkthrough β€” nothing to download.

🦊 Install Walkthroughs

One-time: drag it to your bookmark bar. Then open your product in a tab β†’ click the bookmark β†’ choose β€œThis tab” β†’ click through your flow β†’ Finish. The session token refreshes about hourly; re-drag if it ever stops working.

{{ w.title || 'Untitled walkthrough' }}

{{ w.status }}

Open

No walkthroughs yet. Record your first with the button above.

Walkthrough CTA end screen

Per project

The closing call-to-action shown at the end of your shared walkthroughs. New walkthroughs start from these defaults.

Brand colour

The accent colour for the end-screen button and highlights. Tap a swatch from your brand kit, or type any hex.

Background image

A full-bleed image behind the end screen. Capture your landing page, paste a URL, or upload one.

End-screen background preview

{{ endcardBgMsg }}

Preview β“˜

{{ (endcardForm.headline || '').trim() || 'Your product β€” see it in action' }}

{{ endcardForm.subhead }}

{{ (endcardForm.button_text || '').trim() || 'Get started' }} {{ endcardForm.button_url }}
Video by FoxPlug

Updates live as you edit. Save to make it the default for new walkthroughs.

Brand Kit

Your logo, colours, fonts and voice for {{ (activeProject && activeProject.name) || 'this domain' }} β€” each domain keeps its own.

{{ brandKit && (brandKit.logo_light_url || brandKit.logo_dark_url) ? 'Brand kit set up' : 'Not set up yet' }}

Logo, palette, fonts, voice and language β€” used across every video for this domain.

What feeds this domain

Which connected repo, deploys, and store activity become this domain's updates.

Connect a repo, deploy, or store account under Your account, then choose what feeds this domain here.
  • {{ f.provider }}

    {{ f.label || 'β€”' }} Β· {{ f.status }}

    {{ f.default_project_id === (activeProject && activeProject.id) ? 'Feeds this domain' : ('Feeds: ' + feedTargetName(f.default_project_id)) }}

    Multiple products in one repo? Set per-codebase names in .

Funding

Turn your funding moments into posts β€” the way your commits, deploys and customers already do. Read-only: we never post to your funding accounts.

GitHub Sponsors

Connected βœ“

Every new sponsor and your monthly sponsor income, in on their own. Read-only.

One-click GitHub connect is being switched on β€” please check back soon.

{{ githubConnectMsg }}

Monthly income

{{ fundingIncomeLabel }}

Total sponsors

{{ (funding.snapshot && funding.snapshot.total_sponsors != null) ? funding.snapshot.total_sponsors : (funding.loaded ? 'β€”' : '…') }}

Last read {{ fmt(funding.snapshot.created_at) }}.

No reading yet.

{{ funding.msg }}

Patreon

Connected βœ“

Your patrons, in on their own β€” a new patron becomes a post. Read-only; Patreon has no post API.

One-click Patreon connect is being switched on β€” please check back soon.

{{ patreonConnectMsg }}

Creator

{{ patreonAccountLabel || 'Connected' }}

Patrons

{{ (funding.patreonSnapshot && funding.patreonSnapshot.total_sponsors != null) ? funding.patreonSnapshot.total_sponsors : (funding.loaded ? 'β€”' : '…') }}

Last read {{ fmt(funding.patreonSnapshot.created_at) }}.

Patron count is read when you connect β€” reconnect to refresh it.

Open Collective

Coming soon

Backers and budget from your collective. The connector isn't built yet.

Fund somewhere else?

Tell us where β€” Buy Me a Coffee, Ko-fi, Liberapay, anywhere. We build the most-asked-for one next.

{{ platformRequest.msg }}

Recent sponsors

New sponsors we've picked up β€” each is a moment worth sharing.

  • {{ e.sponsor_entity }}

    {{ e.tier_name }} Β· ${{ (e.tier_monthly_cents/100).toFixed(0) }}/mo Β· since {{ fmt(e.sponsor_created_at) }}

{{ funding.loaded ? 'No sponsors yet. When someone sponsors you on GitHub, they’ll show up here.' : 'Loading…' }}

Live data from your account. FoxPlug checks for new updates every 15 minutes.

Admin console

{{ admin.error }}

Loading admin data…

Give-first funnel

{{ s.label }}

{{ s.count }}

{{ s.pctOfPrev }}% {{ s.note }}

{{ s.count }} {{ s.note }}

GiftPostedViewedPlayedClaimSignupPro
{{ g.product_name || g.gift_token }} {{ fmtDate(g.posted_at) }} {{ g.viewed }} {{ g.played }} {{ g.claim_visits }} {{ g.signups }} {{ g.pros }}

{{ adminStats.total }}

Total users

{{ adminStats.free }}

Free

{{ adminStats.pro }}

Pro

{{ adminStats.serial }}

Broadcast

{{ adminStats.trials }}

Trials active

{{ adminStats.new7 }} / {{ adminStats.new30 }}

New 7d / 30d

Users

No users yet

No users match β€œ{{ admin.userSearch }}”.

Email Plan Subscription Projects +sites Trial ends Created Last seen Controls
{{ row.email }}admin {{ adminPlanShown(row) }} {{ (row.ent_plan || 'β€”') + (row.ent_status ? (' Β· ' + row.ent_status) : '') }} subscribed {{ row.projects_count }} {{ row.extra_projects || 0 }} {{ fmtDate(row.trial_ends_at) }} {{ fmtDate(row.created_at) }} {{ fmtDate(row.last_sign_in_at) }}

Build-tool insights

No responses yet

{{ grp.label }}

β€”

  • {{ item.value }} {{ item.count }}
Recent responses ({{ admin.rows.length }})
DatabaseRepoNo-codeIDEOther
{{ r.db || 'β€”' }} {{ r.repo || 'β€”' }} {{ r.nocode_builder || 'β€”' }} {{ r.ide || 'β€”' }} {{ r.other_text || 'β€”' }}

Promo Hub

New {{ phGrpUnseenReplies.length === 1 ? 'reply' : 'replies' }} ({{ phGrpUnseenReplies.length }})

{{ r.product_name }} new reply from {{ r.reply_author }} Open the reply β†—

{{ replyClean(r.reply_text) }}

{{ phSegueState(r).error }}

{{ d }}

This launch cycle Generating {{ phGrpGenerating.length }} Ready to post {{ phGrpReady.length }} Posted {{ phGrpPosted.length }}

Generating ({{ phGrpGenerating.length }})

{{ r.product_name }}{{ r.product_site_url || '' }}

{{ r.status==='building' ? 'Rendering your launch video…' : 'Queued β€” a video will auto-render soon' }}

Listing β†—

Ready to post ({{ phGrpReady.length }})

β–Ά β–Ά
{{ r.product_name }}no YT

{{ r.comment_text }}

YouTube β†—

2 Β· Paste your comment link β†’ track replies

{{ phpost.error }}

Posted ({{ phGrpPosted.length }})

{{ r.product_name }} posted βœ“ tracking replies βœ“ Adopted βœ“ replied {{ r.is_genuine_reply === true ? 'Open the reply β†—' : 'Open on PH β†—' }}

{{ r.reply_author || 'The maker' }} replied:

{{ replyClean(r.reply_text) }}

{{ phSegueState(r).error }}

{{ d }}

No launches loaded yet β€” hit β€œRefresh candidates”. New launches auto-render into videos on their own from here.

{{ phpromo.error }}

{{ phpromo.note }}

Loading…

No fresh candidates. Hit β€œRefresh candidates” to scan for new launches.

Nothing ready to post yet (needs a rendered video, a comment, and a YouTube URL). Switch to to see candidates in progress.

Gift shortlist ({{ promoHubShortlist().length }})

Ranked best-first. Scored on maker identity, how well it demos, and how cleanly the site captures.
{{ i + 1 }}
{{ r.product_name }} {{ r.gift_score }} {{ phSourceLabel(r.source || 'producthunt') }} {{ phMeta(r) }}

{{ r.gift_reason }}

{{ r.product_site_url }} β†—

{{ (r.genState==='processing' || r.status==='building') ? 'Generating (queued by you)…' : 'Queued by you…' }}

Failed: {{ r.genError || 'render error' }} β€” try again.

Listing β†—
Other candidates ({{ promoHubRest().length }}) β€” didn’t make the shortlist
{{ r.product_name }}{{ r.gift_score }}{{ phSourceLabel(r.source || 'producthunt') }}{{ phMeta(r) }}

{{ r.tagline || '' }}

{{ phWhyNot(r) }}

{{ (r.genState==='processing' || r.status==='building') ? 'Generating (queued by you)…' : 'Queued by you…' }}

Failed: {{ r.genError || 'render error' }} β€” try again.

Listing β†—

Ready to post ({{ promoHubReady().length }})

β–Ά β–Ά
{{ r.product_name }}{{ phSourceLabel(r.source || 'producthunt') }}reviewno commentposted βœ“tracking

{{ (r.genState==='processing' || r.status==='building') ? 'Regenerating (queued by you)…' : 'Queued by you…' }}

βœ“ New version ready β€” click β–Ά to watch it, then copy.

Regenerate failed: {{ r.genError || 'render error' }}

β–Ά Play YouTube β†—

Reply Inbox

{{ phpromo.error }}

{{ phpromo.note }}

No replies detected yet. The poller checks posted launches automatically.

{{ r.product_name }} {{ phSourceLabel(r.source || 'producthunt') }} {{ r.reply_author || 'Maker' }}{{ r.reply_at ? ' Β· ' + fmtDate(r.reply_at) : '' }}

{{ replyClean(r.reply_text) }}

Launch video

Clean, watermark-free launch videos from the EXACT page(s) you give β€” interior, feature and pricing pages welcome (the best material is often inside). You also get a GIF, sticker and poster.

{{ launchvid.result.product_name || 'Your launch video' }} β€” ready

Looking for promotable interior pages…

Suggested interior pages β€” click to include:

We couldn't build a strong video from those URL(s).

{{ launchvid.rejectMsg || 'Upload one or more screenshots (and optional instructions) and we will build the video from those. Your URLs and options above are kept.' }}

Screenshots {{ launchvid.showFallback ? '(needed)' : '(optional)' }}

Drag & drop images here, or click to choose

{{ launchvid.error }}

{{ launchvid.statusMsg || 'Rendering your launch video β€” this takes a couple of minutes. The video appears only when it is fully ready.' }}

{{ launchvid.shots.length }} screenshot(s) attached

Switch to the tab you're demoing…

{{ rec.countdown }}

Recording starts in {{ rec.countdown }}s

{{ rec.phase==='recording' ? 'REC' : 'PAUSED' }} {{ recElapsedLabel }} {{ rec.marks.length }} mark{{ rec.marks.length===1?'':'s' }}

{{ rec.callouts.length }} callout{{ rec.callouts.length===1?'':'s' }} added