Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
# The crawl pass pages get no CSP: their Buy button posts to /crawl/checkout,
# which redirects to coinpayportal.com, and form-action 'self' would block it.
@notcrawl not path /crawl /crawl/*
header @notcrawl Content-Security-Policy "default-src 'self'; script-src 'self' https://crawlproof.com https://cdn.jsdelivr.net; connect-src 'self' https://crawlproof.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://built.indie.pit.world https://pwamart.com; font-src 'self'; frame-src 'self' https://crawlproof.com; base-uri 'self'; form-action 'self' https://pit.world; frame-ancestors 'none'"
header @notcrawl Content-Security-Policy "default-src 'self'; script-src 'self' https://crawlproof.com https://cdn.jsdelivr.net; connect-src 'self' https://crawlproof.com https://cdn.jsdelivr.net https://pit.world; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://built.indie.pit.world https://pwamart.com https://logicsrc.com https://profullstack.com; font-src 'self'; frame-src 'self' https://crawlproof.com; base-uri 'self'; form-action 'self' https://pit.world; frame-ancestors 'none'"

# Correct content types for machine-readable files.
@plain path /robots.txt /llms.txt /llms-full.txt /.well-known/security.txt
Expand Down
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ RUN for f in /api/migrations-pg/*.sql; do \
head -1 "$f" | grep -q '^-- TronBrowser Postgres schema:' \
|| { echo "not a Postgres migration: $f" >&2; exit 1; }; \
done
COPY scripts/pit-footer.mjs /pit-footer.mjs
COPY start.sh /start.sh
RUN chmod +x /start.sh
CMD ["/start.sh"]
58 changes: 54 additions & 4 deletions apps/extensions/public/extension.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,61 @@
<section class="panel" id="detail"><p class="muted">Loading…</p></section>
</main>

<footer><div class="wrap">
TronBrowser Store · <a href="/">tronbrowser.dev</a> · <a href="/store/">Browse</a> · <a href="/store/install-guide.html">Install guide</a> · <a href="/store/submit.html">Publish</a> · <a href="https://github.com/profullstack/tronbrowser.dev">GitHub</a>
</div></footer>
<div data-profullstack-footer data-site="https://tronbrowser.dev/" data-since="2026" data-tagline="MIT License" data-links='[{"label":"Home","href":"/"},{"label":"Store","href":"/store/"},{"label":"Install guide","href":"/store/install-guide.html"},{"label":"Publish","href":"/store/submit.html"},{"label":"Privacy","href":"/privacy"},{"label":"GitHub","href":"https://github.com/profullstack/tronbrowser.dev"},{"label":"Releases","href":"https://github.com/profullstack/tronbrowser.dev/releases"},{"label":"Tor mirror","href":"http://5nlx2hye6lddy4zki4xv3oteoxgerfd3343haizoicmonfb2ediy5gyd.onion","rel":"noopener noreferrer"}]' data-badges='[{"src":"https://logicsrc.com/openicon/set/hq/svg/built-indie.svg","href":"https://built.indie.pit.world/for?site=https://tronbrowser.dev/","alt":"Find this site on built.indie","width":32,"height":32},{"src":"https://logicsrc.com/openicon/set/hq/svg/pwamart.svg","href":"https://pwamart.com/for?site=https://tronbrowser.dev/","alt":"Find this site on PwaMart","width":32,"height":32}]'><footer class="pfs-footer" data-pfs-footer="0.6.10"><style>.pfs-footer{--pfs-footer-muted:color-mix(in srgb,currentColor 62%,transparent);--pfs-footer-gap:.5rem 1.25rem;--pfs-footer-size:.875rem;border-top:1px solid color-mix(in srgb,currentColor 14%,transparent);font-size:var(--pfs-footer-size);line-height:1.5;color:inherit}.pfs-footer__inner{max-width:72rem;margin:0 auto;padding:.85rem 1rem;display:flex;flex-direction:column;align-items:center;gap:.4rem;text-align:center}.pfs-footer a{color:var(--pfs-footer-muted);text-decoration:none}.pfs-footer a:hover,.pfs-footer a:focus-visible{color:inherit;text-decoration:underline}.pfs-footer__links{display:flex;flex-wrap:wrap;justify-content:center;gap:.35rem 1rem}.pfs-footer__ring{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:.4rem}.pfs-footer__badges{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:.4rem}.pfs-footer a.pfs-footer__badge{display:inline-block;line-height:0}.pfs-footer__badge img{display:block;width:200px;height:44px;max-width:100%}.pfs-footer__badge--site img{width:auto;height:auto}.pfs-footer__badge--publisher img{width:32px;height:32px;max-width:none;object-fit:contain}.pfs-footer__badge--square img{width:32px;height:32px;max-width:none;object-fit:contain}.pfs-footer__news{display:flex;justify-content:center}.pfs-footer__sub{display:flex;align-items:center;gap:.35rem;margin:0;flex-wrap:wrap;justify-content:center}.pfs-footer__sub input[type=email]{font:inherit;font-size:.8125rem;color:inherit;background:transparent;width:13.5rem;max-width:62vw;padding:.2rem .5rem;border:1px solid color-mix(in srgb,currentColor 25%,transparent);border-radius:.35rem}.pfs-footer__sub input[type=email]::placeholder{color:var(--pfs-footer-muted);opacity:1}.pfs-footer__sub input[type=email]:focus-visible{outline:2px solid color-mix(in srgb,currentColor 45%,transparent);outline-offset:1px}.pfs-footer__sub button{font:inherit;font-size:.8125rem;color:var(--pfs-footer-muted);background:transparent;padding:.2rem .6rem;border:1px solid color-mix(in srgb,currentColor 25%,transparent);border-radius:.35rem;cursor:pointer}.pfs-footer__sub button:hover,.pfs-footer__sub button:focus-visible{color:inherit}.pfs-footer__hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;opacity:0}.pfs-footer__sub+.pfs-footer__sublink{display:none}.pfs-footer__msg{flex-basis:100%;text-align:center;font-size:.8125rem;color:var(--pfs-footer-muted)}.pfs-footer__msg:empty{display:none}.pfs-footer__msg[data-state=ok]{color:inherit}.pfs-footer__msg[data-state=error]{color:#d92d20;color:light-dark(#b42318,#f97066)}.pfs-footer__copy{margin:0;color:var(--pfs-footer-muted)}.pfs-footer__copy a{color:inherit}.pfs-footer__tagline{display:inline-block;white-space:nowrap}.pfs-footer__brand{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;margin-inline:.35rem;padding:2px 4px;border-radius:3px;background:#202124;line-height:0}.pfs-footer__brand img{display:block;width:20px;height:11px;max-width:none}</style><div class="pfs-footer__inner"><nav class="pfs-footer__links" aria-label="Footer"><a href="/">Home</a><a href="/store/">Store</a><a href="/store/install-guide.html">Install guide</a><a href="/store/submit.html">Publish</a><a href="/privacy">Privacy</a><a href="https://github.com/profullstack/tronbrowser.dev">GitHub</a><a href="https://github.com/profullstack/tronbrowser.dev/releases">Releases</a><a href="http://5nlx2hye6lddy4zki4xv3oteoxgerfd3343haizoicmonfb2ediy5gyd.onion" rel="noopener noreferrer">Tor mirror</a><a href="https://pit.world/pro">Find a pro</a><a href="https://profullstack.com/terms">Terms</a><a href="https://profullstack.com/privacy">Privacy</a><a href="https://profullstack.com/media">Media</a><a href="https://github.com/profullstack" rel="noopener noreferrer">GitHub</a><a href="https://discord.gg/U7dEXfBA3s" rel="noopener noreferrer">Discord</a><a href="https://x.com/profullstackinc" rel="noopener noreferrer">X</a><a href="https://luma.com/profullstack" rel="noopener noreferrer">Events</a><a href="https://luma.com/mergenlaunch" rel="noopener noreferrer">Register for Event</a><a href="https://pairux.com/@profullstack" rel="noopener noreferrer">PairUX</a><a href="https://pairux.com/@moshcoding" rel="noopener noreferrer">Moshcoding</a></nav><nav class="pfs-footer__links" aria-label="Profullstack products"><a href="https://profullstack.com/stack/build">Agentic site builder</a><a href="https://crawlproof.com/surveys">CrawlProof Surveys</a></nav><nav class="webring pfs-footer__ring" aria-label="Profullstack webring"><a href="https://rssamplifier.com/ring/profullstack/previous?from=https%3A%2F%2Ftronbrowser.dev%2F" rel="prev" title="Previous site">&lt;&lt;</a><a href="https://rssamplifier.com/ring/profullstack">Profullstack</a><a href="https://rssamplifier.com/ring/profullstack/next?from=https%3A%2F%2Ftronbrowser.dev%2F" rel="next" title="Next site">&gt;&gt;</a></nav><div class="pfs-footer__news"><form class="pfs-footer__sub" action="https://pit.world/subscribe" method="post" autocomplete="on"><input type="hidden" name="site" value="tronbrowser.dev"><label for="pfs-footer-email">Email</label><input id="pfs-footer-email" type="email" name="email" required maxlength="254" autocomplete="email" placeholder="Email for our newsletter" aria-label="Email address for the Profullstack newsletter"><input class="pfs-footer__hp" name="website" type="text" tabindex="-1" autocomplete="off" aria-hidden="true"><button type="submit">Subscribe</button><span class="pfs-footer__msg" role="status" aria-live="polite"></span><script>(function wireSubscribe(form) {
if (!form || form.getAttribute('data-pfs-wired')) return;
form.setAttribute('data-pfs-wired', '1');
var msg = form.querySelector('.pfs-footer__msg');
var button = form.querySelector('button');
var reasons = {
invalid: "that doesn't look like an email address",
undeliverable: "that address's domain can't receive email",
failed: 'the confirmation email could not be sent, try again later',
};
function say(text, state) {
if (!msg) return;
msg.textContent = text;
msg.setAttribute('data-state', state);
}
form.addEventListener('submit', function (event) {
if (typeof fetch !== 'function') return; // let the plain POST go
event.preventDefault();
var data = new FormData(form);
var email = String(data.get('email') || '').trim();
// The honeypot: a bot that fills it gets the normal answer and nothing is sent.
if (data.get('website')) return say('Email confirmation sent. Check your inbox.', 'ok');
if (button) button.disabled = true;
say('Sending…', 'busy');
fetch(new URL('/api/subscribe', form.action).href, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ email: email, site: data.get('site') }),
})
.then(function (res) {
return res
.json()
.catch(function () {
return {};
})
.then(function (body) {
if (res.ok && body.ok) {
say('Email confirmation sent to ' + email + '. Check your inbox.', 'ok');
form.reset();
} else {
say('Failed: ' + (body.error || reasons[body.status] || 'pit.world answered ' + res.status), 'error');
}
});
})
.catch(function (err) {
say('Failed: could not reach pit.world (' + ((err && err.message) || err) + ')', 'error');
})
.then(function () {
if (button) button.disabled = false;
});
});
})(document.currentScript.parentNode)</script></form><a class="pfs-footer__sublink" href="https://pit.world/subscribe?site=https://tronbrowser.dev/">Newsletter</a></div><div class="pfs-footer__badges"><a class="pfs-footer__badge pfs-footer__badge--site" href="https://built.indie.pit.world/for?site=https://tronbrowser.dev/"><img src="https://logicsrc.com/openicon/set/hq/svg/built-indie.svg" alt="Find this site on built.indie" width="32" height="32" loading="lazy"></a><a class="pfs-footer__badge pfs-footer__badge--site" href="https://pwamart.com/for?site=https://tronbrowser.dev/"><img src="https://logicsrc.com/openicon/set/hq/svg/pwamart.svg" alt="Find this site on PwaMart" width="32" height="32" loading="lazy"></a></div><p class="pfs-footer__copy"><a href="tel:+18885264640">Phone: +1-888-526-4640</a></p><p class="pfs-footer__copy">&copy; 2026 <a class="pfs-footer__brand" href="https://profullstack.com/" title="Profullstack, Inc."><img src="https://profullstack.com/assets/logo.svg" alt="" width="20" height="11" loading="lazy"></a> <a href="https://profullstack.com/">Profullstack, Inc.</a> <span class="pfs-footer__tagline">&middot; MIT License</span></p></div></footer></div>
<script type="module" src="https://cdn.jsdelivr.net/npm/@profullstack/footer@latest/src/embed.js"></script>

<script src="/store/store.js"></script>
<!--pit-footer--><!--/pit-footer-->

</body>
</html>
Loading
Loading