---
title: "How to build a Flutter PDF viewer with flutter_pdfview"
canonical_url: "https://www.nutrient.io/blog/how-to-build-a-flutter-pdf-viewer/"
md_url: "https://www.nutrient.io/blog/how-to-build-a-flutter-pdf-viewer.md"
last_updated: "2026-07-10T11:16:05.891Z"
description: "Build a Flutter PDF viewer step by step with flutter_pdfview — covering setup, zooming, scrolling, and page navigation, plus when to reach for Nutrient."
---

**TL;DR**

This guide shows how to build a Flutter PDF viewer from scratch. It compares open source packages like `flutter_pdfview`, walks through integration steps (dependencies, configuration, and widget creation), and covers page navigation, zooming, and dragging. It also covers the options available through Nutrient’s Flutter PDF editor.

This post will walk you through the process of setting up a basic PDF viewer in Flutter to handle single-page documents.

[Flutter](https://flutter.dev/) is an open source framework developed by Google that allows for creating natively compiled applications for mobile, web, and desktop from a single codebase in [Dart](https://dart.dev/language).

First, you’ll choose a package for PDF viewing from the open source options. Then you’ll integrate it into a Flutter project to get a working PDF viewer app.

## Choosing the right PDF package for Flutter

When selecting a PDF library for Flutter, evaluate your requirements against package quality and functionality. For simple use cases, an open source library is a good starting point. For more advanced needs, Nutrient offers a [Flutter PDF editor](https://www.nutrient.io/sdk/flutter/).

To find suitable packages, [searching for `pdf`](https://pub.dev/flutter/packages?q=pdf&platform=android+ios) on [pub.dev](https://pub.dev) reveals many options. Key factors to consider include:

- **Pub points** — Reflects the quality of the package based on static analysis, including support for null safety and adherence to Dart conventions.

- **Popularity** — Indicates the number of developers using the package.

- **Update frequency** — A recent update date often signifies an actively maintained project.

- **Verified publisher** — Some packages come from verified publishers.

Among the search results, the following packages are noteworthy:

- [`flutter_pdfview`](https://pub.dev/packages/flutter_pdfview) — A Flutter plugin that provides a `PDFView` widget on Android and iOS

- [`native_pdf_view`](https://pub.dev/packages/native_pdf_view) — A Flutter plugin for rendering PDF files on web, macOS, Windows, Android, and iOS (now published as `pdfx`)

- [`advance_pdf_viewer`](https://pub.dev/packages/advance_pdf_viewer) — A Flutter plugin for handling PDF files

Of the three packages, `flutter_pdfview` fits a simple PDF viewer best. It ships an example in its [GitHub repository](https://github.com/endigo/flutter_pdfview), the configuration steps are short, and on Android, it’s built on a Google library called [PDFium](https://pdfium.googlesource.com/pdfium/), which [we use at Nutrient too](https://www.nutrient.io/blog/contributing-to-pdfium/). (On iOS, it renders with Apple’s PDFKit.)

## Building a PDF viewer with flutter_pdfview

`flutter_pdfview` renders PDFs on both Android and iOS. It displays PDF files inside your Flutter app and supports page navigation, zooming, and more. It exposes [configuration options](https://github.com/endigo/flutter_pdfview#options) to customize the experience, and there’s an [example app](https://github.com/endigo/flutter_pdfview/tree/master/example) in the [GitHub repository](https://github.com/endigo/flutter_pdfview).

To keep the use case simple, this post will use `flutter_pdfview` to show a single-page PDF document on an Android device with [API 30](https://developer.android.com/about/versions/).

The app’s main layout is a widget that shows the rendered PDF and supports pinch-to-zoom and dragging the zoomed page.

### Getting started

Make sure [Flutter is installed](https://docs.flutter.dev/) and set up on your development machine. Check it by running:

```bash

flutter doctor

```

This command will verify if you have everything in place to start developing with Flutter.

### Step 1 — Creating a new Flutter project

Begin by creating a new Flutter project. Open your terminal and run:

```bash

flutter create pdf_viewer_app

```

Navigate to your project directory:

```bash

cd pdf_viewer_app

```

### Step 2 — Adding the flutter_pdfview dependency

Next, add the `flutter_pdfview` package to your `pubspec.yaml` file under dependencies:

```diff...
dependencies:
  flutter:
    sdk: flutter

+ flutter_pdfview: ^1.2.7...

```

Be careful with the above, as spaces matter in YAML files.

Run `flutter pub get` to install the package.

### Step 3 — Updating the Android and iOS configurations

For Android, ensure your `minSdkVersion` is at least 21 in `android/app/build.gradle`:

```groovy

defaultConfig {...
    minSdkVersion 21...
}

```

For iOS, enable Swift support by adding the following to your `ios/Podfile`:

```ruby

platform :ios, '12.0'

```

Then, install the dependencies:

```bash

cd ios
pod install
cd..

```

### Step 4 — Creating the PDF viewer widget

Now you’ll create the PDF viewer widget. Open `lib/main.dart` and replace its content with the following code:

```dart

import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'dart:async';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PDFScreen(),
    );
  }
}

class PDFScreen extends StatefulWidget {
  @override
  _PDFScreenState createState() => _PDFScreenState();
}

class _PDFScreenState extends State<PDFScreen> {
  String? _localPath;
  int? _totalPages = 0;
  int? _currentPage = 0;
  bool pdfReady = false;
  late PDFViewController _pdfViewController;

  @override
  void initState() {
    super.initState();
    fromAsset('assets/sample.pdf', 'sample.pdf').then((file) {
      setState(() {
        _localPath = file.path;
        pdfReady = true;
      });
    });
  }

  Future<File> fromAsset(String asset, String fileName) async {
    final byteData = await rootBundle.load(asset);
    final file = File('${(await getTemporaryDirectory()).path}/$fileName');
    await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
    return file;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PDF Viewer'),
        actions: _totalPages!= null? <Widget>[
                Center(child: Text('${_currentPage! + 1} / $_totalPages')),
                IconButton(
                  icon: Icon(Icons.chevron_left),
                  onPressed: () {
                    setState(() {
                      _currentPage = (_currentPage! - 1).clamp(0, _totalPages! - 1);
                    });
                    _pdfViewController.setPage(_currentPage!);
                  },
                ),
                IconButton(
                  icon: Icon(Icons.chevron_right),
                  onPressed: () {
                    setState(() {
                      _currentPage = (_currentPage! + 1).clamp(0, _totalPages! - 1);
                    });
                    _pdfViewController.setPage(_currentPage!);
                  },
                ),
              ]
            : null,
      ),
      body: pdfReady? PDFView(
              filePath: _localPath,
              enableSwipe: true,
              swipeHorizontal: true,
              autoSpacing: false,
              pageFling: false,
              onRender: (_pages) {
                setState(() {
                  _totalPages = _pages;
                });
              },
              onViewCreated: (PDFViewController vc) {
                _pdfViewController = vc;
              },
              onPageChanged: (page, total) {
                setState(() {
                  _currentPage = page;
                });
              },
              onError: (error) {
                print(error.toString());
              },
              onPageError: (page, error) {
                print('$page: ${error.toString()}');
              },
            )
          : Center(child: CircularProgressIndicator()),
    );
  }
}

```

### Step 5 — Adding a sample PDF

Add a [sample PDF document](https://www.nutrient.io/downloads/pspdfkit-flutter-quickstart-guide.pdf) named `sample.pdf` to your `assets` folder. If the folder doesn’t exist, create it in the root directory of your project. Then, update your `pubspec.yaml` file to include the assets:

```diff

flutter:

+  assets:

+    - assets/sample.pdf

```

### Step 6 — Running the app

To run the PDF viewer, make sure to connect a physical Android device or open an emulator from the [Android Virtual Device Manager](https://developer.android.com/studio/run/managing-avds). Then from the command line, type:

```bash

flutter run

```

After a short building process, the PDF viewer app will be ready to use on the Android device. 🎉

## Troubleshooting and error handling

The following sections outline errors you may encounter and how to deal with them.

### flutter_pdfview isn’t displaying the PDF

- Ensure the `flutter_pdfview` dependency is installed by running:

```bash

flutter pub get

```

- Confirm the PDF file is correctly located in the `assets` folder and properly referenced in `pubspec.yaml`.

- For Android, check that `minSdkVersion` is set to `21` or higher.

### iOS: Podfile issues

- Run `pod install` inside the `ios` directory if you’re encountering issues with missing dependencies.

- Ensure `platform :ios, '12.0'` is set in `ios/Podfile`.

### App crashes when loading PDF

- Confirm you’ve granted necessary storage permissions on Android.

- Use `try-catch` blocks around file loading logic to handle potential errors.

## Cons of flutter_pdfview for advanced features

While `flutter_pdfview` is a solid package for rendering PDFs in Flutter, it does have certain limitations when it comes to advanced features.

### Uneven cross-platform support

`flutter_pdfview` supports pinch-to-zoom (via the `minZoom`/`maxZoom` options and `PDFViewController.setScale`), but several other options — including `fitPolicy`, `nightMode`, `pageSnap`, and `onPageError` — work on Android only. Behavior can differ across platforms, so you may need per-platform handling.

### Limited page navigation

While basic page navigation (like swiping between pages) is supported, there’s no built-in support for more advanced navigation controls like a page slider, page jump, or navigation bar. You need to implement custom controls for these features manually.

### No native support for annotations or form filling

`flutter_pdfview` doesn’t have built-in support for adding annotations or filling out forms within the PDF. You can use additional packages such as [`pdf_render`](https://pub.dev/packages/pdf_render) or [`pdf_text`](https://pub.dev/packages/pdf_text) to manipulate the content, but combining them with `flutter_pdfview` to render the updated content requires additional development work.

### No text selection or search functionality

Text selection and search aren’t natively supported in `flutter_pdfview`. To enable text search and selection, you’ll need to extract the text using packages like [`pdf_text`](https://pub.dev/packages/pdf_text) and build a custom search and selection system. This adds complexity to the implementation.

These limitations mean that `flutter_pdfview` might not be the best fit if you require these advanced features for your Flutter PDF viewer. You may need to consider other solutions or integrate additional libraries for a full-featured experience.

## Conclusion

This post covered some factors to look at when selecting a PDF package from a set of open source packages, and it showed how to build a PDF viewer using the open source Flutter PDF library, [`flutter_pdfview`](https://github.com/endigo/flutter_pdfview), which is good for solving simple use cases without too much hassle. However, [`AndroidPdfViewer`](https://github.com/barteksc/AndroidPdfViewer) — the library [`flutter_pdfview`](https://github.com/endigo/flutter_pdfview) is based on — has seen only intermittent maintenance, and older releases were published to [JCenter](https://developer.android.com/studio/build/jcenter-migration), an artifact repository that’s now read-only.

For more complex customization, Nutrient offers its own [Flutter PDF library](https://www.nutrient.io/guides/flutter.md) with a detailed [getting started](https://www.nutrient.io/sdk/flutter/getting-started.md) guide. Nutrient ships with many features out of the box, including:

- A [customizable UI] that’s simple and easy to use.

- Embeddable prebuilt tools to easily add functionality like [annotating documents](https://www.nutrient.io/guides/flutter/annotations.md), [filling and signing forms](https://www.nutrient.io/guides/flutter/signatures.md), and much more.

- Multiple file type support — from image files (JPG, PNG, and TIFF) to PDF documents.

It also features [active development cycles](https://www.nutrient.io/guides/flutter/changelog.md) with constant improvements and bug fixes. To get started with Nutrient Flutter SDK, check out our [free trial](https://www.nutrient.io/try/). If you have any questions about our Flutter PDF library, please don’t hesitate to [reach out to us](https://www.nutrient.io/support/request/). We’re happy to help!

**Recommended reading**: Start with [Flutter PDF creation](https://www.nutrient.io/blog/create-and-edit-pdfs-in-flutter.md), explore [React Native alternatives](https://www.nutrient.io/blog/react-native-pdf-libraries/), or learn about [advanced PDF features](https://www.nutrient.io/guides/flutter/annotations.md).

## FAQ

#### How do I choose the right PDF package for Flutter?

When selecting a PDF package, consider factors like pub points, popularity, update frequency, and whether the package supports your required features. Popular packages for Flutter include `flutter_pdfview`, `native_pdf_view`, and `advance_pdf_viewer`.

#### How do I integrate flutter_pdfview into my Flutter project?

To integrate `flutter_pdfview`, add it to your `pubspec.yaml` dependencies, include [`path_provider`](https://pub.dev/packages/path_provider) for file management, run `flutter pub get`, set the Android `minSdkVersion` and iOS Podfile platform, and add your PDF document to the project’s assets.

#### What are the main features of flutter_pdfview?

`flutter_pdfview` provides a widget for rendering PDFs in Flutter applications. It supports basic functionalities like viewing PDF documents with pinch-to-zoom and page navigation. It uses the `AndroidPdfViewer` library under the hood for rendering.

#### Can I customize the PDF viewer with flutter_pdfview?

`flutter_pdfview` offers some configuration options to customize the viewing experience, such as setting up page zoom and scrolling. For more extensive customization, consider using more advanced libraries or integrating with tools like Nutrient.

#### What should I do if I encounter issues with flutter_pdfview?

If you face issues with `flutter_pdfview`, check the [GitHub repository](https://github.com/endigo/flutter_pdfview) for troubleshooting tips and open issues. For more complex needs, consider alternative solutions like [Nutrient Flutter SDK](https://www.nutrient.io/sdk/flutter/), which offers additional support and features.

## Related reading

- [How to build a React Native PDF viewer](https://www.nutrient.io/blog/how-to-build-a-react-native-pdf-viewer.md) — Cross-platform PDF viewing with React Native

- [Build an Android PDF viewer using Nutrient](https://www.nutrient.io/blog/how-to-build-an-android-pdf-viewer.md) — Step-by-step Android PDF viewer guide

- [Top five document viewers for developers](https://www.nutrient.io/blog/top-doc-viewers/) — Compare DOCX and PDF viewer libraries side by side

Explore all available platforms on the [mobile SDK overview](https://www.nutrient.io/sdk/mobile-overview/).
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [1. Extract and chunk the PDF.](/blog/chat-with-pdf.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [Fillable Pdf](/blog/fillable-pdf.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Dotnet Maui Pdf Viewer](/blog/how-to-build-a-dotnet-maui-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [How To Build A Javascript Pdf Viewer](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [or](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [or](/blog/how-to-convert-html-to-pdf-using-react.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [or](/blog/how-to-create-a-react-js-signature-pad.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Extract Tables From Pdf And Images](/blog/how-to-extract-tables-from-pdf-and-images.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [Open an image.](/blog/how-to-use-tesseract-ocr-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Javascript Pdf Libraries](/blog/javascript-pdf-libraries.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [Pdf Extraction Benchmark Opendataloader Bench](/blog/pdf-extraction-benchmark-opendataloader-bench.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [or](/blog/sample-blog-updated.md)
- [Add DWS MCP Server to your Claude Code project.](/blog/teaching-llms-to-read-pdfs.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

