I tried translating an entire PowerPoint file using the Google Cloud Translation API

I tried translating an entire PowerPoint file using the Google Cloud Translation API

I tried out the document translation feature of the Cloud Translation API, which is useful when you want to translate PowerPoint files into another language while preserving the layout. I tested how shapes, text boxes, and speaker notes are handled, and whether custom terminology can be fixed using a glossary.
2026.06.03

This page has been translated by machine translation. View original

Hi, I'm Keema.

There are situations where you want to translate proposal materials and slides created in PowerPoint into another language while preserving the layout.
A typical requirement is to convert a presentation with shapes, flow diagrams, and charts into English without breaking the visual appearance.
However, if you extract only the text from the slides for translation, the shape placement and flow diagrams fall apart.
Furthermore, unique proper nouns such as product names and character names often need to be consistently translated the same way every time.

Previously, I wrote an article about translating PDFs using the Document Translation feature of Google Cloud's Cloud Translation API.
This feature supports not only PDFs, but also Word, Excel, and PowerPoint.
In this article, I used the same feature to translate a PowerPoint (PPTX) file as-is, and verified in practice how shapes, text boxes, and speaker notes are handled, and whether a glossary can lock in custom terminology.

This article is the PowerPoint edition of a series that verifies document translation by format.
Specifications and behavior were confirmed against Google Cloud's official documentation, with relevant sections cited.
I then ran actual tests to verify whether things work as the official documentation describes.

Series Articles

Format Article
PDF Edition Cloud Translation API で PDF をレイアウトを保ったまま翻訳する
Word Edition Cloud Translation API で Word をレイアウトを保ったまま翻訳する
Excel Edition Cloud Translation API で Excel をレイアウトを保ったまま翻訳する
PowerPoint Edition (this article)

Target audience: Those considering automating the translation of PowerPoint materials

1. Conclusion: Official Documentation vs. Verified Results

For those who want to get to the point quickly, here is a summary of what the Google Cloud official documentation says about translating PowerPoint (PPTX) files, along with the results I confirmed by actually running translations.
Detailed steps and before/after images are in §3 and later.

Aspect Official Documentation Verified Results (confirmed in this article)
Titles, bullet points, tables, layout Translates while preserving format and layout Preserved and translated
Content inside shapes and text boxes (Word is explicitly stated as "not translated." PPTX is not explicitly stated.) Was translated
Speaker notes (Not explicitly stated) Was translated
Charts and images (Not explicitly stated) Charts (title, axes, legend, categories) and images pasted as pictures remained in Japanese
Glossary (locking custom terminology) Translation can be locked with a glossary Applied consistently across the entire slide, including titles, bullet points, tables, shapes, text boxes, and speaker notes

The big difference from Word and Excel is that content inside shapes and text boxes is also translated.
In addition, speaker notes, which are unique to PowerPoint, are also translated, and the glossary is applied consistently to all of these.
For those in a hurry, this table and the images in §4 should give you an overview.
As the final installment of the series, §8 contains a table summarizing the differences across all three formats.

2. What Is Document Translation in Cloud Translation API?

Cloud Translation API's Document Translation is a feature that, when you pass a file directly to it, translates it while preserving the formatting and layout.
It supports DOCX, PPTX, XLSX, and PDF.
An overview of the feature, authentication, and how to create a glossary were covered in previous articles.

Cited from: DevelopersIO: Cloud Translation API で PDF をレイアウトを保ったまま翻訳する

The key thing I wanted to verify for PowerPoint is how shapes and text boxes are handled.
In Word and Excel, the content inside text boxes and shapes was not translated, but since shapes are a primary building block in PowerPoint, I wanted to verify whether the behavior changes.

3. Preparation for Verification

3.1 Prerequisites

The prerequisites are the same as in the Word and Excel editions (macOS, Python 3.12 venv, google-cloud-translate 3.26.0, a personal project with billing enabled).
The steps for enabling the API, ADC authentication, and installing libraries into the venv are also the same.

3.2 Sample Document (Original Fictional Anime)

For verification purposes, I had Claude create a PowerPoint slide deck in the form of an introduction to a fictional anime called "Hoshirei Monogatari: Lumina Chronicle."
It shares the same world setting as the PDF, Word, and Excel editions, with the same proper nouns (coined terms).
The content is completely original and has no relation to any real works, people, or organizations.

The slide deck consists of 7 slides and is packed with verification elements unique to PowerPoint.

  • Title, bullet points, tables
  • A flow diagram titled "Steps of Reso-Evolution" made with rounded rectangle shapes and arrows
  • Text placed inside shapes of various forms: ellipses, hexagons, stars, callouts, arrows, and clouds
  • A text box (note) on the world-setting slide
  • A bar chart imported from Excel (embedded chart)
  • Speaker notes (presenter's notes) on each slide

The PowerPoint translated this time has a total of 7 slides.
All slides before translation are shown below.

Pre-translation PowerPoint slide 1 (title, Japanese)
Pre-translation PowerPoint slide 1: Title and subtitle, key visual image

Pre-translation PowerPoint slide 2 (world setting, Japanese)
Pre-translation PowerPoint slide 2: Bullet-point world setting, text box (note), chart image

Pre-translation PowerPoint slide 3 (Hoshirei Codex, Japanese)
Pre-translation PowerPoint slide 3: Table for the Hoshirei Codex

Pre-translation PowerPoint slide 4 (Steps of Reso-Evolution, Japanese)
Pre-translation PowerPoint slide 4: Flow diagram titled "Steps of Reso-Evolution" made with rounded rectangle shapes and arrows

Pre-translation PowerPoint slide 5 (popularity ranking, Japanese)
Pre-translation PowerPoint slide 5: Bar chart of popularity ranking (embedded chart)

Pre-translation PowerPoint slide 6 (various shapes, Japanese)
Pre-translation PowerPoint slide 6: Text placed inside shapes of various forms: ellipses, hexagons, stars, callouts, arrows, and clouds

Pre-translation PowerPoint slide 7 (summary, Japanese)
Pre-translation PowerPoint slide 7: Summary cards (rounded rectangle shapes) and text boxes

4. Translating a PowerPoint (PPTX) File

The script used for translation is the same one from the Word edition. Since it determines the MIME type from the file extension, it works just by changing the input to a PPTX file.
The full script is reproduced here so the article stands on its own.

Full text of translate_document_handson.py (click to expand)
from __future__ import annotations

import argparse
import time
from pathlib import Path

from google.cloud import translate_v3 as translate

# Glossaries and custom models must be placed in us-central1.
DEFAULT_LOCATION = "us-central1"

# Extension → MIME type (supported formats for Document Translation)
MIME_BY_SUFFIX = {
    ".pdf": "application/pdf",
    ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
    ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
}

def mime_for(path: str) -> str:
    """Returns the MIME type from the input file's extension. Raises ValueError for unsupported extensions."""
    suffix = Path(path).suffix.lower()
    if suffix not in MIME_BY_SUFFIX:
        raise ValueError(f"Unsupported extension: {suffix} (supported: {', '.join(MIME_BY_SUFFIX)})")
    return MIME_BY_SUFFIX[suffix]

def parse_args() -> argparse.Namespace:
    p = argparse.ArgumentParser(description="Cloud Translation API document translation (synchronous)")
    p.add_argument("--project", required=True, help="GCP project ID")
    p.add_argument("--input", required=True, help="Input file path")
    p.add_argument("--output", required=True, help="Output file path (result without glossary)")
    p.add_argument("--source", default="ja", help="Source language code (default: ja)")
    p.add_argument("--target", default="en", help="Target language code (default: en)")
    p.add_argument("--location", default=DEFAULT_LOCATION, help=f"Location (default: {DEFAULT_LOCATION})")
    p.add_argument("--glossary-id", default=None, help="Glossary ID (when specified, outputs both with and without glossary)")
    return p.parse_args()

def build_request(args: argparse.Namespace, content: bytes) -> dict:
    """Builds the request dictionary for translate_document.

    Specifying the source language is required when using a glossary (per official spec).
    """
    parent = f"projects/{args.project}/locations/{args.location}"
    mime_type = mime_for(args.input)
    request: dict = {
        "parent": parent,
        "source_language_code": args.source,
        "target_language_code": args.target,
        "document_input_config": {"content": content, "mime_type": mime_type},
    }
    if args.glossary_id:
        glossary_path = (
            f"projects/{args.project}/locations/{args.location}"
            f"/glossaries/{args.glossary_id}"
        )
        request["glossary_config"] = translate.TranslateTextGlossaryConfig(glossary=glossary_path)
    return request

def write_bytes(path: str, data: bytes) -> None:
    Path(path).parent.mkdir(parents=True, exist_ok=True)
    Path(path).write_bytes(data)

def main() -> None:
    args = parse_args()
    content = Path(args.input).read_bytes()
    print(f"Input: {args.input} ({len(content):,} bytes, {args.source}{args.target})")

    client = translate.TranslationServiceClient()
    request = build_request(args, content)

    started = time.perf_counter()
    response = client.translate_document(request=request)
    elapsed = time.perf_counter() - started

    base = response.document_translation
    write_bytes(args.output, base.byte_stream_outputs[0])
    print(f"Processing time: {elapsed:.2f} seconds")
    print(f"Output (no glossary): {args.output} ({len(base.byte_stream_outputs[0]):,} bytes)")

    # With glossary: a single call returns a separate glossary_document_translation output
    if args.glossary_id and response.glossary_document_translation.byte_stream_outputs:
        out = Path(args.output)
        glossary_out = str(out.with_name(f"{out.stem}_glossary{out.suffix}"))
        write_bytes(glossary_out, response.glossary_document_translation.byte_stream_outputs[0])
        print(f"Output (with glossary): {glossary_out}")

if __name__ == "__main__":
    main()

First, translate without a glossary.

python translate_document_handson.py \
    --project <YOUR_PROJECT_ID> \
    --input hoshirei_ja.pptx \
    --output hoshirei_en.pptx
# Example output
Input: hoshirei_ja.pptx (146,984 bytes, ja→en)
Processing time: 1.32 seconds
Output (no glossary): hoshirei_en.pptx (138,328 bytes)

After checking the translation, the titles, bullet points, and tables were translated into English, and the layout was preserved.
First, here are the before-and-after comparisons for all 7 slides.

Before/after comparison (PowerPoint slide 1, title)
Slide 1: Left is before translation (Japanese), right is after. Title and subtitle are translated into English.

Before/after comparison (PowerPoint slide 2, world setting)
Slide 2: Left is before, right is after. Both the bullet points and the text box (note) on the right are translated.

Before/after comparison (PowerPoint slide 3, Hoshirei Codex)
Slide 3: Left is before, right is after. The table data is translated into English.

Before/after comparison (PowerPoint slide 4, Steps of Reso-Evolution)
Slide 4: Left is before, right is after. In the flow diagram made with rounded rectangle shapes and arrows, the text inside the shapes is also translated.

Before/after comparison (PowerPoint slide 5, popularity ranking)
Slide 5: Left is before, right is after. The chart's title, axes, legend, and categories remain in Japanese.

Before/after comparison (PowerPoint slide 6, various shapes)
Slide 6: Left is before, right is after. The text inside shapes of every form—ellipses, hexagons, stars, callouts, arrows, and clouds—is translated.

Before/after comparison (PowerPoint slide 7, summary)
Slide 7: Left is before, right is after. The text inside the summary cards (rounded rectangle shapes) is also translated.

The biggest difference from Word and Excel was in how shapes and text boxes are handled.

4.1 Content Inside Shapes and Text Boxes Is Also Translated

The "Steps of Reso-Evolution" flow diagram (slide 4) had even the text inside the rounded rectangle shapes translated.
The text placed inside shapes of various forms—ellipses, hexagons, stars, callouts, arrows, and clouds (slide 6)—was also fully translated.
The text box (note) on the world-setting slide (slide 2) and the content inside the summary cards (slide 7) were also translated.

In Word and Excel, the content inside text boxes and shapes was not translated, but in PowerPoint, the content inside shapes and text boxes was translated.
Even within the same Document Translation feature, how shapes are handled is the opposite depending on the format.

4.2 Speaker Notes Are Also Translated

Speaker notes (presenter's notes) were also checked.
The notes on all slides were translated into English.
Notes are a PowerPoint-specific element not found in Word or Excel, but they are treated as translation targets in the same way as body text and shapes.
The glossary is also applied consistently to notes along with the rest of the slide (covered in more detail in §5.3).

4.3 Charts and Images Are Not Translated

Charts and images were not translated, the same as in Excel.
As shown in the comparison images above for the popularity ranking slide (slide 5), the embedded chart's title, axes, legend, and categories all remain in Japanese.
Also, items placed as images—such as the key visual on the title slide (slide 1) or the chart pasted as an image on the world-setting slide (slide 2)—are not translated because the text within them is part of the image.

5. Locking Custom Terminology with a Glossary

I verified whether proper nouns and custom terminology can be locked to specific translations.
To use a glossary, you need to (1) prepare a TSV with the mapping between source terms and translations, (2) upload it to Cloud Storage, and (3) create a glossary resource.

5.1 Prepare the Glossary TSV

The glossary is prepared as a TSV file with the source term (Japanese) and translation (English) listed tab-separated, one per line.
No header row is needed; the left column is the coined source term and the right column is the fixed translation you want.
For this test, I prepared 20 coined terms from the sample as glossary_ja_en.tsv.

星霊	Hoshirei
共鳴進化	Reso-Evolution
輝光石	Lumina Shard
雷狼ボルテ	Voltefang
焔狐ココ	Pyrofox Coco
水亀アクオ	Aquortle
草鹿リーフィ	Leafawn
輝竜ルミナ	Lumidragon
月読の祠	Moonread Shrine
守護者	Warden
星導士	Starwright
星霊守護協会	Hoshirei Warden Guild
共鳴値	Reso-Value
共鳴の灯	Resonance Flame
絆ゲージ	Bond Gauge
星霊酔い	Hoshirei-sickness
星霊図鑑	Hoshirei Codex
ルミナ群島	Lumina Archipelago
七つの祠	Seven Shrines
共鳴結界	Reso-Barrier

5.2 Upload the TSV to Cloud Storage and Create a Glossary Resource

Rather than uploading the TSV directly to create a glossary resource, you first place it in Cloud Storage and then create the resource by specifying that GCS URI.
Create the bucket in the same us-central1 location as the glossary.

# Create bucket (skip if it already exists)
gcloud storage buckets create gs://<YOUR_BUCKET> \
    --project <YOUR_PROJECT_ID> --location us-central1

# Upload TSV
gcloud storage cp glossary_ja_en.tsv \
    gs://<YOUR_BUCKET>/glossaries/glossary_ja_en.tsv

Next, create the glossary resource from the uploaded TSV.
Creation is a long-running operation (LRO), so run it from the client library and wait for it to complete.
Save the following code as setup_glossary.py and run it within the venv.

Full text of setup_glossary.py (click to expand)
from google.cloud import translate_v3 as translate

PROJECT_ID = "<YOUR_PROJECT_ID>"
LOCATION = "us-central1"   # Glossaries are only supported in us-central1
GLOSSARY_ID = "hoshirei-ja-en"
INPUT_URI = "gs://<YOUR_BUCKET>/glossaries/glossary_ja_en.tsv"

client = translate.TranslationServiceClient()
name = client.glossary_path(PROJECT_ID, LOCATION, GLOSSARY_ID)
glossary = translate.Glossary(
    name=name,
    # Unidirectional (ja→en) glossary
    language_pair=translate.Glossary.LanguageCodePair(
        source_language_code="ja", target_language_code="en"
    ),
    input_config=translate.GlossaryInputConfig(
        gcs_source=translate.GcsSource(input_uri=INPUT_URI)
    ),
)
parent = f"projects/{PROJECT_ID}/locations/{LOCATION}"
operation = client.create_glossary(parent=parent, glossary=glossary)
result = operation.result(180)   # Wait up to 180 seconds for completion
print(f"Creation complete: {result.name} (entry count: {result.entry_count})")
python setup_glossary.py
# Example output
Creation complete: projects/.../locations/us-central1/glossaries/hoshirei-ja-en (entry count: 20)

The official documentation also explicitly states that custom resources must use us-central1.

Note: All of your resources in a single request to Cloud Translation - Advanced must have the same location. Currently, only global and us-central1 locations are supported. For all custom resources—AutoML models, glossaries, long-running-operations—you must use us-central1.

Cited from: Official documentation: Migrate to Cloud Translation - Advanced (v3) | Google Cloud

5.3 Comparing With and Without the Glossary

Translate with the glossary specified.
Passing the glossary ID created in 5.2 to --glossary-id returns both a "without glossary" and "with glossary" result in a single response.
The fixed translations in the following translation results and speaker notes—such as 星霊 becoming Hoshirei and 星導士 becoming Starwright—correspond to these registered entries.

python translate_document_handson.py \
    --project <YOUR_PROJECT_ID> \
    --input hoshirei_ja.pptx \
    --output hoshirei_en.pptx \
    --glossary-id <YOUR_GLOSSARY_ID>

Looking at the results without a glossary first, the translations of proper nouns were inconsistent (per Claude's analysis).
Counting the translations of 星霊, which appears 16 times in the source (including speaker notes), without a glossary, the main translation variants were as follows:

Translation of 星霊 (without glossary) Occurrences
Star Spirit 6
Star Spirits 4
star spirit 2
Celestial Spirit 2
star spirits 1
Other variants Several

The same word was split across multiple variants, including differences in capitalization and singular/plural forms.

Switching to the glossary version, this was neatly unified.
The title slide is where the translation visibly changed.

Comparison without/with glossary (PowerPoint slide 1)
Left is without glossary (title reads "Star Spirit Story"), right is with glossary ("Hoshirei Story"—星霊 is locked to Hoshirei)

With the glossary, 星霊 was fixed to Hoshirei, 守護者 to Warden, 共鳴進化 to Reso-Evolution, and 輝光石 to Lumina Shard, exactly as registered.
The glossary was applied consistently across the entire slide—titles, bullet points, tables, shapes and text box content, and even speaker notes.
For example, 星導士 in the speaker notes was translated as Star Guide (a literal translation) without the glossary, but was fixed to Starwright with the glossary.

After checking the full output with the glossary, all registered coined terms were consistently fixed to their registered translations in the PowerPoint (per Claude's analysis).
In the Word edition, one instance of 星霊 was missed, but in this PowerPoint sample, no remaining literal translations were found.
However, occasional misses can happen depending on context, so it is worth noting that even with a glossary, 100% coverage cannot be guaranteed.

6. Pricing and Processing Time

The pricing for document translation varies depending on the translation model used.
For the standard NMT model, document translation is charged per page, and in PowerPoint, each slide counts as a page.

Item Unit Price
NMT document translation $0.08 / page

Cited from: Pricing page: Pricing | Google Cloud

The cost for this sample (7 slides), including both the with-glossary and without-glossary runs, was well under $1.
The processing time was approximately 1–2 seconds in practice.

7. About the Attribution Notice ("Machine Translated by Google")

In the PDF edition, "Machine Translated by Google" appeared in the upper left of the translated PDF.
For this PowerPoint (PPTX), even without explicitly specifying attribution, this notice was not visible in the translated file (the same was true for Word and Excel).
Since the presence or absence of this notice differed between PDF and Office formats under the same conditions, I checked the specification.

The attribution text can be specified as customizedAttribution in the API request, and the default when not specified is "Machine Translated by Google."
This field is not PDF-specific; it is common to translateDocument (document translation) as a whole.

customizedAttribution string

Optional. This flag is to support user customized attribution. If not provided, the default is Machine Translated by Google. Customized attribution should follow rules in https://cloud.google.com/translate/attribution#attribution_and_logos

Cited from: API reference: Method: projects.locations.translateDocument | Google Cloud

What is important to note here is that customizedAttribution only describes the attribution text itself—there is no explicit statement in the official documentation about how or whether that text is reflected in the output of each format (i.e., whether it is baked into the file).
The reason why the presence of the attribution notice differs by format could not be confirmed from official sources.
Within the scope of my testing, the attribution notice was baked into the PDF output (confirmed with a native PDF in the PDF edition) but was not included in Office format outputs (DOCX/XLSX/PPTX).
My assumption is that this is because PDF output reconstructs the translated text overlaid on the page to preserve the layout—a fundamentally different output construction process from editable Office formats—but this is not backed by official documentation.

Another important point on a separate axis is the explicit obligation under the brand guidelines.
This is separate from whether the notice is "baked into the output file": it requires that when you show translation results to users, regardless of format, you make it clear that the content is machine-translated.

Whenever you display translation results from Google Translate directly to users, you must make it clear to users that they are viewing automatic translations from Google Translate using the appropriate text or brand elements.

Cited from: Brand guidelines: Attribution requirements | Google Cloud

In other words, the fact that the attribution notice is not baked into the Office format output is not itself a problem, but when publishing or distributing translation results, regardless of format, it is the user's responsibility to make it clear that the content is machine-translated.

8. Summary (Comparison Across the Series)

PowerPoint (PPTX) translates not only titles, bullet points, and tables, but also the content inside shapes and text boxes as well as speaker notes, and the glossary is applied consistently to all of these.
What is not translated are charts (embedded charts) and figures pasted as images.

Here is a summary table of the differences discovered by translating all three formats—Word, Excel, and PowerPoint—throughout this series.

Element Word (DOCX) Excel (XLSX) PowerPoint (PPTX)
Body text, tables, data Translated Translated Translated
Content inside text boxes and shapes Not translated Not translated Translated
Charts (title, axes, legend) Not translated Not translated
Formulas Preserved and recalculated (string literals inside formulas are not translated)
Speaker notes Translated
Glossary Applied consistently Applied consistently Applied consistently

The biggest difference is in how content inside text boxes and shapes is handled.
In Word and Excel, it is not translated and remains in Japanese, whereas in PowerPoint, it is translated.
Depending on how a document is structured, this affects decisions about where to place text before translation.

  • Word/Excel: Place text you want translated in the body text or table cells rather than in text boxes
  • PowerPoint: Text placed in shapes or text boxes will be translated. What is not translated are charts and figures pasted as images

It was also common across all formats that charts are not translated.
If you want to translate chart titles or legends, you will need to prepare them separately as text before converting them to a chart image.

Throughout this series, it was confirmed that PDF, Word, Excel, and PowerPoint can all be translated while preserving their layouts, and that custom terminology can be largely locked in with a glossary.
It seems best to understand the format of the document you are working with and how shapes and charts are used, so you can identify any areas that need manual attention before or after translation.

I hope this series is useful for those considering automating the translation of Office documents.

References

Share this article