{"id":30263146,"url":"https://github.com/armakuni/gatsby-source-guru","last_synced_at":"2026-01-20T17:52:43.206Z","repository":{"id":307804908,"uuid":"1030774186","full_name":"armakuni/gatsby-source-guru","owner":"armakuni","description":"🚀 A Gatsby source plugin for fetching content from GetGuru knowledge base and creating pages from your cards","archived":false,"fork":false,"pushed_at":"2025-08-11T22:31:41.000Z","size":13364,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-12T00:22:12.733Z","etag":null,"topics":["cms","gatsby","gatsby-plugin","gatsby-source-plugin","getguru","guru","javascript","knowledge-base","nodejs","typescript"],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/armakuni.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-02T09:46:01.000Z","updated_at":"2025-08-11T22:31:44.000Z","dependencies_parsed_at":"2025-08-02T11:02:29.417Z","dependency_job_id":null,"html_url":"https://github.com/armakuni/gatsby-source-guru","commit_stats":null,"previous_names":["armakuni/gatsby-source-guru"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/armakuni/gatsby-source-guru","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fgatsby-source-guru","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fgatsby-source-guru/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fgatsby-source-guru/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fgatsby-source-guru/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/armakuni","download_url":"https://codeload.github.com/armakuni/gatsby-source-guru/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fgatsby-source-guru/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270631759,"owners_count":24619379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-15T02:00:12.559Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cms","gatsby","gatsby-plugin","gatsby-source-plugin","getguru","guru","javascript","knowledge-base","nodejs","typescript"],"created_at":"2025-08-15T21:06:04.660Z","updated_at":"2026-01-20T17:52:43.172Z","avatar_url":"https://github.com/armakuni.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gatsby-source-guru\n\nA Gatsby source plugin for fetching content from [GetGuru](https://www.getguru.com/) knowledge base and creating pages from your cards.\n\n## Features\n\n- 🚀 **Fetch cards** from GetGuru API with collection-based authentication\n- 📝 **Convert HTML to Markdown** using Turndown for better Gatsby integration\n- 🖼️ **Download attachments** and optimise for static hosting\n- 🔗 **Convert internal links** between Guru cards to local page routes\n- ⚡ **GraphQL integration** with typed nodes for queries\n- 🛡️ **Error handling** with detailed logging and fallbacks\n\n## Installation\n\n```bash\nnpm install gatsby-source-guru\n# or\nyarn add gatsby-source-guru\n```\n\n## Configuration\n\nAdd the plugin to your `gatsby-config.js`:\n\n```javascript\nmodule.exports = {\n  plugins: [\n    {\n      resolve: 'gatsby-source-guru',\n      options: {\n        // Required: Your Guru collection ID\n        collectionId: 'your-collection-id',\n        \n        // Required: Authentication - choose one method\n        \n        // Option 1: Collection-based auth (recommended)\n        authMode: 'collection',\n        collectionToken: process.env.GURU_COLLECTION_TOKEN,\n        \n        // Option 2: User-based auth  \n        // authMode: 'user',\n        // apiUsername: process.env.GURU_API_USERNAME,\n        // apiPassword: process.env.GURU_API_PASSWORD,\n        // teamName: process.env.GURU_TEAM_NAME,\n        \n        // Optional: Download settings\n        downloadAttachments: true,        // Download card attachments\n        attachmentsDir: 'static/guru-attachments', // Where to save files\n        \n        // Optional: Content processing\n        convertToMarkdown: true,          // Convert HTML to Markdown\n        processInternalLinks: true,       // Convert Guru links to local routes\n        \n        // Optional: Debugging\n        verbose: false                    // Enable detailed logging\n      }\n    }\n  ]\n}\n```\n\n## Environment Variables\n\nCreate a `.env` file in your project root:\n\n```bash\n# Collection-based authentication (recommended)\nGURU_COLLECTION_TOKEN=your-collection-token\n\n# OR User-based authentication\n# GURU_API_USERNAME=your-username\n# GURU_API_PASSWORD=your-password\n# GURU_TEAM_NAME=your-team-name\n```\n\n## Usage\n\n### GraphQL Queries\n\nThe plugin creates `GuruCard` nodes that you can query:\n\n```graphql\nquery {\n  allGuruCard {\n    nodes {\n      id\n      title\n      content          # Processed content (HTML or Markdown)\n      markdownContent  # Markdown version (if enabled)\n      htmlContent      # Original HTML content\n      slug             # URL-friendly slug\n      lastModified\n      dateCreated\n      owner {\n        firstName\n        lastName\n        email\n      }\n      collection {\n        name\n        id\n      }\n      attachments {\n        filename\n        url\n        localPath      # Path to downloaded file\n      }\n    }\n  }\n}\n```\n\n### Creating Pages\n\nUse the data in `gatsby-node.js` to create pages:\n\n```javascript\nconst path = require('path')\n\nexports.createPages = async ({ graphql, actions, reporter }) =\u003e {\n  const { createPage } = actions\n  \n  const result = await graphql(`\n    query {\n      allGuruCard {\n        nodes {\n          id\n          slug\n          title\n          content\n        }\n      }\n    }\n  `)\n  \n  if (result.errors) {\n    reporter.panicOnBuild('Error loading Guru cards', result.errors)\n    return\n  }\n  \n  const cardTemplate = path.resolve('./src/templates/card.js')\n  \n  result.data.allGuruCard.nodes.forEach(card =\u003e {\n    createPage({\n      path: `/pages/${card.slug}/`,\n      component: cardTemplate,\n      context: {\n        id: card.id,\n        title: card.title\n      }\n    })\n  })\n}\n```\n\n### Page Template Example\n\nCreate `src/templates/card.js`:\n\n```jsx\nimport React from 'react'\nimport { graphql } from 'gatsby'\nimport Layout from '../components/layout'\n\nconst CardTemplate = ({ data }) =\u003e {\n  const card = data.guruCard\n  \n  return (\n    \u003cLayout\u003e\n      \u003carticle\u003e\n        \u003cheader\u003e\n          \u003ch1\u003e{card.title}\u003c/h1\u003e\n          \u003cp\u003e\n            By {card.owner.firstName} {card.owner.lastName} • \n            Last updated: {new Date(card.lastModified).toLocaleDateString()}\n          \u003c/p\u003e\n        \u003c/header\u003e\n        \n        \u003cdiv dangerouslySetInnerHTML={{ __html: card.content }} /\u003e\n        \n        {card.attachments?.length \u003e 0 \u0026\u0026 (\n          \u003csection\u003e\n            \u003ch3\u003eAttachments\u003c/h3\u003e\n            {card.attachments.map(attachment =\u003e (\n              \u003ca \n                key={attachment.filename} \n                href={attachment.localPath || attachment.url}\n                download\n              \u003e\n                {attachment.filename}\n              \u003c/a\u003e\n            ))}\n          \u003c/section\u003e\n        )}\n      \u003c/article\u003e\n    \u003c/Layout\u003e\n  )\n}\n\nexport const query = graphql`\n  query($id: String!) {\n    guruCard(id: { eq: $id }) {\n      id\n      title\n      content\n      markdownContent\n      lastModified\n      owner {\n        firstName\n        lastName\n        email\n      }\n      attachments {\n        filename\n        url\n        localPath\n      }\n    }\n  }\n`\n\nexport default CardTemplate\n```\n\n## Authentication Methods\n\n### Collection-Based (Recommended)\n\nBest for CI/CD and team environments:\n\n1. Get your collection ID from Guru dashboard\n2. Create a collection token in Guru settings\n3. Use username + token authentication\n\n### User-Based\n\nFor development or personal use:\n\n1. Use your Guru email and password\n2. Less secure, not recommended for production\n\n## Content Processing\n\n### HTML to Markdown Conversion\n\nWhen `convertToMarkdown: true`, the plugin converts HTML content to Markdown using [Turndown](https://github.com/domchristie/turndown). This provides:\n\n- Better integration with Markdown-based Gatsby workflows\n- Cleaner content for search indexing\n- Easier content manipulation\n\n### Internal Link Processing\n\nThe plugin automatically converts internal Guru card links to local page routes:\n\n```html\n\u003c!-- Original Guru link --\u003e\n\u003ca href=\"https://app.getguru.com/card/abc123/My-Card\"\u003eMy Card\u003c/a\u003e\n\n\u003c!-- Converted to local route --\u003e\n\u003ca href=\"/pages/my-card/\"\u003eMy Card\u003c/a\u003e\n```\n\n### Attachment Handling\n\nFiles are downloaded and stored locally:\n\n- **Images**: Available for Gatsby image optimisation\n- **Documents**: Served as static assets\n- **Public files**: Direct download links maintained\n- **Private files**: Downloaded for local serving\n\n## Configuration Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `collectionId` | string | **required** | Your Guru collection ID |\n| `authMode` | string | `'collection'` | Authentication method: `'collection'` or `'user'` |\n| `guruUsername` | string | - | Username for collection auth |\n| `guruToken` | string | - | Token for collection auth |\n| `guruEmail` | string | - | Email for user auth |\n| `guruPassword` | string | - | Password for user auth |\n| `downloadAttachments` | boolean | `true` | Download card attachments |\n| `attachmentsDir` | string | `'static/guru-attachments'` | Directory for downloaded files |\n| `convertToMarkdown` | boolean | `true` | Convert HTML to Markdown |\n| `processInternalLinks` | boolean | `true` | Process internal Guru links |\n| `verbose` | boolean | `false` | Enable detailed logging |\n\n## Troubleshooting\n\n### Authentication Issues\n\n```\nError: Unauthorized (401)\n```\n\n- Verify your credentials in `.env`\n- Check collection ID is correct\n- Ensure token has proper permissions\n\n### Module Not Found\n\n```\nCannot find module 'turndown'\n```\n\n- Run `npm install` or `yarn install`\n- Ensure `turndown` is in dependencies\n\n### No Cards Found\n\n```\nFound 0 cards via search\n```\n\n- Verify collection has published cards\n- Check collection permissions\n- Enable `verbose: true` for detailed logs\n\n### Build Failures\n\n```\nError building static HTML\n```\n\n- Check for client-side only code in templates\n- Verify GraphQL queries match schema\n- Use `gatsby clean` to clear cache\n\n## Development\n\n### Local Development\n\n```bash\n# Clone the repository\ngit clone https://github.com/armakuni/ak-way.git\ncd ak-way/plugins/gatsby-source-guru\n\n# Install dependencies\nnpm install\n\n# Test in a Gatsby project\nnpm link\ncd /path/to/your/gatsby-site\nnpm link gatsby-source-guru\n```\n\n### Testing\n\n```bash\n# Run tests\nnpm test\n\n# Test with different auth methods\nGURU_USERNAME=test npm test\n```\n\n## Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests\n5. Submit a pull request\n\n## License\n\nMIT License - see [LICENSE](./LICENSE) file for details.\n\n## Support\n\n- 📖 [Documentation](https://github.com/armakuni/ak-way/tree/main/plugins/gatsby-source-guru)\n- 🐛 [Issues](https://github.com/armakuni/ak-way/issues)\n- 💬 [Discussions](https://github.com/armakuni/ak-way/discussions)\n\n## Related\n\n- [Gatsby](https://www.gatsbyjs.com/) - Static site generator\n- [GetGuru](https://www.getguru.com/) - Knowledge management platform\n- [Turndown](https://github.com/domchristie/turndown) - HTML to Markdown converter\n\n---\n\nBuilt with ❤️ by [Armakuni](https://armakuni.com)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farmakuni%2Fgatsby-source-guru","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farmakuni%2Fgatsby-source-guru","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farmakuni%2Fgatsby-source-guru/lists"}