☁️ Serverless Astro #
Here we will see how you can set up an Astro landing page form. Astro builds static sites, which are typically faster and more secure. Using serverless functions, you can add functionality traditionally handled by a backend yet keep the Astro speed. When it comes to serverless there are a number of options, writing code in JavaScript, Rust or other languages and also in terms of the platform the code runs on. Netlify offers hassle-free setup, and we will stick with JavaScript in case this is your first time trying serverless.
As just hinted, serverless functions let you run traditional back-end operations without having to configure and maintain a back end server. Typically, they are cheap to run and can easily scale up to handle high demand. The main trade-off is spin-up time, the time between the request being received and the cloud server being ready to start working on the request. This is falling all the time and in fact is not critical for our use case.
🧱 What we’re Building #
We will use Astro and Svelte to create a single page site; a landing page for a book launch. The focus is on how to integrate serverless functions with Astro, so we will keep the site fairly basic. This makes this an ideal tutorial to follow if you are just getting started with Astro. We will add a contact form and see how you can link that up to Netlify serverless functions. The serverless function will use a Telegram bot to send a message to a Telegram private chat. This can make the app more convenient to use, as site admins can have access to messages via the Telegram mobile app as well as while they are at their desk.
Netlify makes the serverless function available via an endpoint on the same domain the site is
hosted on. We will invoke the Netlify function by sending a REST POST
request (containing form data in the body). If this all sounds interesting, then let’s get
going!
⚙️ Astro Setup #
We are going to use Svelte to create the contact form and interface with the serverless function, so need to add the Svelte integration as we set up Astro. Let’s do that now from the Terminal:
Choose the Minimal app template and accept suggested config when prompted. Once that’s
all done, open up your browser just to check we’re good to go. The CLI will tell you where the
local dev server is running, this will be http://localhost:3000
if
there is not already something running on port 3000
. Don’t
expect too much (yet)! If all is working well, you will just see the word “Astro” in
the browser window.
Have a look at astro.config.mjs
in the project root folder. Astro has
added the Svelte integration for you!
🏡 Astro Landing Page Home Page #
We will start with the home page. The markup will all be done in Astro, and we will only use
Svelte for the contact form. Replace the content in src/pages/index.astro
:
Add some optional styling to make it look a little nicer:
src/pages/index.astro
— click to expand code.
We are using self-hosted fonts here. You can download the fonts from google-webfonts-helper . Unzip and move the four files to a new public/fonts
folder.
Astro Aliases #
If that’s all working, we will move on to the contact form component. Astro lets you define
aliases for folders within your project. This can be more convenient than writing something like import ContactForm from '../../components/ContactForm.svelte'
.
First create a src/components
folder then edit tsconfig.json
in the project root folder, so it looks like this:
Now add the component to the Home Page (it won’t work until we actually create and define the Svelte component).
The client:load
directive in line 26 is an Astro hydration parameter.
We use load
here to tell Astro always to hydrate the ContactForm
component, making it interactive by letting its JavaScript load. This makes sense here as the form
will probably be in view when the page loads, not to mention that it is a main feature of the page.
If we had a contact form which was JavaScript heavy and far down the page (so initially out of view)
we could instruct Astro to hydrate it only when visible, using client:visible
. This would improve user experience, optimizing loading the visible content faster.
Contact Form #
Typically, you will add client-side and serverless-side form input validation. To keep the code lean and stop the post getting too long, we will not add this here, though. Let me know if you would like to see some possible ways to do this; I could write a separate post.
Create src/components/ContactForm.svelte
and add the content below.
You see, we can add additional scoped styling within Astro Svelte components. Remove this style
block if you are skipping styling.
We add very basic bot detection in the form of a honeypot field (line 45
). This is not displayed in, or announced by, the browser, but a bot would find it and might be
tempted to fill it out. So any time we see a response with this field filled out, we can assume a
bot filled it out. For a production app, you might consider using a spam detection service like Akismet or Cloudflare bot detection HTTP headers. Captchas might also be suitable in some cases.
The form fields use Svelte input bindings, this is a little different to (and simpler than) what you might be used to if you come from a React background. Let me know if a separate post or video on Svelte form and input bindings would be useful.
Although we later add the Axios package for use in the serverless function, the fetch API helps us
out here with actually reaching the serverless function. We send a JSON POST
request to /.netlify/functions/contact-form-message
. For this
to work, we need to create the serverless function with a file name contact-form-message.js
. We will do that next!
🌥 Serverless Function #
First, we will add some Netlify configuration to the project. Create netlify.toml
in the project’s root folder and add this content:
Notice the publish directory is dist
which is where Astro outputs your
build site to. Next, we can create the functions folder: netlify/functions
then add contact-form-message.js
. If you prefer TypeScript,
change the extension and also add the @netlify/functions
package. You
can import types (only if you are working in TypeScript) adding import type { Handler } from '@netlify/functions';
to the top of this file.
As mentioned earlier, we use Axios here to contact Telegram servers, relaying the contact message to our private chat. We can add it as a project dependency now:
Let’s set up a Telegram bot, so we can get the environment variables needed to wire this up.
🤖 Telegram Bot #
The process for getting Telegram API credentials is quite simple, just follow step by step, and you will have API keys in a couple of minutes.
- Bots are created by Telegram's Bot Father — isn't that cute! Open up a new chat with @BotFather .
-
You interact with bots in Telegram by typing commands which begin with a
/
in the chat window. Create a new bot using the command/newbot
. Bot Father will ask you for a name and then a username. The name can be anything, but the username needs to endbot
and should only contain alphanumeric characters and underscores. I will use “Astro Landing Page Form Site” as the name andastro_landing_page_form_bot
as the username. Bot Father will respond with the new API key for your bot make a note of this. - Next, we need to create a new group chat and add the bot to it (you can also add anyone whom you want to receive bot messages). From the Telegram menu, select New Group. Enter a name for the group when prompted, then in the Add Members window type the username of your bot.
-
We’re almost done. Next, we need to get the ID for this new group chat, so we can send
messages to it from the Netlify Serverless Function. From the group chat, send a message to
the bot by typing the following command as a message “
/my_id @my_bot
” replacemy_bot
with the name of your bot. -
In the Terminal, use curl to see the bot’s updates. Remember to replace
123456789:AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQq
with the API key you got earlier: - how to set up an Astro Svelte project;
- how to use Netlify serverless functions to provide “back-end” functionality to your Astro app; and
- a convenient and efficient way to manage environment variables in your Netlify project.
Can you add back-end functions to an Astro static site? #
- Services like Netlify make it easy to add serverless functions to your static site. This is with the added convenience of not having to set up and maintain infrastructure. Other advantages include not having to worry about ensuring there is enough capacity online to handle incoming requests. One disadvantage is the spin-up time for serverless functions; typically there is a short delay between the request being received and work starting on processing it. Spin-up times are dropping and for many use cases they are not an issue. If you need minimal spin-up time, consider a Cloudflare Worker as the setup there offers considerable help.
Does Astro work with serverless functions? #
- Astro works well with serverless functions. Essentially, you can decouple your static site and the serverless functions. This makes it easier to keep the serverless functions if you later decide to move from Astro to another site builder. You can use serverless to add features like contact forms and comments, as well as registering likes to a database. On an e-commerce site, you might use serverless functions to get the latest stock levels displayed to the user interface.
Do you have to write JAMStack serverless functions in JavaScript #
- We have seen how to write a JavaScript serverless function using Netlify. On Netlify, you can also write Rust and Go serverless functions. Other services like Cloudflare workers also support Rust.
Retreive Chat ID #
If you don’t have curl on your machine, just paste the link into your browser instead. If you are working on a shared machine, be sure to clear the link from the browser history, as it contains an API key.
You will get a response back something like this:
OK this is just some JSON. It contains two ids, although we just need one. The first is the
message ID. We don’t need this one. The second, within the chat object, starts with a
“-
”, this is the required chat ID, including the “-
”.
We have all the API data we need to proceed. Let's carry on by setting up or function.
Netlify Environment Variables #
Netlify has the easiest way for handling environment. You can add them manually using the web
console, though I prefer the CLI. If you want to try my way, add the Telegram credentials to a
new .env
file:
Notice, you should not prefix these with PUBLIC_
as you would normally
do for Astro environment variables. This is because we do not need to expose the credentials on
the front end, just for the serverless function. In fact, another advantage of using serverless
functions is the added security of not needing to expose credentials to the client. Next you will
need to install the Netlify CLI globally on your machine, if you do not already have it installed:
Next, commit your project to GitHub, GitLab or whichever service you use and set it up as you
normally do. Be sure to add .env
to the .gitignore
file, so the credentials do not end up in your remote repo. If this is your first time using
Netlify, follow the step-by-step deploy instructions . Once the project is set up, just run the following commands from the project folder:
Just follow prompts to the right project, and this will take the variables from the .env
file and add them to your project on Netlify's servers. There is not a massive convenience pickup
as we only have two variable here, but for larger projects it is definitely worth the effort. Learn
more about managing Netlify environment variables from Netlify .
You might need to rebuild the site once you have added the environment variables.
🗳 Poll #
💯 Astro Landing Page Contact Form: Testing #
Everything should be working now, so let’s test it. The Netlify console will give you a link to the freshly built site. Follow the link and complete the contact form. Open up your Telegram app, and you should have a message in the group chat you created.
🙌🏽 Astro Landing Page Contact Form: Wrapping Up #
In this post we have had an introduction to Astro and seen:
The full code for the app is available in the Astro demo repo on Rodney Lab GitHub .
I hope you found this article useful and am keen to hear how you plan to use the Astro code in your own projects.
🏁 Astro Landing Page Form: Summary #
🙏🏽 Astro Landing Page Contact Form: Feedback #
Have you found the post useful? Would you prefer to see posts on another topic instead? Get in touch with ideas for new posts. Also, if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, please consider supporting me through Buy me a Coffee.
Just dropped a new post on how you can use Serverless with Astro.
— Rodney (@askRodney) March 30, 2022
You see how to set up a landing page with contact form using Astro with Netlify Serverless functions and a spot of Svelte.
I hope you find it useful!
https://t.co/hyOW0mq1cI#AstroJS #svelte #serverless
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on Astro as well as SvelteKit. Also, subscribe to the newsletter to keep up-to-date with our latest projects.