mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-05 03:50:29 +01:00
feat(ads): collect ad details at Dodo checkout
This commit is contained in:
+399
@@ -0,0 +1,399 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Advertise on BentoPDF - Homepage Logo Ads | BentoPDF</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Put your logo on the BentoPDF homepage. Eight slots, a flat monthly price and no tracking. From $129 a month, cancel anytime."
|
||||
/>
|
||||
<meta name="author" content="BentoPDF" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
|
||||
<link rel="canonical" href="https://www.bentopdf.com/advertise" />
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://www.bentopdf.com/advertise" />
|
||||
<meta
|
||||
property="og:title"
|
||||
content="Advertise on BentoPDF - Homepage Logo Ads | BentoPDF"
|
||||
/>
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Put your logo on the BentoPDF homepage. Eight slots, a flat monthly price and no tracking. From $129 a month, cancel anytime."
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
content="https://www.bentopdf.com/images/og-tools.png"
|
||||
/>
|
||||
<meta property="og:site_name" content="BentoPDF" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta
|
||||
name="twitter:title"
|
||||
content="Advertise on BentoPDF - Homepage Logo Ads | BentoPDF"
|
||||
/>
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content="Put your logo on the BentoPDF homepage. Eight slots, a flat monthly price and no tracking. From $129 a month, cancel anytime."
|
||||
/>
|
||||
<meta
|
||||
name="twitter:image"
|
||||
content="https://www.bentopdf.com/images/og-tools.png"
|
||||
/>
|
||||
<meta name="twitter:site" content="@BentoPDF" />
|
||||
|
||||
<link href="/src/css/styles.css" rel="stylesheet" />
|
||||
<link href="/src/css/landing.css" rel="stylesheet" />
|
||||
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="192x192"
|
||||
href="/images/favicon-192x192.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="512x512"
|
||||
href="/images/favicon-512x512.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/images/apple-touch-icon.png"
|
||||
/>
|
||||
<link rel="icon" href="/favicon.ico" sizes="32x32" />
|
||||
</head>
|
||||
|
||||
<body class="lp antialiased">
|
||||
{{> navbar }}
|
||||
|
||||
<div id="app">
|
||||
<section id="ad-paid" class="lp-sec" hidden>
|
||||
<div class="lp-frame">
|
||||
<div class="lp-pad--tight">
|
||||
<div class="lp-note">
|
||||
<i data-lucide="circle-check"></i>
|
||||
<p>
|
||||
<strong>Payment received, thanks.</strong>
|
||||
We review every ad and usually put it live within two business
|
||||
days. To change anything, email
|
||||
<a
|
||||
href="mailto:[email protected]?subject=Ad%20for%20BentoPDF"
|
||||
class="text-indigo-400 hover:underline"
|
||||
>[email protected]</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="ad-failed" class="lp-sec" hidden>
|
||||
<div class="lp-frame">
|
||||
<div class="lp-pad--tight">
|
||||
<div class="lp-note">
|
||||
<i data-lucide="circle-alert"></i>
|
||||
<p>
|
||||
<strong>Checkout didn't go through.</strong>
|
||||
Nothing was charged. Try again below or email
|
||||
<a
|
||||
href="mailto:[email protected]?subject=Advertise%20on%20BentoPDF"
|
||||
class="text-indigo-400 hover:underline"
|
||||
>[email protected]</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="advertise-hero" class="lp-sec lp-sec--first">
|
||||
<div class="lp-frame">
|
||||
<div class="lp-head lp-head--center">
|
||||
<div>
|
||||
<h1 class="lp-h1">
|
||||
<span class="line">Advertise on</span>
|
||||
<span class="line dim">BentoPDF</span>
|
||||
</h1>
|
||||
<p class="lp-head-p">
|
||||
Put your logo on the BentoPDF homepage, right above the tools
|
||||
people open to work on their PDFs. Eight slots, a flat monthly
|
||||
price, and no tracking of any kind.
|
||||
</p>
|
||||
<div class="lp-actions">
|
||||
<span class="lp-brackets">
|
||||
<a href="#pricing" class="lp-btn lp-btn--primary">
|
||||
<span>See pricing</span>
|
||||
<i data-lucide="arrow-right"></i>
|
||||
</a>
|
||||
</span>
|
||||
<a
|
||||
href="mailto:[email protected]?subject=Advertise%20on%20BentoPDF"
|
||||
class="lp-btn lp-btn--ghost"
|
||||
>
|
||||
<i data-lucide="mail"></i>
|
||||
<span>Email us</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="pricing" class="lp-sec lp-band">
|
||||
<div class="lp-frame">
|
||||
<div class="lp-head lp-head--center">
|
||||
<div>
|
||||
<h2 class="lp-h2">
|
||||
<span class="line">Pick a</span>
|
||||
<span class="line dim">row</span>
|
||||
</h2>
|
||||
<p class="lp-head-p">
|
||||
Billed monthly. Cancel anytime and your ad stays up until the
|
||||
end of the month you paid for.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lp-grid lp-grid--2">
|
||||
<div class="lp-cell lp-tier lp-cell--accent lp-reveal">
|
||||
<h3>Top row</h3>
|
||||
<p class="lp-tier-for">
|
||||
Four slots, first in line above the tools
|
||||
</p>
|
||||
<div class="lp-tier-price"><b>$199</b><span>/ month</span></div>
|
||||
<ul>
|
||||
<li><i data-lucide="check"></i>Larger tile in the first row</li>
|
||||
<li><i data-lucide="check"></i>Your logo, name and link</li>
|
||||
<li>
|
||||
<i data-lucide="check"></i>On every language version of the
|
||||
homepage
|
||||
</li>
|
||||
<li><i data-lucide="check"></i>Cancel anytime</li>
|
||||
</ul>
|
||||
<a
|
||||
href="https://www.bentopdf.com/api/ad-checkout?row=top"
|
||||
class="lp-btn lp-btn--primary lp-btn--sm"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>Book the top row</a
|
||||
>
|
||||
</div>
|
||||
<div class="lp-cell lp-tier lp-reveal">
|
||||
<h3>Second row</h3>
|
||||
<p class="lp-tier-for">Four slots, right below the top row</p>
|
||||
<div class="lp-tier-price"><b>$129</b><span>/ month</span></div>
|
||||
<ul>
|
||||
<li>
|
||||
<i data-lucide="check"></i>Standard tile in the second row
|
||||
</li>
|
||||
<li><i data-lucide="check"></i>Your logo, name and link</li>
|
||||
<li>
|
||||
<i data-lucide="check"></i>On every language version of the
|
||||
homepage
|
||||
</li>
|
||||
<li><i data-lucide="check"></i>Cancel anytime</li>
|
||||
</ul>
|
||||
<a
|
||||
href="https://www.bentopdf.com/api/ad-checkout?row=second"
|
||||
class="lp-btn lp-btn--ghost lp-btn--sm"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>Book the second row</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="lp-sec">
|
||||
<div class="lp-frame">
|
||||
<div class="lp-head lp-head--center">
|
||||
<div>
|
||||
<h2 class="lp-h2">
|
||||
<span class="line">How it</span>
|
||||
<span class="line dim">works</span>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lp-grid lp-grid--3">
|
||||
<div class="lp-cell lp-reveal">
|
||||
<span class="lp-tile"><i data-lucide="credit-card"></i></span>
|
||||
<h3>Book a row</h3>
|
||||
<p>
|
||||
Checkout is handled by Dodo Payments, our merchant of record, so
|
||||
you get a proper invoice with sales tax taken care of.
|
||||
</p>
|
||||
</div>
|
||||
<div class="lp-cell lp-reveal">
|
||||
<span class="lp-tile"><i data-lucide="image"></i></span>
|
||||
<h3>Add your ad</h3>
|
||||
<p>
|
||||
Checkout asks for the name to show, your link, and a link to
|
||||
your logo as a square SVG or PNG of at least 128 by 128 pixels.
|
||||
</p>
|
||||
</div>
|
||||
<div class="lp-cell lp-reveal">
|
||||
<span class="lp-tile"><i data-lucide="rocket"></i></span>
|
||||
<h3>Go live</h3>
|
||||
<p>
|
||||
We review every ad by hand and usually put it live within two
|
||||
business days. Need a new logo or link later? Just email us.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="lp-sec">
|
||||
<div class="lp-frame">
|
||||
<div class="lp-pad--tight">
|
||||
<div class="lp-note lp-reveal">
|
||||
<i data-lucide="eye-off"></i>
|
||||
<p>
|
||||
<strong
|
||||
>We don't track our visitors, so we don't track your ad
|
||||
either.</strong
|
||||
>
|
||||
No pixels, no scripts, no impression or click counts. Your logo
|
||||
is served from bentopdf.com and links straight to your site. To
|
||||
measure visits, add UTM parameters to your link and read them in
|
||||
your own analytics.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="lp-sec">
|
||||
<div class="lp-frame">
|
||||
<div class="lp-head lp-head--center">
|
||||
<div>
|
||||
<h2 class="lp-h2">
|
||||
<span class="line">Frequently asked</span>
|
||||
<span class="line dim">questions</span>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lp-faq-wrap">
|
||||
<div id="faq-accordion" class="lp-faq lp-reveal">
|
||||
<div class="faq-item">
|
||||
<button
|
||||
class="faq-question w-full flex justify-between items-center text-left"
|
||||
type="button"
|
||||
>
|
||||
<span>What can I advertise?</span>
|
||||
<i data-lucide="plus" class="faq-icon"></i>
|
||||
</button>
|
||||
<div
|
||||
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
|
||||
>
|
||||
<p>
|
||||
Software, services and products that are useful to people
|
||||
who work with documents. We don't accept gambling, adult
|
||||
content, malware, or anything misleading. If we turn your ad
|
||||
down, we refund you in full.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<button
|
||||
class="faq-question w-full flex justify-between items-center text-left"
|
||||
type="button"
|
||||
>
|
||||
<span>Where does my ad show?</span>
|
||||
<i data-lucide="plus" class="faq-icon"></i>
|
||||
</button>
|
||||
<div
|
||||
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
|
||||
>
|
||||
<p>
|
||||
On the bentopdf.com homepage, in every language, directly
|
||||
above the tool grid. Self-hosted copies of BentoPDF never
|
||||
show ads.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<button
|
||||
class="faq-question w-full flex justify-between items-center text-left"
|
||||
type="button"
|
||||
>
|
||||
<span>Can you tell me how many people saw my ad?</span>
|
||||
<i data-lucide="plus" class="faq-icon"></i>
|
||||
</button>
|
||||
<div
|
||||
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
|
||||
>
|
||||
<p>
|
||||
No. BentoPDF has no analytics, so there are no impression or
|
||||
click numbers to share. Add UTM parameters to your link to
|
||||
see the visits we send you in your own analytics.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<button
|
||||
class="faq-question w-full flex justify-between items-center text-left"
|
||||
type="button"
|
||||
>
|
||||
<span>How do I cancel?</span>
|
||||
<i data-lucide="plus" class="faq-icon"></i>
|
||||
</button>
|
||||
<div
|
||||
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
|
||||
>
|
||||
<p>
|
||||
Email us and we'll cancel your subscription. Your ad stays
|
||||
up until the end of the month you paid for.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="lp-sec">
|
||||
<div class="lp-frame">
|
||||
<div class="lp-cta">
|
||||
<h2 class="lp-h2">Questions before you book?</h2>
|
||||
<p>Email us about slots, pricing or anything else.</p>
|
||||
<div class="lp-cta-actions">
|
||||
<span class="lp-brackets">
|
||||
<a
|
||||
href="mailto:[email protected]?subject=Advertise%20on%20BentoPDF"
|
||||
class="lp-btn lp-btn--primary"
|
||||
>
|
||||
<span>[email protected]</span>
|
||||
<i data-lucide="arrow-right"></i>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{{> footer }}
|
||||
<script type="module" src="src/js/utils/lucide-init.ts"></script>
|
||||
<script type="module" src="src/js/main.ts"></script>
|
||||
<script type="module" src="src/js/mobileMenu.ts"></script>
|
||||
<script type="module" src="src/js/landing.ts"></script>
|
||||
<script type="module" src="src/js/advertise.ts"></script>
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebPage",
|
||||
"name": "Advertise on BentoPDF - Homepage Logo Ads | BentoPDF",
|
||||
"url": "https://www.bentopdf.com/advertise"
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,80 @@
|
||||
const DODO_API = 'https://test.dodopayments.com';
|
||||
|
||||
const PRODUCTS = new Map([
|
||||
['top', 'pdt_0Nqt0672sYJEtrkIb2K6m'],
|
||||
['second', 'pdt_0Nqt069LgdQFPo1tFS1yF'],
|
||||
]);
|
||||
|
||||
const FIELDS = [
|
||||
{
|
||||
key: 'ad_name',
|
||||
label: 'Name on the ad',
|
||||
field_type: 'text',
|
||||
placeholder: 'Acme Invoices',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: 'ad_link',
|
||||
label: 'Link',
|
||||
field_type: 'url',
|
||||
placeholder: 'https://example.com',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: 'ad_logo',
|
||||
label: 'Logo link (square SVG or PNG)',
|
||||
field_type: 'url',
|
||||
placeholder: 'https://example.com/logo.svg',
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
||||
function redirect(location) {
|
||||
return new Response(null, {
|
||||
status: 303,
|
||||
headers: { Location: location, 'Cache-Control': 'no-store' },
|
||||
});
|
||||
}
|
||||
|
||||
async function createCheckout(productId, page) {
|
||||
const response = await fetch(`${DODO_API}/checkouts`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.DODO_PAYMENTS_API_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
product_cart: [{ product_id: productId, quantity: 1 }],
|
||||
custom_fields: FIELDS,
|
||||
return_url: `${page}?paid=1`,
|
||||
cancel_url: `${page}#pricing`,
|
||||
}),
|
||||
signal: AbortSignal.timeout(10000),
|
||||
});
|
||||
const body = await response.text();
|
||||
if (!response.ok) {
|
||||
throw new Error(`Dodo returned ${response.status}: ${body}`);
|
||||
}
|
||||
const { checkout_url } = JSON.parse(body);
|
||||
if (
|
||||
typeof checkout_url !== 'string' ||
|
||||
!checkout_url.startsWith('https://')
|
||||
) {
|
||||
throw new Error(`Dodo returned no checkout URL: ${body}`);
|
||||
}
|
||||
return checkout_url;
|
||||
}
|
||||
|
||||
export async function GET(request) {
|
||||
const url = new URL(request.url);
|
||||
const page = `${url.origin}/advertise`;
|
||||
const productId = PRODUCTS.get(url.searchParams.get('row'));
|
||||
if (!productId) return redirect(`${page}#pricing`);
|
||||
|
||||
try {
|
||||
return redirect(await createCheckout(productId, page));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return redirect(`${page}?checkout=failed`);
|
||||
}
|
||||
}
|
||||
+83
@@ -348,6 +348,89 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section
|
||||
id="ads-section"
|
||||
class="lp-ads hide-section"
|
||||
aria-labelledby="ads-title"
|
||||
hidden
|
||||
>
|
||||
<div class="lp-ads-head">
|
||||
<p id="ads-title" class="lp-kicker">Sponsored</p>
|
||||
<a href="/advertise" class="lp-ads-cta">
|
||||
<span>Advertise here</span>
|
||||
<i data-lucide="arrow-up-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="lp-ads-grid lp-cross">
|
||||
<a
|
||||
class="lp-ad lp-ad--top"
|
||||
href="#"
|
||||
rel="sponsored noopener"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="lp-ad-logo" style="--ad-tint: #f97316">A</span>
|
||||
<span class="lp-ad-text"><b>Acme Invoices</b></span>
|
||||
</a>
|
||||
<a
|
||||
class="lp-ad lp-ad--top"
|
||||
href="#"
|
||||
rel="sponsored noopener"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="lp-ad-logo" style="--ad-tint: #22c55e">G</span>
|
||||
<span class="lp-ad-text"><b>Globex Mail</b></span>
|
||||
</a>
|
||||
<a
|
||||
class="lp-ad lp-ad--top"
|
||||
href="#"
|
||||
rel="sponsored noopener"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="lp-ad-logo" style="--ad-tint: #0ea5e9">I</span>
|
||||
<span class="lp-ad-text"><b>Initech Notes</b></span>
|
||||
</a>
|
||||
<a
|
||||
class="lp-ad lp-ad--top"
|
||||
href="#"
|
||||
rel="sponsored noopener"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="lp-ad-logo" style="--ad-tint: #e11d48">H</span>
|
||||
<span class="lp-ad-text"><b>Hooli Sign</b></span>
|
||||
</a>
|
||||
<a class="lp-ad" href="#" rel="sponsored noopener" target="_blank">
|
||||
<span class="lp-ad-logo" style="--ad-tint: #a855f7">U</span>
|
||||
<span class="lp-ad-text"><b>Umbrella VPN</b></span>
|
||||
</a>
|
||||
<a class="lp-ad" href="#" rel="sponsored noopener" target="_blank">
|
||||
<span class="lp-ad-logo" style="--ad-tint: #eab308">S</span>
|
||||
<span class="lp-ad-text"><b>Stark Backup</b></span>
|
||||
</a>
|
||||
<a
|
||||
class="lp-ad lp-ad--open"
|
||||
href="https://www.bentopdf.com/api/ad-checkout?row=second"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span class="lp-ad-logo"><i data-lucide="plus"></i></span>
|
||||
<span class="lp-ad-text"><b>Your logo here</b></span>
|
||||
</a>
|
||||
<a
|
||||
class="lp-ad lp-ad--open"
|
||||
href="https://www.bentopdf.com/api/ad-checkout?row=second"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span class="lp-ad-logo"><i data-lucide="plus"></i></span>
|
||||
<span class="lp-ad-text"><b>Your logo here</b></span>
|
||||
</a>
|
||||
</div>
|
||||
<p class="lp-ads-note">
|
||||
Ads are plain logos and links. No tracking pixels, no scripts, no
|
||||
pop-ups.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div
|
||||
id="tool-grid"
|
||||
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 md:gap-6"
|
||||
|
||||
@@ -507,7 +507,12 @@ export function processDocument(document, options) {
|
||||
};
|
||||
}
|
||||
|
||||
export const ENGLISH_ONLY_PAGES = new Set(['terms', 'privacy', 'licensing']);
|
||||
export const ENGLISH_ONLY_PAGES = new Set([
|
||||
'terms',
|
||||
'privacy',
|
||||
'licensing',
|
||||
'advertise',
|
||||
]);
|
||||
|
||||
export function processPage(document, pageName, options) {
|
||||
if (ENGLISH_ONLY_PAGES.has(pageName)) {
|
||||
|
||||
@@ -2153,3 +2153,161 @@ body.lp ::selection {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.lp-ads {
|
||||
margin: 0 0 40px;
|
||||
}
|
||||
|
||||
.lp-ads-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.lp-ads-cta {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--lp-text-2);
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.lp-ads-cta:hover {
|
||||
color: var(--lp-text);
|
||||
}
|
||||
|
||||
.lp-ads-cta svg {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.lp-ads-grid {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 1px;
|
||||
background: var(--lp-line);
|
||||
border: 1px solid var(--lp-line);
|
||||
}
|
||||
|
||||
.lp-ad {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
min-height: 64px;
|
||||
padding: 14px 18px;
|
||||
background: var(--lp-bg);
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
.lp-ad:hover {
|
||||
background-color: var(--lp-bg-2);
|
||||
}
|
||||
|
||||
.lp-ad--top {
|
||||
min-height: 92px;
|
||||
background: var(--lp-bg-2);
|
||||
}
|
||||
|
||||
.lp-ad--top:hover {
|
||||
background-color: var(--lp-bg-3);
|
||||
}
|
||||
|
||||
.lp-ad-logo {
|
||||
display: grid;
|
||||
flex: none;
|
||||
place-items: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 6px;
|
||||
background: var(--ad-tint, var(--lp-bg-3));
|
||||
font-family: var(--lp-display);
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.lp-ad--top .lp-ad-logo {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.lp-ad-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.lp-ad-text b {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-family: var(--lp-display);
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.01em;
|
||||
color: var(--lp-text);
|
||||
}
|
||||
|
||||
.lp-ad--open .lp-ad-logo {
|
||||
border: 1px dashed var(--lp-line-2);
|
||||
background: transparent;
|
||||
color: var(--lp-dim);
|
||||
transition:
|
||||
color 0.2s,
|
||||
border-color 0.2s;
|
||||
}
|
||||
|
||||
.lp-ad--open .lp-ad-logo svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.lp-ad--open b {
|
||||
font-weight: 500;
|
||||
color: var(--lp-text-2);
|
||||
}
|
||||
|
||||
.lp-ad--open:hover .lp-ad-logo {
|
||||
border-color: var(--lp-accent-2);
|
||||
color: var(--lp-accent-3);
|
||||
}
|
||||
|
||||
.lp-ads-note {
|
||||
margin: 12px 0 0;
|
||||
font-size: 13px;
|
||||
color: var(--lp-dim);
|
||||
}
|
||||
|
||||
@media (min-width: 900px) {
|
||||
.lp-ads-grid {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.lp-ad,
|
||||
.lp-ad--top {
|
||||
gap: 10px;
|
||||
min-height: 56px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.lp-ad-logo,
|
||||
.lp-ad--top .lp-ad-logo {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.lp-ad-text b {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const outcome = params.get('status') ?? '';
|
||||
const failed =
|
||||
params.get('checkout') === 'failed' ||
|
||||
['failed', 'expired', 'cancelled'].includes(outcome);
|
||||
const paid = params.has('paid') || params.has('subscription_id');
|
||||
|
||||
if (failed || paid) {
|
||||
document
|
||||
.getElementById(failed ? 'ad-failed' : 'ad-paid')
|
||||
?.removeAttribute('hidden');
|
||||
}
|
||||
@@ -45,6 +45,15 @@ const FAVORITE_STAR_PATHS = [
|
||||
] as const;
|
||||
declare const __BRAND_NAME__: string;
|
||||
|
||||
const adsSection = document.getElementById('ads-section');
|
||||
if (
|
||||
adsSection &&
|
||||
(['bentopdf.com', 'www.bentopdf.com'].includes(window.location.hostname) ||
|
||||
import.meta.env.DEV)
|
||||
) {
|
||||
adsSection.hidden = false;
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
await initI18n();
|
||||
await loadRuntimeConfig();
|
||||
|
||||
@@ -217,6 +217,10 @@
|
||||
"source": "/(.*)\\.html",
|
||||
"headers": [{ "key": "Cache-Control", "value": "public, max-age=3600" }]
|
||||
},
|
||||
{
|
||||
"source": "/api/(.*)",
|
||||
"headers": [{ "key": "Cache-Control", "value": "no-store" }]
|
||||
},
|
||||
{
|
||||
"source": "/(ar|be|da|de|es|fr|id|it|ja|ko|nl|pl|pt|ru|sk|sv|tr|uk|vi|zh|zh-TW|ca|fa)/(.*)",
|
||||
"headers": [{ "key": "Cache-Control", "value": "public, max-age=300" }]
|
||||
|
||||
@@ -76,6 +76,7 @@ function loadPages(): Set<string> {
|
||||
'licensing',
|
||||
'kura',
|
||||
'hyper-compress',
|
||||
'advertise',
|
||||
'404',
|
||||
'pdf-converter',
|
||||
'pdf-editor',
|
||||
@@ -803,6 +804,7 @@ export default defineConfig(({ command }) => {
|
||||
licensing: resolve(__dirname, 'licensing.html'),
|
||||
kura: resolve(__dirname, 'kura.html'),
|
||||
'hyper-compress': resolve(__dirname, 'hyper-compress.html'),
|
||||
advertise: resolve(__dirname, 'advertise.html'),
|
||||
...Object.fromEntries(
|
||||
fs
|
||||
.readdirSync(resolve(__dirname, 'blog'))
|
||||
|
||||
Reference in New Issue
Block a user