Read any article on the internet in your preferred language. Shift extracts article content from web pages and translates it while preserving formatting, images, and typography.
- ๐ท๏ธ Web Scraping: Extract clean article content from any URL using Firecrawl
- ๐ Translation: Translate articles to 12+ languages while preserving Markdown formatting
- ๐พ Smart Caching: Articles and translations are cached locally for instant re-access
- ๐จ Beautiful Reading: Clean, minimal reader mode with typography optimized for long-form content
- ๐ Dark Mode: Toggle between light and dark themes
- ๐ฑ Responsive Design: Works perfectly on mobile, tablet, and desktop
- โก Instant Loading: Cached articles load instantly on revisit
- ๐ Language Toggle: Seamlessly switch between original and translated content
- Framework: Next.js 16.1.4 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS 4 (built-in typography support)
- UI Components: shadcn/ui (base-nova style, hugeicons)
- Web Scraping: @mendable/firecrawl-js
- Translation: lingo.dev SDK
- Markdown Rendering: react-markdown with remark-gfm and rehype-highlight
- Syntax Highlighting: react-syntax-highlighter
- Caching: localStorage with timestamp-based cache management
Shift showcases lingo.dev's Markdown translation capabilities. The app demonstrates how lingo.dev can:
- Translate complex Markdown content while preserving formatting
- Handle code blocks, links, images, and rich text structure
- Maintain document structure during translation
- Provide seamless language switching for content-heavy applications
The translation preserves:
- Headers and text hierarchy
- Code blocks with syntax highlighting
- Image references and alt text
- Links and their targets
- Lists, quotes, and other Markdown elements
- Node.js 18+
- pnpm (recommended) or npm/yarn
-
Clone the repository
git clone <repository-url> cd shift-read
-
Install dependencies
pnpm install
-
Set up environment variables
Create a
.env.localfile in the project root:FIRECRAWL_API_KEY=your_firecrawl_api_key_here LINGODOTDEV_API_KEY=your_lingodotdev_api_key_here
-
Get API Keys
- Firecrawl: Sign up at firecrawl.dev to get your API key
- lingo.dev: Sign up at lingo.dev to get your API key
-
Run the development server
pnpm dev
-
Open your browser Navigate to http://localhost:3000
pnpm devStarts the development server with hot reload at http://localhost:3000
pnpm buildCreates an optimized production build
pnpm startRuns the production build at http://localhost:3000
pnpm lintRuns ESLint to check for code issues
Shift supports translation to these languages:
- ๐ช๐ธ Spanish (es)
- ๐ซ๐ท French (fr)
- ๐ฉ๐ช German (de)
- ๐ฏ๐ต Japanese (ja)
- ๐จ๐ณ Chinese (zh)
- ๐ธ๐ฆ Arabic (ar)
- ๐ฎ๐ณ Hindi (hi)
- ๐ต๐น Portuguese (pt)
- ๐ท๐บ Russian (ru)
- ๐ฐ๐ท Korean (ko)
- ๐ฎ๐น Italian (it)
- ๐ณ๐ฑ Dutch (nl)
The source language is automatically detected and filtered from the translation options.
shift-read/
โโโ app/
โ โโโ page.tsx # Homepage with URL input
โ โโโ layout.tsx # Root layout with providers
โ โโโ globals.css # Global styles (Tailwind v4)
โ โโโ read/[...url]/
โ โ โโโ page.tsx # Reading page with article display
โ โโโ actions/
โ โโโ fetchContent.ts # Firecrawl server action
โ โโโ translate.ts # lingo.dev server action
โ โโโ cleanMarkdown.ts # Markdown cleanup utilities
โโโ components/
โ โโโ ArticleHeader.tsx # Title, author, date, image display
โ โโโ LanguageSelector.tsx # Language dropdown
โ โโโ MDXRender.tsx # Markdown renderer with custom components
โ โโโ ThemeToggle.tsx # Dark/light mode toggle
โโโ lib/
โ โโโ utils.ts # Utility functions
โ โโโ storage.ts # localStorage helpers
โโโ README.md
โโโ package.json
โโโ next.config.ts
โโโ tsconfig.json
- URL Input: User enters an article URL on the homepage
- Content Extraction: Firecrawl scrapes the URL and extracts clean Markdown content
- Caching: Article is cached in localStorage for instant future access
- Translation: User can select a target language and lingo.dev translates the content
- Display: Article is rendered with beautiful typography and preserved formatting
- Toggle: Users can switch between original and translated content seamlessly
- Homepage: URL validation, navigation, theme toggle
- Content Extraction: Test with Medium, Substack, personal blogs
- Translation: Verify language selection and translation quality
- Caching: Confirm instant loading of cached articles
- Responsive: Test on mobile, tablet, desktop
- Dark Mode: Verify all components work in both themes
# Medium articles
https://medium.com/@author/article-title
# Substack articles
https://author.substack.com/p/article-title
# Personal blogs
https://example.com/blog/article-titleThe next.config.ts file allows external images from any HTTPS domain:
images: {
remotePatterns: [
{
protocol: 'https',
hostname: '**',
},
],
}Required environment variables:
FIRECRAWL_API_KEY= # Firecrawl API key for web scraping
LINGODOTDEV_API_KEY= # lingo.dev API key for translationIssue: "Failed to extract article content"
- Solution: Check Firecrawl API key and ensure URL is accessible
Issue: "Translation failed"
- Solution: Verify lingo.dev API key and target language code
Issue: Images not loading
- Solution: Ensure images are served over HTTPS (Next.js requirement)
Issue: Styling issues
- Solution: Clear browser cache and restart dev server
Add debug logging by setting:
DEBUG=shift:*This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
If you have any questions or issues, please open an issue on the GitHub repository.
Built with โค๏ธ using Next.js, Tailwind CSS, Firecrawl, and lingo.dev