Service integrations
Guides
3 min read
How to connect a form service, a newsletter provider and checkout links to the theme.
Nightgrid is a static site with no server code. Forms, newsletter sign-ups and payments work by pointing the theme at a service you choose.
The theme was not tested against any particular service. Where this page names one, it is an example; the provider’s own documentation is the authority on its addresses and settings.
1. Contact form
As shipped, the contact form is a preview: it is shown with a short note, its button checks the fields, and nothing a visitor types is sent anywhere. To connect it, give it the address a form service gives you. Formspree, Basin and Getform are examples of such services.
Either set the address in .env (or in your host’s build settings):
PUBLIC_CONTACT_FORM_ACTION=https://example.com/your-form-endpointor write it in src/data/contact.ts:
form: {
action: 'https://example.com/your-form-endpoint',
// ...
},The variable is read when the site is built, so build again after changing it.
What the form does. It is an ordinary HTML form that sends a POST request to that address, with the fields name, email, topic, message and leave_blank. The browser then shows whatever the service answers with. So the service must accept a plain form post and send the visitor on to a page.
The thanks page. Once the form has an address, the theme builds /contact/thanks/. Set your service to send visitors there after a message. If the service reads that address from a form field, uncomment redirect: 'redirect' in form.fields in src/data/contact.ts (and change the name to the one your service expects): the form then sends the full address of the thanks page in a hidden field.
Tip
leave_blankis a trap field that people do not see and simple programs fill in. Dropping messages that arrive with it filled in is the job of your form service: some expect a field name of their own, so check its documentation and rename the field inform.fields.honeypotinsrc/data/contact.ts.
To leave the form out of the page, delete the form block in src/data/contact.ts.
2. Newsletter sign-up
Both footers show an email field and a button (src/components/chrome/NewsletterForm.astro). As shipped it is a preview: the field and the button do nothing, and a line under them says “Not connected yet. Nothing is sent.”
To connect it, either set the address in .env:
PUBLIC_NEWSLETTER_FORM_ACTION=https://example.com/your-newsletter-endpointor write it in src/site.config.ts:
footer: {
newsletter: {
text: 'Product updates and new features, a few times a year.',
action: { label: 'Subscribe', href: 'https://example.com/your-newsletter-endpoint' },
},
// ...
},The variable wins when both are set.
What the field does. With an address it becomes an ordinary HTML form that sends a POST request with one field, email. The browser then shows whatever the provider answers with. Use the address your provider gives for a plain HTML form, one that answers with a page or sends the visitor on to one.
Caution
Not every provider’s form address is made for a plain HTML form. Loops is one example: its documentation (loops.so/docs/forms/custom-form, read on 2026-10-14) says the address answers with JSON and recommends sending the form with JavaScript. With the theme’s plain form, a visitor would be shown that JSON after subscribing. For a provider like that, add a script of your own that sends the form and shows a message.
To remove the sign-up, empty both footer.newsletter.text and footer.newsletter.action.label.
3. Checkout links
A plan’s button is a link. It can be a page of your own or a checkout link from a payment provider (a hosted payment page, for example). A plan can have one link for monthly and one for yearly billing; the switch on the pricing cards changes which one the button opens.
// src/data/pricing.ts
{
name: 'Team',
price: '$12',
priceYearly: '$9',
summary: 'More history, more tools and a scheduled digest.',
features: ['Unlimited connected tools', '12 months of history', 'Weekly email digest'],
cta: {
label: 'Choose Team',
href: 'https://example.com/checkout/team-monthly',
hrefYearly: 'https://example.com/checkout/team-yearly',
},
featured: true,
},How it works:
- The page is built with the monthly prices and the monthly links, so it is complete without JavaScript.
- When a visitor picks the other period,
src/scripts/billing.tschanges the prices shown and the address of each plan button. A plan withouthrefYearlykeeps its one link. - The change is written to a
role="status"line that screen readers read out.
4. Analytics
See Analytics and cookie consent.