appscript.dev
Automation Beginner Slides

Auto-number slides and add a progress footer

Standardise navigation across the deck — 3/12, 4/12 in the corner of every slide.

Published Oct 5, 2025

Northwind’s sales and training decks get reordered constantly — slides moved, merged, split. Google Slides will number slides for you, but only if you use the built-in placeholder, and that gets lost the moment someone pastes a slide from another deck. The result is a deck where the audience cannot tell slide 4 of 12 from slide 4 of 30, and the presenter cannot say “we’re nearly there” with any confidence.

This script drops a small N / total progress footer into the bottom-right corner of every slide. It is a beginner-friendly automation: one loop, one text box per slide, and a tidy navigation cue that always reflects the current slide count.

What you’ll need

  • A Google Slides deck and its ID, taken from the URL.
  • Nothing else — the script creates each footer text box itself.

The script

// Footer text box position and size, in points.
// 720 x 540 pt is the standard 4:3 slide; 960 x 540 for widescreen.
const FOOTER_LEFT = 680;   // distance from the left edge
const FOOTER_TOP = 540;    // distance from the top edge
const FOOTER_WIDTH = 60;
const FOOTER_HEIGHT = 20;

/**
 * Adds a "N / total" progress footer to the bottom-right corner of
 * every slide in a deck.
 *
 * @param {string} deckId  The ID of the Google Slides presentation.
 */
function addProgressFooter(deckId) {
  const deck = SlidesApp.openById(deckId);
  const slides = deck.getSlides();

  if (slides.length === 0) {
    Logger.log('Deck has no slides — nothing to number.');
    return;
  }

  // Walk every slide and stamp its position in the deck.
  slides.forEach(function (slide, i) {
    // i is zero-based, so add 1 for a human-readable slide number.
    const label = (i + 1) + ' / ' + slides.length;

    // Insert a small text box in the bottom-right corner.
    slide.insertTextBox(label, FOOTER_LEFT, FOOTER_TOP, FOOTER_WIDTH, FOOTER_HEIGHT);
  });

  Logger.log('Added a progress footer to ' + slides.length + ' slides.');
}

How it works

  1. addProgressFooter opens the deck by ID and reads all of its slides into an array.
  2. If the deck is empty it logs a message and returns, so an empty deck does not produce an error.
  3. It loops over the slides with their index i. Because i is zero-based, it adds 1 to get the slide number a viewer expects.
  4. It builds the label as N / total — for example 3 / 12 — using the array length for the total, so the footer is always correct for the deck as it stands now.
  5. insertTextBox places a small box at the position fixed by the FOOTER_* constants. The defaults sit in the bottom-right corner of a standard slide.

Example run

Run the script against a 12-slide deck and every slide gains a corner footer:

SlideFooter text
First slide1 / 12
Fourth slide4 / 12
Last slide12 / 12

The presenter and the audience both get a consistent navigation cue, whatever order the slides ended up in.

Run it

This is an on-demand finishing touch, run once a deck is final:

  1. In the Apps Script editor, open addProgressFooter and pass your deck’s ID, or call it from another function.
  2. Click Run and approve the authorisation prompt the first time.
  3. Open the deck to check the footers.

To run it from the deck itself, add a menu:

function onOpen() {
  SlidesApp.getUi()
    .createMenu('Deck tools')
    .addItem('Add progress footer', 'footerActiveDeck')
    .addToUi();
}

function footerActiveDeck() {
  addProgressFooter(SlidesApp.getActivePresentation().getId());
}

Watch out for

  • The script adds a new text box every time it runs. Run it twice and each slide gets two stacked footers. Either run it once on a finished deck, or delete the old footers first by tagging them with a known title and removing any box that matches before inserting fresh ones.
  • The FOOTER_* coordinates assume a standard 4:3 slide (720 × 540 pt). On a widescreen 16:9 deck (960 × 540 pt) the footer will sit too far left — bump FOOTER_LEFT to around 880.
  • Footers are placed on individual slides, not the master or layout. A slide added after the script runs will have no footer until you run it again.
  • The text box uses the deck’s default font and size. Style it afterwards, or extend the script to call getText().getTextStyle() on the inserted box if you want a specific look.

Related