diff --git a/site/.markdowndb/files.json b/site/.markdowndb/files.json new file mode 100644 index 000000000..cc74531c4 --- /dev/null +++ b/site/.markdowndb/files.json @@ -0,0 +1,7631 @@ +[ + { + "_id": "1677f29b39bf4fb465d7689c0b6b95fc646fcdbc", + "file_path": "content/config.js", + "extension": "js", + "url_path": "config.js", + "filetype": null, + "metadata": {}, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "6c42d2f694cd9fe881f58ae89b923b0e574775cc", + "file_path": "content/testimonials.json", + "extension": "json", + "url_path": "testimonials.json", + "filetype": null, + "metadata": {}, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "f65acc699d64771262f208e4c7523f2117768531", + "file_path": "content/assets/sidebar.json", + "extension": "json", + "url_path": "assets/sidebar.json", + "filetype": null, + "metadata": {}, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "ba8a20474197a5aedf49bb4ac77243e0955edfbd", + "file_path": "content/assets/sidebar1.json", + "extension": "json", + "url_path": "assets/sidebar1.json", + "filetype": null, + "metadata": {}, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "08a4cbb1be3482aa77c7ef4902fb585dc9f65d84", + "file_path": "content/blog/attribute-relation-file-format-arff.md", + "extension": "md", + "url_path": "blog/attribute-relation-file-format-arff", + "filetype": null, + "metadata": { + "title": "Attribute Relation File Format (ARFF)", + "created": "2018-08-23T00:00:00.000Z", + "authors": [ + "branko-dj" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/attribute-relation-file-format-arff.md", + "to": "blog/mailto:PLU@io.arc.nasa.gov", + "toRaw": "mailto:PLU@io.arc.nasa.gov", + "text": "PLU@io.arc.nasa.gov", + "embed": false, + "internal": true + }, + { + "from": "blog/attribute-relation-file-format-arff.md", + "to": "https://www.openml.org/search?type=data", + "toRaw": "https://www.openml.org/search?type=data", + "text": "openml", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "d6d9d3e25aa57330c59bb6e95a68938063daa6fc", + "file_path": "content/blog/auto-publish-your-datasets-using-travis-ci.md", + "extension": "md", + "url_path": "blog/auto-publish-your-datasets-using-travis-ci", + "filetype": null, + "metadata": { + "title": "Auto-publish your datasets using Travis-CI", + "created": "2018-05-23T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/auto-publish-your-datasets-using-travis-ci.md", + "to": "https://github.com/datasets/dac-crs-codes", + "toRaw": "https://github.com/datasets/dac-crs-codes", + "text": "https://github.com/datasets/dac-crs-codes", + "embed": false, + "internal": false + }, + { + "from": "blog/auto-publish-your-datasets-using-travis-ci.md", + "to": "https://github.com/datahq/datahub-qa/issues/213", + "toRaw": "https://github.com/datahq/datahub-qa/issues/213", + "text": "https://github.com/datahq/datahub-qa/issues/213", + "embed": false, + "internal": false + }, + { + "from": "blog/auto-publish-your-datasets-using-travis-ci.md", + "to": "blog/https:/raw.githubusercontent.com/datahq/datahub-content/master/assets/img/travis-ci-env-vars.png", + "toRaw": "https://raw.githubusercontent.com/datahq/datahub-content/master/assets/img/travis-ci-env-vars.png", + "text": "setting env variable test to overcome some travise specific errors", + "embed": true, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "468a7e6c803c101d77b00a67145fae9907f7e983", + "file_path": "content/blog/automated-kpis-collection-and-visualization-of-the-funnels.md", + "extension": "md", + "url_path": "blog/automated-kpis-collection-and-visualization-of-the-funnels", + "filetype": null, + "metadata": { + "title": "Automated KPIs collection and visualization of the funnels", + "created": "2018-07-10T00:00:00.000Z", + "authors": [ + "branko-dj" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/automated-kpis-collection-and-visualization-of-the-funnels.md", + "to": "https://github.com/datahq/datahub-metrics", + "toRaw": "https://github.com/datahq/datahub-metrics", + "text": "datahub-metrics", + "embed": false, + "internal": false + }, + { + "from": "blog/automated-kpis-collection-and-visualization-of-the-funnels.md", + "to": "https://github.com/datahq/datahub-metrics/blob/master/datapackage.json", + "toRaw": "https://github.com/datahq/datahub-metrics/blob/master/datapackage.json", + "text": "here", + "embed": false, + "internal": false + }, + { + "from": "blog/automated-kpis-collection-and-visualization-of-the-funnels.md", + "to": "https://datahub.io/datahq/datahub-metrics", + "toRaw": "https://datahub.io/datahq/datahub-metrics", + "text": "https://datahub.io/datahq/datahub-metrics", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "3060c5ce13895f61feaad1ff256f8d9b313a2f12", + "file_path": "content/blog/automatically-updated-core-datasets-on-datahub.md", + "extension": "md", + "url_path": "blog/automatically-updated-core-datasets-on-datahub", + "filetype": null, + "metadata": { + "title": "Automatically updated core datasets on DataHub", + "created": "2018-09-05T00:00:00.000Z", + "modified": "2020-06-24T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "core/finance-vix", + "toRaw": "/core/finance-vix", + "text": "VIX - CBOE Volatility Index", + "embed": false, + "internal": true + }, + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "core/natural-gas", + "toRaw": "/core/natural-gas", + "text": "Natural gas prices", + "embed": false, + "internal": true + }, + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "core/oil-prices", + "toRaw": "/core/oil-prices", + "text": "Oil prices", + "embed": false, + "internal": true + }, + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "core/bond-yields-us-10y", + "toRaw": "/core/bond-yields-us-10y", + "text": "10 year US Government Bond Yields", + "embed": false, + "internal": true + }, + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "core/bond-yields-uk-10y", + "toRaw": "/core/bond-yields-uk-10y", + "text": "10 year UK Government Bond Yields", + "embed": false, + "internal": true + }, + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "core/airport-codes", + "toRaw": "/core/airport-codes", + "text": "Airport codes", + "embed": false, + "internal": true + }, + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "core/language-codes", + "toRaw": "/core/language-codes", + "text": "Language codes", + "embed": false, + "internal": true + }, + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "core/population-growth-estimates-and-projections", + "toRaw": "/core/population-growth-estimates-and-projections", + "text": "Population growth estimates and projections", + "embed": false, + "internal": true + }, + { + "from": "blog/automatically-updated-core-datasets-on-datahub.md", + "to": "https://discord.gg/KrRzMKU", + "toRaw": "https://discord.gg/KrRzMKU", + "text": "community chat on :discord: Discord", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "3bf5dcf2a478f767bf48e0006ad05664538ff033", + "file_path": "content/blog/basics-of-metadata-how-it-helps-to-understand-your-data.md", + "extension": "md", + "url_path": "blog/basics-of-metadata-how-it-helps-to-understand-your-data", + "filetype": null, + "metadata": { + "title": "Basics of Metadata: How It Helps Understand Your Data", + "created": "2025-06-02T00:00:00.000Z", + "description": "Learn the basics of metadata—from built-in CSV attributes like filename and media type to simple external files—and see how it makes your data discoverable.", + "authors": [ + "anuveyatsu" + ], + "image": "/static/img/blog/basics-of-metadata-how-it-helps-to-understand-your-data/metadata-iceberg-illustration-vector.png", + "filetype": "blog", + "faqs": [ + { + "question": "What's the difference between data and metadata?", + "answer": "Data is the actual content (the temperature readings in our example), while metadata is information about that content (title, description, license, etc.). Think of data as the story and metadata as the book cover, table of contents, and publication information." + }, + { + "question": "Do I need to create metadata for every data file?", + "answer": "For optimal discoverability and usability, yes. Even minimal metadata (title, description) significantly improves how users and systems interact with your data. The more critical or widely used the dataset, the more metadata you should provide." + }, + { + "question": "What format should I use for metadata files?", + "answer": "Simple formats like YAML or JSON are excellent for most use cases. Choose YAML when human readability is important, and JSON when machine-to-machine interoperability is the priority. For standardized data catalogs, consider using schemas like DCAT, Schema.org, or Frictionless Data descriptors." + }, + { + "question": "Where should metadata files be stored?", + "answer": "Ideally, keep metadata files alongside your data files with a clear naming convention (e.g., `data.csv` and `data.csv.meta.yaml`). This makes it easier to maintain the connection between data and its metadata as both evolve." + }, + { + "question": "How detailed should my metadata be?", + "answer": "Start with the essentials, title, description, and licensing information. Then add more detail based on your users' needs—technical users might need schema information, while researchers might need methodology details and citations." + } + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/basics-of-metadata-how-it-helps-to-understand-your-data.md", + "to": "static/img/blog/basics-of-metadata-how-it-helps-to-understand-your-data/metadata-iceberg-illustration-vector.png", + "toRaw": "/static/img/blog/basics-of-metadata-how-it-helps-to-understand-your-data/metadata-iceberg-illustration-vector.png", + "text": "\"An iceberg showing a small tip labeled 'CSV File' above water and a large submerged base labeled with metadata attributes like title, description, license, timestamps, and keywords.\"", + "embed": true, + "internal": true + }, + { + "from": "blog/basics-of-metadata-how-it-helps-to-understand-your-data.md", + "to": "static/img/blog/basics-of-metadata-how-it-helps-to-understand-your-data/metadata-ingestion-pipeline-steps-diagram.png", + "toRaw": "/static/img/blog/basics-of-metadata-how-it-helps-to-understand-your-data/metadata-ingestion-pipeline-steps-diagram.png", + "text": "\"Five-step metadata ingestion diagram showing Discovery, Parsing, Validation, Transformation, and Indexing stages with simple icons for each.\"", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "37d3c7fbee5d49ffa5f5a390d29efa95ea38e89c", + "file_path": "content/blog/ckan-resource-uploads-via-api.md", + "extension": "md", + "url_path": "blog/ckan-resource-uploads-via-api", + "filetype": null, + "metadata": { + "title": "Enhancing CKAN Resource Uploads via API with Cloudflare R2, Workers, and Queues.", + "description": "Integrating Cloudflare R2 with CKAN revolutionizes resource uploads by enabling direct API-based file storage. Using pre-signed URLs, event-driven processing, and automated metadata updates via Workers and Queues, this approach streamlines uploads, enhances data consistency, and eliminates manual intervention.", + "created": "2025-02-26T00:00:00.000Z", + "authors": [ + "shreyas" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "9931215c37ea25184efa49f5dcf230ccf9ed552d", + "file_path": "content/blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "extension": "md", + "url_path": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons", + "filetype": null, + "metadata": { + "title": "Comparotron: A simple way to visualize and share comparisons", + "created": "2020-03-08T00:00:00.000Z", + "authors": [ + "rufuspollock" + ], + "tags": [ + "Open Data Day", + "Comparotron", + "Labs" + ], + "tasks": [] + }, + "tags": [ + "Open Data Day", + "Comparotron", + "Labs" + ], + "links": [ + { + "from": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "to": "https://github.com/datopian/comparotron", + "toRaw": "https://github.com/datopian/comparotron", + "text": "https://github.com/datopian/comparotron", + "embed": false, + "internal": false + }, + { + "from": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "to": "https://comparotron.datahub.io", + "toRaw": "https://comparotron.datahub.io", + "text": "https://comparotron.datahub.io", + "embed": false, + "internal": false + }, + { + "from": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "to": "blog/https:/f.cloud.github.com/assets/180658/750549/198722d0-e4d0-11e2-8a57-998f68acfeaf.png", + "toRaw": "https://f.cloud.github.com/assets/180658/750549/198722d0-e4d0-11e2-8a57-998f68acfeaf.png", + "text": "The first mockup of the idea (by David McCandless) done for the Where Does My Money Go", + "embed": true, + "internal": false + }, + { + "from": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "to": "static/img/blog/comparotron-v0.2-march-2020-coronavirus-vs-flu.svg", + "toRaw": "/static/img/blog/comparotron-v0.2-march-2020-coronavirus-vs-flu.svg", + "text": "Coronavirus (COVID-19) vs Flu Mortality Rates", + "embed": true, + "internal": true + }, + { + "from": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "to": "static/img/blog/comparotron-v0.2-march-2020-military-vs-aid.svg", + "toRaw": "/static/img/blog/comparotron-v0.2-march-2020-military-vs-aid.svg", + "text": "US Spending on Military vs Aid", + "embed": true, + "internal": true + }, + { + "from": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "to": "static/img/blog/comparotron-v0.2-march-2020-military-vs-aid.svg", + "toRaw": "/static/img/blog/comparotron-v0.2-march-2020-military-vs-aid.svg", + "text": "US Spending on Military vs Aid", + "embed": true, + "internal": true + }, + { + "from": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "to": "static/img/blog/comparotron-v0.2-march-2020-coronavirus-vs-flu.svg", + "toRaw": "/static/img/blog/comparotron-v0.2-march-2020-coronavirus-vs-flu.svg", + "text": "Coronavirus (COVID-19) vs Flu Mortality Rates", + "embed": true, + "internal": true + }, + { + "from": "blog/comparotron-a-simple-way-to-visualize-and-share-comparisons.md", + "to": "blog/toc", + "toRaw": "toc", + "text": "", + "embed": false, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "4a2b7d7ab03cf0597b811931a67fa675180ad852", + "file_path": "content/blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "extension": "md", + "url_path": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists", + "filetype": null, + "metadata": { + "title": "Core Data: Essential Datasets for Data Wranglers and Data Scientists", + "created": "2017-11-03T00:00:00.000Z", + "authors": [ + "rufuspollock", + "mikanebu", + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core", + "toRaw": "https://datahub.io/core", + "text": "https://datahub.io/core", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/docs/core-data", + "toRaw": "https://datahub.io/docs/core-data", + "text": "https://datahub.io/docs/core-data", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/country-list", + "toRaw": "https://datahub.io/core/country-list", + "text": "https://datahub.io/core/country-list", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/country-list/r/data.csv", + "toRaw": "https://datahub.io/core/country-list/r/data.csv", + "text": "https://datahub.io/core/country-list/r/data.csv", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/country-list/r/data.json", + "toRaw": "https://datahub.io/core/country-list/r/data.json", + "text": "https://datahub.io/core/country-list/r/data.json", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/country-codes", + "toRaw": "https://datahub.io/core/country-codes", + "text": "https://datahub.io/core/country-codes", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/country-codes/r/country-codes.csv", + "toRaw": "https://datahub.io/core/country-codes/r/country-codes.csv", + "text": "https://datahub.io/core/country-codes/r/country-codes.csv", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/country-codes/r/country-codes.json", + "toRaw": "https://datahub.io/core/country-codes/r/country-codes.json", + "text": "https://datahub.io/core/country-codes/r/country-codes.json", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/population", + "toRaw": "https://datahub.io/core/population", + "text": "https://datahub.io/core/population", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/population/r/population.csv", + "toRaw": "https://datahub.io/core/population/r/population.csv", + "text": "https://datahub.io/core/population/r/population.csv", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/population/r/population.json", + "toRaw": "https://datahub.io/core/population/r/population.json", + "text": "https://datahub.io/core/population/r/population.json", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/country-list/r/data.csv", + "toRaw": "https://datahub.io/core/country-list/r/data.csv", + "text": "https://datahub.io/core/country-list/r/data.csv", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core/country-list/r/data.json", + "toRaw": "https://datahub.io/core/country-list/r/data.json", + "text": "https://datahub.io/core/country-list/r/data.json", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/docs/getting-started/getting-data", + "toRaw": "https://datahub.io/docs/getting-started/getting-data", + "text": "https://datahub.io/docs/getting-started/getting-data", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/docs/getting-started/getting-data", + "toRaw": "https://datahub.io/docs/getting-started/getting-data", + "text": "https://datahub.io/docs/getting-started/getting-data", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/core", + "toRaw": "https://datahub.io/core", + "text": "https://datahub.io/core", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "https://datahub.io/docs/core-data/curators", + "toRaw": "https://datahub.io/docs/core-data/curators", + "text": "https://datahub.io/docs/core-data/curators", + "embed": false, + "internal": false + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "static/img/docs/country-list-preview-table.png", + "toRaw": "/static/img/docs/country-list-preview-table.png", + "text": "preview table for the dataset on the showcase page", + "embed": true, + "internal": true + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "static//docs/country-list-downloads.png", + "toRaw": "/static//docs/country-list-downloads.png", + "text": "download it in either CSV or JSON formats", + "embed": true, + "internal": true + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "static/img/docs/population-preview-table.png", + "toRaw": "/static/img/docs/population-preview-table.png", + "text": "Preview the population data on the showcase page", + "embed": true, + "internal": true + }, + { + "from": "blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists.md", + "to": "blog/toc", + "toRaw": "toc", + "text": "", + "embed": false, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "acf1d50a650142253fb7960d3e01fabeada6ccb1", + "file_path": "content/blog/covid19-and-compartmental-models-in-epidemiology.md", + "extension": "md", + "url_path": "blog/covid19-and-compartmental-models-in-epidemiology", + "filetype": null, + "metadata": { + "title": "COVID-19 and Compartmental Models in Epidemiology", + "created": "2020-05-08T00:00:00.000Z", + "authors": [ + "rufuspollock" + ], + "tags": [ + "COVID-19", + "epidemiology", + "models", + "curve-fitting", + "epidemic" + ], + "tasks": [] + }, + "tags": [ + "COVID-19", + "epidemiology", + "models", + "curve-fitting", + "epidemic" + ], + "links": [ + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://github.com/CSSEGISandData", + "toRaw": "https://github.com/CSSEGISandData", + "text": "CSSEGISandData", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://github.com/nties/COVID19-open-research-dataset", + "toRaw": "https://github.com/nties/COVID19-open-research-dataset", + "text": "on GitHub", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://www.kaggle.com/sudalairajkumar/novel-corona-virus-2019-dataset", + "toRaw": "https://www.kaggle.com/sudalairajkumar/novel-corona-virus-2019-dataset", + "text": "on Kaggle", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://www.medrxiv.org/content/10.1101/2020.03.20.20040048v1", + "toRaw": "https://www.medrxiv.org/content/10.1101/2020.03.20.20040048v1", + "text": "SEIR model", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://github.com/datasets/awesome-data/blob/master/coronavirus.md", + "toRaw": "https://github.com/datasets/awesome-data/blob/master/coronavirus.md", + "text": "on this page", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://datahub.io/core/covid-19", + "toRaw": "https://datahub.io/core/covid-19", + "text": "time series", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://en.wikipedia.org/wiki/Basic_reproduction_number", + "toRaw": "https://en.wikipedia.org/wiki/Basic_reproduction_number", + "text": "basic reproduction number", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://www.medrxiv.org/content/10.1101/2020.03.09.20033357v1", + "toRaw": "https://www.medrxiv.org/content/10.1101/2020.03.09.20033357v1", + "text": "Fergusson et al.", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://github.com/DataForScience/Epidemiology101", + "toRaw": "https://github.com/DataForScience/Epidemiology101", + "text": "Epidemiology101", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "http://www.gleamviz.org/", + "toRaw": "http://www.gleamviz.org/", + "text": "Gleamviz model", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://github.com/datasciencecampus/google-mobility-reports-data/", + "toRaw": "https://github.com/datasciencecampus/google-mobility-reports-data/", + "text": "mobility data", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://covid19.gleamproject.org/mobility", + "toRaw": "https://covid19.gleamproject.org/mobility", + "text": "Gleamproject", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://medium.com/data-for-science/visualizing-the-spread-of-covid-19-a4ea21ee8e46", + "toRaw": "https://medium.com/data-for-science/visualizing-the-spread-of-covid-19-a4ea21ee8e46", + "text": "here", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "https://www.coronawhy.org/cord19", + "toRaw": "https://www.coronawhy.org/cord19", + "text": "coronawhy", + "embed": false, + "internal": false + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "static/img/blog/2020-05-05-covid19-models/edward-howell-IDhks1n8GYM-unsplash.jpg", + "toRaw": "/static/img/blog/2020-05-05-covid19-models/edward-howell-IDhks1n8GYM-unsplash.jpg", + "text": "Man sleeping on a bus during the COVID-19 outbreak in London", + "embed": true, + "internal": true + }, + { + "from": "blog/covid19-and-compartmental-models-in-epidemiology.md", + "to": "static/img/blog/2020-05-05-covid19-models/sirmodel_beta_mu_parameters.png", + "toRaw": "/static/img/blog/2020-05-05-covid19-models/sirmodel_beta_mu_parameters.png", + "text": "sirmodel-beta-mu-parameters", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "ebe1d4a99792d8d66849565718bcac64c8a020b3", + "file_path": "content/blog/create-a-simple-catalog-of-anything-using-markdown.md", + "extension": "md", + "url_path": "blog/create-a-simple-catalog-of-anything-using-markdown", + "filetype": null, + "metadata": { + "title": "Create a catalog of anything using Markdown files in Obsidian", + "created": "2023-05-30T00:00:00.000Z", + "authors": [ + "Ola Rubaj" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "https://obsidian.md/", + "toRaw": "https://obsidian.md/", + "text": "official website", + "embed": false, + "internal": false + }, + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "https://github.com/blacksmithgu/obsidian-dataview", + "toRaw": "https://github.com/blacksmithgu/obsidian-dataview", + "text": "\"Dataview\" plugin", + "embed": false, + "internal": false + }, + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "https://github.com/datopian/markdowndb/tree/main/examples/obsidian-dataview", + "toRaw": "https://github.com/datopian/markdowndb/tree/main/examples/obsidian-dataview", + "text": "vault created in this tutorial here", + "embed": false, + "internal": false + }, + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/dataview.gif", + "toRaw": "/static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/dataview.gif", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/table1.png", + "toRaw": "/static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/table1.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/table2.png", + "toRaw": "/static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/table2.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/harry_original.png", + "toRaw": "/static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/harry_original.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/harry.png", + "toRaw": "/static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/harry.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/create-a-simple-catalog-of-anything-using-markdown.md", + "to": "static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/link-preview.png", + "toRaw": "/static/img/blog/2023-05-30-Create-a-catalog-of-anything-using-markdown-files/link-preview.png", + "text": "", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "c5b29504d139596edd2b1204c12951c5de5918f8", + "file_path": "content/blog/create-a-website-from-scratch.md", + "extension": "md", + "url_path": "blog/create-a-website-from-scratch", + "filetype": null, + "metadata": { + "title": "Tutorial 1: Create a website from scratch using Markdown and Flowershow", + "created": "2023-06-20T00:00:00.000Z", + "authors": [ + "Ola Rubaj" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/create-a-website-from-scratch.md", + "to": "https://github.com/", + "toRaw": "https://github.com/", + "text": "GitHub", + "embed": false, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "https://vercel.com/", + "toRaw": "https://vercel.com/", + "text": "Vercel", + "embed": false, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "https://github.com/datopian/flowershow", + "toRaw": "https://github.com/datopian/flowershow", + "text": "datopian/flowershow repository", + "embed": false, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "https://vercel.com/dashboard", + "toRaw": "https://vercel.com/dashboard", + "text": "your Vercel dashboard", + "embed": false, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/35cb9df6-d93e-4ce6-9741-54be744cf9e7/55ca0e14-6780-40e3-9ecc-148a7fa7c08e.png?crop=focalpoint&fit=crop&fp-x=0.0945&fp-y=0.4783&fp-z=2.5970&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=162&mark-y=440&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0yNjUmaD03MiZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/35cb9df6-d93e-4ce6-9741-54be744cf9e7/55ca0e14-6780-40e3-9ecc-148a7fa7c08e.png?crop=focalpoint&fit=crop&fp-x=0.0945&fp-y=0.4783&fp-z=2.5970&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=162&mark-y=440&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0yNjUmaD03MiZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 2 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/bdd61961-e1fe-4282-abec-75ae66bfeaa5/85df39b9-51a8-410a-a83b-93f2d2d6256c.png?crop=focalpoint&fit=crop&fp-x=0.2455&fp-y=0.4226&fp-z=1.4615&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=94&mark-y=427&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NzQmaD05OSZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/bdd61961-e1fe-4282-abec-75ae66bfeaa5/85df39b9-51a8-410a-a83b-93f2d2d6256c.png?crop=focalpoint&fit=crop&fp-x=0.2455&fp-y=0.4226&fp-z=1.4615&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=94&mark-y=427&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NzQmaD05OSZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 3 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/879ebed5-fec7-443e-8be9-66b73a4ec044/583f8a42-fc35-43d8-b791-70e22976ed46.png?crop=focalpoint&fit=crop&fp-x=0.2455&fp-y=0.5030&fp-z=1.5031&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=113&mark-y=429&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NTkmaD05NCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/879ebed5-fec7-443e-8be9-66b73a4ec044/583f8a42-fc35-43d8-b791-70e22976ed46.png?crop=focalpoint&fit=crop&fp-x=0.2455&fp-y=0.5030&fp-z=1.5031&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=113&mark-y=429&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NTkmaD05NCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 3 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/61441f7d-ccc4-45ca-b52d-4ccc0573d787/ff97c393-2fff-407e-abe2-bc96c18562cc.png?crop=focalpoint&fit=crop&fp-x=0.2922&fp-y=0.7621&fp-z=2.4427&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=440&mark-y=385&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0zMjEmaD0xMjgmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/61441f7d-ccc4-45ca-b52d-4ccc0573d787/ff97c393-2fff-407e-abe2-bc96c18562cc.png?crop=focalpoint&fit=crop&fp-x=0.2922&fp-y=0.7621&fp-z=2.4427&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=440&mark-y=385&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0zMjEmaD0xMjgmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 3 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/d2382391-f4bc-4ffe-b8e8-e22b9f6550ad/f4817109-ae2e-49f9-98ad-2f8dfe9a5b3b.png?crop=focalpoint&fit=crop&fp-x=0.2455&fp-y=0.5833&fp-z=1.5031&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=113&mark-y=429&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NTkmaD05NCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/d2382391-f4bc-4ffe-b8e8-e22b9f6550ad/f4817109-ae2e-49f9-98ad-2f8dfe9a5b3b.png?crop=focalpoint&fit=crop&fp-x=0.2455&fp-y=0.5833&fp-z=1.5031&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=113&mark-y=429&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NTkmaD05NCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 3 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/a9b6af4c-4645-4b93-9c28-75d23e7f48a3/55dcaf47-8851-4808-ab9e-6fe6c4d552aa.png?crop=focalpoint&fit=crop&fp-x=0.6919&fp-y=0.4929&fp-z=1.7767&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=57&mark-y=416&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMDg2Jmg9MTIxJmZpdD1jcm9wJmNvcm5lci1yYWRpdXM9MTA%3D", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/a9b6af4c-4645-4b93-9c28-75d23e7f48a3/55dcaf47-8851-4808-ab9e-6fe6c4d552aa.png?crop=focalpoint&fit=crop&fp-x=0.6919&fp-y=0.4929&fp-z=1.7767&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=57&mark-y=416&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMDg2Jmg9MTIxJmZpdD1jcm9wJmNvcm5lci1yYWRpdXM9MTA%3D", + "text": "Step 4 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/ae740310-736d-48e5-9fbf-cf567a2ff966/2bc653a7-0e6c-4eaa-a11b-85a2a4d4c1d3.png?crop=focalpoint&fit=crop&fp-x=0.5007&fp-y=0.5152&fp-z=1.0564&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=33&mark-y=379&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMTM0Jmg9MTk1JmZpdD1jcm9wJmNvcm5lci1yYWRpdXM9MTA%3D", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/ae740310-736d-48e5-9fbf-cf567a2ff966/2bc653a7-0e6c-4eaa-a11b-85a2a4d4c1d3.png?crop=focalpoint&fit=crop&fp-x=0.5007&fp-y=0.5152&fp-z=1.0564&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=33&mark-y=379&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMTM0Jmg9MTk1JmZpdD1jcm9wJmNvcm5lci1yYWRpdXM9MTA%3D", + "text": "Step 5 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/1df8967e-2bcf-43ec-b3d0-a9d638d21ff7/af6d363d-2872-4a45-b5e5-16ca754e4702.png?crop=focalpoint&fit=crop&fp-x=0.5005&fp-y=0.3351&fp-z=1.8197&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=328&mark-y=414&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz01NDUmaD0xMjQmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/1df8967e-2bcf-43ec-b3d0-a9d638d21ff7/af6d363d-2872-4a45-b5e5-16ca754e4702.png?crop=focalpoint&fit=crop&fp-x=0.5005&fp-y=0.3351&fp-z=1.8197&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=328&mark-y=414&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz01NDUmaD0xMjQmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 6 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/319f8eef-5007-4885-a3d6-6dc7fd7472ea/80b34413-f7da-4765-90d6-89a93fb4eab5.png?crop=focalpoint&fit=crop&fp-x=0.0697&fp-y=0.3482&fp-z=2.5500&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=72&mark-y=390&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0yODImaD0xNzQmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/9bef984b-9dd1-4c07-ae32-88bb426c306e/steps/319f8eef-5007-4885-a3d6-6dc7fd7472ea/80b34413-f7da-4765-90d6-89a93fb4eab5.png?crop=focalpoint&fit=crop&fp-x=0.0697&fp-y=0.3482&fp-z=2.5500&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=72&mark-y=390&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0yODImaD0xNzQmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 6 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/5b5166f4-2965-4a91-9bec-47108fe34234/steps/adecdf18-e46a-4003-984e-1dc1945963df/6792cf00-20fc-4e24-88ca-8d35a41aadab.png?crop=focalpoint&fit=crop&fp-x=0.9589&fp-y=0.0345&fp-z=3.0108&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=992&mark-y=53&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMjAmaD05MiZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/5b5166f4-2965-4a91-9bec-47108fe34234/steps/adecdf18-e46a-4003-984e-1dc1945963df/6792cf00-20fc-4e24-88ca-8d35a41aadab.png?crop=focalpoint&fit=crop&fp-x=0.9589&fp-y=0.0345&fp-z=3.0108&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=992&mark-y=53&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMjAmaD05MiZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 1 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/5b5166f4-2965-4a91-9bec-47108fe34234/steps/8578ff07-5dc9-4908-bc81-197293970344/9b01a3fb-47fe-48ed-a7bc-c9910e9e42ef.png?crop=focalpoint&fit=crop&fp-x=0.8963&fp-y=0.1997&fp-z=2.9422&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=553&mark-y=420&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz01NjImaD0xMTImZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/5b5166f4-2965-4a91-9bec-47108fe34234/steps/8578ff07-5dc9-4908-bc81-197293970344/9b01a3fb-47fe-48ed-a7bc-c9910e9e42ef.png?crop=focalpoint&fit=crop&fp-x=0.8963&fp-y=0.1997&fp-z=2.9422&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=553&mark-y=420&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz01NjImaD0xMTImZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 1 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/b7f96b7d-28b1-4366-b889-681b327b5f40/a0d2bffd-2e81-4878-854b-0766cf710339.png?crop=focalpoint&fit=crop&fp-x=0.2578&fp-y=0.4408&fp-z=1.3063&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=39&mark-y=274&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz03MzAmaD00MDQmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/b7f96b7d-28b1-4366-b889-681b327b5f40/a0d2bffd-2e81-4878-854b-0766cf710339.png?crop=focalpoint&fit=crop&fp-x=0.2578&fp-y=0.4408&fp-z=1.3063&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=39&mark-y=274&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz03MzAmaD00MDQmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 1 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/2cfbda16-23dc-45b2-9be9-a4b5b3a255d1/da2be1ca-da13-4257-a830-3ece2b89ff51.png?crop=focalpoint&fit=crop&fp-x=0.4560&fp-y=0.4590&fp-z=1.1707&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=321&mark-y=313&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0yMjYmaD04MCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/2cfbda16-23dc-45b2-9be9-a4b5b3a255d1/da2be1ca-da13-4257-a830-3ece2b89ff51.png?crop=focalpoint&fit=crop&fp-x=0.4560&fp-y=0.4590&fp-z=1.1707&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=321&mark-y=313&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0yMjYmaD04MCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 1 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/4ce5b74e-40e5-4c3f-a3ce-be7fa8959489/25b9ddc8-c1df-44f8-bf3e-7d08960f0592.png?crop=focalpoint&fit=crop&fp-x=0.0900&fp-y=0.4574&fp-z=2.8680&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=226&mark-y=441&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xNjgmaD03MCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/4ce5b74e-40e5-4c3f-a3ce-be7fa8959489/25b9ddc8-c1df-44f8-bf3e-7d08960f0592.png?crop=focalpoint&fit=crop&fp-x=0.0900&fp-y=0.4574&fp-z=2.8680&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=226&mark-y=441&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xNjgmaD03MCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 2 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/b14c059d-89e4-419b-8ac4-0e219ed195af/4d86a32a-b5f8-48d1-bccd-ddbfd140fe5a.png?crop=focalpoint&fit=crop&fp-x=0.0754&fp-y=0.4711&fp-z=2.7997&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=157&mark-y=442&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xOTImaD02OCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/b14c059d-89e4-419b-8ac4-0e219ed195af/4d86a32a-b5f8-48d1-bccd-ddbfd140fe5a.png?crop=focalpoint&fit=crop&fp-x=0.0754&fp-y=0.4711&fp-z=2.7997&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=157&mark-y=442&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xOTImaD02OCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 3 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/e4d28cd5-3863-46e3-813d-5304ec0d769f/ce2bf765-9bef-4d96-8354-0eed3aa88c03.png?crop=focalpoint&fit=crop&fp-x=0.9435&fp-y=0.3449&fp-z=2.9525&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=945&mark-y=422&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMDkmaD0xMDkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/e4d28cd5-3863-46e3-813d-5304ec0d769f/ce2bf765-9bef-4d96-8354-0eed3aa88c03.png?crop=focalpoint&fit=crop&fp-x=0.9435&fp-y=0.3449&fp-z=2.9525&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=945&mark-y=422&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMDkmaD0xMDkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 3 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/daad6528-db93-426c-8b8b-ae67d0a28189/a5767c01-a16e-4c4b-b4a0-5595663b175d.png?crop=focalpoint&fit=crop&fp-x=0.5170&fp-y=0.3762&fp-z=1.0470&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=7&mark-y=300&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMTg2Jmg9MTUwJmZpdD1jcm9wJmNvcm5lci1yYWRpdXM9MTA%3D", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/daad6528-db93-426c-8b8b-ae67d0a28189/a5767c01-a16e-4c4b-b4a0-5595663b175d.png?crop=focalpoint&fit=crop&fp-x=0.5170&fp-y=0.3762&fp-z=1.0470&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=7&mark-y=300&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMTg2Jmg9MTUwJmZpdD1jcm9wJmNvcm5lci1yYWRpdXM9MTA%3D", + "text": "Step 3 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/74159a33-2897-4ffb-af3d-ce2fa109e570/0e96f7a4-b4ff-418e-9b44-73573a4354d1.png?crop=focalpoint&fit=crop&fp-x=0.9227&fp-y=0.2208&fp-z=2.9167&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=696&mark-y=417&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz00NjgmaD0xMTkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/74159a33-2897-4ffb-af3d-ce2fa109e570/0e96f7a4-b4ff-418e-9b44-73573a4354d1.png?crop=focalpoint&fit=crop&fp-x=0.9227&fp-y=0.2208&fp-z=2.9167&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=696&mark-y=417&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz00NjgmaD0xMTkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 4 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/09130863-221f-436e-bab0-a46bea2fd5c4/bdbd1458-3b5c-4352-a8fb-5921132ee3e4.png?crop=focalpoint&fit=crop&fp-x=0.4998&fp-y=0.3476&fp-z=1.4555&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=262&mark-y=447&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NzYmaD01OCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/09130863-221f-436e-bab0-a46bea2fd5c4/bdbd1458-3b5c-4352-a8fb-5921132ee3e4.png?crop=focalpoint&fit=crop&fp-x=0.4998&fp-y=0.3476&fp-z=1.4555&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=262&mark-y=447&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NzYmaD01OCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 4 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/40bf87e4-a2b1-4a99-97da-5e87530d0622/88a19d05-ce63-4da0-9e85-e427b063245e.png?crop=focalpoint&fit=crop&fp-x=0.5545&fp-y=0.5989&fp-z=1.3207&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=612&mark-y=616&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0yMDcmaD01NSZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/40bf87e4-a2b1-4a99-97da-5e87530d0622/88a19d05-ce63-4da0-9e85-e427b063245e.png?crop=focalpoint&fit=crop&fp-x=0.5545&fp-y=0.5989&fp-z=1.3207&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=612&mark-y=616&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0yMDcmaD01NSZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 4 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/0d273173-d852-47e4-b41e-418b9196e0fd/fbf1afe6-7af3-4b06-8ab0-d3c41d2923ce.png?crop=focalpoint&fit=crop&fp-x=0.5000&fp-y=0.5000&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/0d273173-d852-47e4-b41e-418b9196e0fd/fbf1afe6-7af3-4b06-8ab0-d3c41d2923ce.png?crop=focalpoint&fit=crop&fp-x=0.5000&fp-y=0.5000&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n", + "text": "Step 5 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/94b4e4ab-458c-4be9-b7a9-e34c7b4185b9/645687a4-b91d-4870-a935-48403b8ce33c.png?crop=focalpoint&fit=crop&fp-x=0.5000&fp-y=0.5000&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/94b4e4ab-458c-4be9-b7a9-e34c7b4185b9/645687a4-b91d-4870-a935-48403b8ce33c.png?crop=focalpoint&fit=crop&fp-x=0.5000&fp-y=0.5000&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n", + "text": "Step 5 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/a1294580-7d0d-492c-a880-32040b4bee48/5e7ddd43-03e3-4545-b1b3-cd631da401d8.png?crop=focalpoint&fit=crop&fp-x=0.2207&fp-y=0.3824&fp-z=1.4465&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=43&mark-y=261&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NzkmaD00MzEmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/4aa9bd80-6829-415e-b3a8-6136bfb176eb/steps/a1294580-7d0d-492c-a880-32040b4bee48/5e7ddd43-03e3-4545-b1b3-cd631da401d8.png?crop=focalpoint&fit=crop&fp-x=0.2207&fp-y=0.3824&fp-z=1.4465&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=43&mark-y=261&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NzkmaD00MzEmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 6 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/1708e4fa-8234-4393-a8e9-cd972afce770/b986ab26-d53f-4b57-8520-fb87782dfb22.png?crop=focalpoint&fit=crop&fp-x=0.9119&fp-y=0.2208&fp-z=2.9167&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=737&mark-y=417&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0zMDkmaD0xMTkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/1708e4fa-8234-4393-a8e9-cd972afce770/b986ab26-d53f-4b57-8520-fb87782dfb22.png?crop=focalpoint&fit=crop&fp-x=0.9119&fp-y=0.2208&fp-z=2.9167&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=737&mark-y=417&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0zMDkmaD0xMTkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 2 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/e79d32ef-9385-4903-8ca1-408f78752633/7006ac1c-796c-4bb6-95ef-dd4d9969c9b6.png?crop=focalpoint&fit=crop&fp-x=0.8712&fp-y=0.2679&fp-z=2.9167&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=476&mark-y=417&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz01NDcmaD0xMTkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/e79d32ef-9385-4903-8ca1-408f78752633/7006ac1c-796c-4bb6-95ef-dd4d9969c9b6.png?crop=focalpoint&fit=crop&fp-x=0.8712&fp-y=0.2679&fp-z=2.9167&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=476&mark-y=417&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz01NDcmaD0xMTkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 2 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/54c786cb-15d6-4abe-8893-fa95dff3ed0a/c39152b2-f446-4e39-a2f3-9b3cf0e7c193.png?crop=focalpoint&fit=crop&fp-x=0.3476&fp-y=0.2214&fp-z=2.1864&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=394&mark-y=418&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz00MTMmaD04NyZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/54c786cb-15d6-4abe-8893-fa95dff3ed0a/c39152b2-f446-4e39-a2f3-9b3cf0e7c193.png?crop=focalpoint&fit=crop&fp-x=0.3476&fp-y=0.2214&fp-z=2.1864&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=394&mark-y=418&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz00MTMmaD04NyZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 3 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/8ffe1e8c-45f9-42b7-8053-bc8bc61b098c/56489034-d5a9-495e-8fb7-1fbfff62d7f3.png?crop=focalpoint&fit=crop&fp-x=0.5170&fp-y=0.3440&fp-z=1.0470&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=7&mark-y=300&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMTg2Jmg9ODYmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/8ffe1e8c-45f9-42b7-8053-bc8bc61b098c/56489034-d5a9-495e-8fb7-1fbfff62d7f3.png?crop=focalpoint&fit=crop&fp-x=0.5170&fp-y=0.3440&fp-z=1.0470&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=7&mark-y=300&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0xMTg2Jmg9ODYmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 4 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/382d133d-19f3-4aee-a0fa-535fcb361090/fe7b1fc6-c8f0-4f3f-958a-204c4fc65cf8.png?crop=focalpoint&fit=crop&fp-x=0.9227&fp-y=0.2208&fp-z=2.9167&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=696&mark-y=417&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz00NjgmaD0xMTkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "toRaw": "https://images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/382d133d-19f3-4aee-a0fa-535fcb361090/fe7b1fc6-c8f0-4f3f-958a-204c4fc65cf8.png?crop=focalpoint&fit=crop&fp-x=0.9227&fp-y=0.2208&fp-z=2.9167&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=696&mark-y=417&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz00NjgmaD0xMTkmZml0PWNyb3AmY29ybmVyLXJhZGl1cz0xMA%3D%3D", + "text": "Step 5 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/13c5873d-4071-4ae2-b641-d6202631076c/53029856-5543-4681-919a-092ed2dacb02.png?crop=focalpoint&fit=crop&fp-x=0.4998&fp-y=0.3476&fp-z=1.4555&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=262&mark-y=447&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NzYmaD01OCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/13c5873d-4071-4ae2-b641-d6202631076c/53029856-5543-4681-919a-092ed2dacb02.png?crop=focalpoint&fit=crop&fp-x=0.4998&fp-y=0.3476&fp-z=1.4555&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=262&mark-y=447&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz02NzYmaD01OCZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 5 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "blog/https:/images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/68002c21-451a-4536-89b6-8a0d01d327eb/bb71cbb3-7a79-45f3-a71e-2500a380556c.png?crop=focalpoint&fit=crop&fp-x=0.6278&fp-y=0.7315&fp-z=2.3207&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=418&mark-y=428&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0zNjUmaD05NyZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "toRaw": "https://images.tango.us/workflows/c14ae6dc-9e15-49f5-af87-b513daa701ba/steps/68002c21-451a-4536-89b6-8a0d01d327eb/bb71cbb3-7a79-45f3-a71e-2500a380556c.png?crop=focalpoint&fit=crop&fp-x=0.6278&fp-y=0.7315&fp-z=2.3207&w=1200&border=2%2CF4F2F7&border-radius=8%2C8%2C8%2C8&border-radius-inner=8%2C8%2C8%2C8&blend-align=bottom&blend-mode=normal&blend-x=0&blend-w=1200&blend64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL21hZGUtd2l0aC10YW5nby13YXRlcm1hcmstdjIucG5n&mark-x=418&mark-y=428&m64=aHR0cHM6Ly9pbWFnZXMudGFuZ28udXMvc3RhdGljL2JsYW5rLnBuZz9tYXNrPWNvcm5lcnMmYm9yZGVyPTYlMkNGRjc0NDImdz0zNjUmaD05NyZmaXQ9Y3JvcCZjb3JuZXItcmFkaXVzPTEw", + "text": "Step 5 screenshot", + "embed": true, + "internal": false + }, + { + "from": "blog/create-a-website-from-scratch.md", + "to": "static/img/blog/tutorial-1-result.png", + "toRaw": "/static/img/blog/tutorial-1-result.png", + "text": "", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "64c9f09fb6fc94c982027a91bab6e149addbae71", + "file_path": "content/blog/data-desktop-app-alpha-release.md", + "extension": "md", + "url_path": "blog/data-desktop-app-alpha-release", + "filetype": null, + "metadata": { + "title": "Data desktop app - alpha release with drag and drop data publishing support", + "created": "2017-12-01T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "image": "/static/img/docs/app-cli-update.png", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/data-desktop-app-alpha-release.md", + "to": "https://datahub.io/download", + "toRaw": "https://datahub.io/download", + "text": "https://datahub.io/download", + "embed": false, + "internal": false + }, + { + "from": "blog/data-desktop-app-alpha-release.md", + "to": "static/img/docs/drag-n-drop.gif", + "toRaw": "/static/img/docs/drag-n-drop.gif", + "text": "drag and drop any files (e.g. CSV) or Data Packages (datapackage.json) into the tray icon", + "embed": true, + "internal": true + }, + { + "from": "blog/data-desktop-app-alpha-release.md", + "to": "static/img/docs/app-showcase.png", + "toRaw": "/static/img/docs/app-showcase.png", + "text": "A preview of your dataset. Here you can preview how it would look like online and edit name and title properties for it.", + "embed": true, + "internal": true + }, + { + "from": "blog/data-desktop-app-alpha-release.md", + "to": "static/img/docs/app-field-info.png", + "toRaw": "/static/img/docs/app-field-info.png", + "text": "\"Field Information\" table that contains details from table schema for the data", + "embed": true, + "internal": true + }, + { + "from": "blog/data-desktop-app-alpha-release.md", + "to": "static/img/docs/app-publish.png", + "toRaw": "/static/img/docs/app-publish.png", + "text": "publish your data with go button", + "embed": true, + "internal": true + }, + { + "from": "blog/data-desktop-app-alpha-release.md", + "to": "static/img/docs/app-cli-update.png", + "toRaw": "/static/img/docs/app-cli-update.png", + "text": "to drag and drop publishing the desktop app auto-installs the command line program", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "17a542c1247b8017bdb67fd14c8fb36c5a5767f9", + "file_path": "content/blog/data-validation-in-the-datahub.md", + "extension": "md", + "url_path": "blog/data-validation-in-the-datahub", + "filetype": null, + "metadata": { + "title": "Data Validation in the DataHub", + "created": "2018-01-24T00:00:00.000Z", + "authors": [ + "rufuspollock", + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/data-validation-in-the-datahub.md", + "to": "http://datahub.io/docs/getting-started/publishing-data", + "toRaw": "http://datahub.io/docs/getting-started/publishing-data", + "text": "here", + "embed": false, + "internal": false + }, + { + "from": "blog/data-validation-in-the-datahub.md", + "to": "https://github.com/frictionlessdata/goodtables-py", + "toRaw": "https://github.com/frictionlessdata/goodtables-py", + "text": "goodtables library", + "embed": false, + "internal": false + }, + { + "from": "blog/data-validation-in-the-datahub.md", + "to": "https://frictionlessdata.io/specs/table-schema", + "toRaw": "https://frictionlessdata.io/specs/table-schema", + "text": "https://frictionlessdata.io/specs/table-schema", + "embed": false, + "internal": false + }, + { + "from": "blog/data-validation-in-the-datahub.md", + "to": "static/img/docs/validation-report-vix-daily.png", + "toRaw": "/static/img/docs/validation-report-vix-daily.png", + "text": "Results of the Validation report", + "embed": true, + "internal": true + }, + { + "from": "blog/data-validation-in-the-datahub.md", + "to": "static/img/docs/validation-report-revenue.png", + "toRaw": "/static/img/docs/validation-report-revenue.png", + "text": "validation report revenue", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "f5a3b8c591e50ecdb7b4dbe4433746129a3325fb", + "file_path": "content/blog/datasets-in-zip-format.md", + "extension": "md", + "url_path": "blog/datasets-in-zip-format", + "filetype": null, + "metadata": { + "title": "Datasets in zip format", + "created": "2017-10-19T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/datasets-in-zip-format.md", + "to": "static/img/docs/data-files.png", + "toRaw": "/static/img/docs/data-files.png", + "text": "finance-vix dataset", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "e9bc65008c1506fbdde1857931b451763d96b121", + "file_path": "content/blog/edit-a-website-locally.md", + "extension": "md", + "url_path": "blog/edit-a-website-locally", + "filetype": null, + "metadata": { + "title": "Tutorial 2: Edit your Flowershow website locally on your computer", + "created": "2023-06-22T00:00:00.000Z", + "authors": [ + "Ola Rubaj" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/edit-a-website-locally.md", + "to": "https://en.wikipedia.org/wiki/Markdown", + "toRaw": "https://en.wikipedia.org/wiki/Markdown", + "text": "Markdown", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://en.wikipedia.org/wiki/Markup_language", + "toRaw": "https://en.wikipedia.org/wiki/Markup_language", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://en.wikipedia.org/wiki/Formatted_text", + "toRaw": "https://en.wikipedia.org/wiki/Formatted_text", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://help.obsidian.md/Linking+notes+and+files/Internal+links", + "toRaw": "https://help.obsidian.md/Linking+notes+and+files/Internal+links", + "text": "wiki-links", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://help.obsidian.md/Editing+and+formatting/Callouts", + "toRaw": "https://help.obsidian.md/Editing+and+formatting/Callouts", + "text": "callouts", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://github.com/", + "toRaw": "https://github.com/", + "text": "GitHub", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://vercel.com/", + "toRaw": "https://vercel.com/", + "text": "Vercel", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://obsidian.md/", + "toRaw": "https://obsidian.md/", + "text": "Obsidian", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://desktop.github.com/", + "toRaw": "https://desktop.github.com/", + "text": "GitHub Desktop", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "https://vercel.com/dashboard", + "toRaw": "https://vercel.com/dashboard", + "text": "vercel dashboard", + "embed": false, + "internal": false + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/tutorial-2-result.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/tutorial-2-result.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "blog/create-a-website-from-scratch", + "toRaw": "create-a-website-from-scratch", + "text": "", + "embed": false, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-starting-screen.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-starting-screen.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-clone-signin.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-clone-signin.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-clone.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-clone.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-clone-path-select.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-clone-path-select.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-no-local-changes.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/gh-desktop-no-local-changes.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-starting.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-starting.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "blog/create-a-website-from-scratch", + "toRaw": "create-a-website-from-scratch", + "text": "", + "embed": false, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-start.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-start.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-edit.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-edit.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-add-link.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-add-link.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-add-link-2.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-add-link-2.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-add-folder.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-add-folder.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-add-folder-2.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-add-folder-2.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-book.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-book.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-book-index.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-book-index.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-book-index-2.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-book-index-2.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-book-index-3.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-book-index-3.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-bookshelf-link.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-bookshelf-link.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-link-aliases.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-link-aliases.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-callout.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/obsidian-content-index-callout.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-all-changed-files.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-all-changed-files.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-add-commit-message.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-add-commit-message.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-commit-message.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-commit-message.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-history.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-history.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "blog/create-a-website-from-scratch", + "toRaw": "create-a-website-from-scratch", + "text": "", + "embed": false, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-history-after-push.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/github-desktop-history-after-push.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/vercel-dashboard.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/vercel-dashboard.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/vercel-project-dashboard.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/vercel-project-dashboard.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/tutorial-2-result.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/tutorial-2-result.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/live-book-home-page.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/live-book-home-page.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/edit-a-website-locally.md", + "to": "static/img/blog/2023-06-22-Edit-your-flowershow-website/live-book.png", + "toRaw": "/static/img/blog/2023-06-22-Edit-your-flowershow-website/live-book.png", + "text": "", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "ea0530981da886387414f824b2dfa924b0616a34", + "file_path": "content/blog/effortless-user-management-portaljs.md", + "extension": "md", + "url_path": "blog/effortless-user-management-portaljs", + "filetype": null, + "metadata": { + "title": "Effortless User Management in PortalJS", + "description": "The latest PortalJS user management update makes this process more intuitive.", + "created": "2025-01-28T00:00:00.000Z", + "authors": [ + "popovayoana", + "lucasbispo" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/effortless-user-management-portaljs.md", + "to": "https://cloud.portaljs.com/", + "toRaw": "https://cloud.portaljs.com/", + "text": "Get started now", + "embed": false, + "internal": false + }, + { + "from": "blog/effortless-user-management-portaljs.md", + "to": "images/blog/add-user.webp", + "toRaw": "/images/blog/add-user.webp", + "text": "Add user to organization", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "240aacb5249a4f01b1c9f4851fc172e6c4565605", + "file_path": "content/blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "extension": "md", + "url_path": "blog/enhancing-geospatial-data-visualization-with-portaljs", + "filetype": null, + "metadata": { + "title": "Adding Maps to PortalJS: Enhancing Geospatial Data Visualization with PortalJS", + "created": "2023-07-18T00:00:00.000Z", + "authors": [ + "João Demenech", + "Luccas Mateus", + "Yoana Popova" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/", + "toRaw": "https://portaljs.org/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/", + "toRaw": "https://portaljs.org/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/", + "toRaw": "https://portaljs.org/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/", + "toRaw": "https://portaljs.org/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/", + "toRaw": "https://portaljs.org/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://storybook.portaljs.org/", + "toRaw": "https://storybook.portaljs.org/", + "text": "PortalJS library", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/", + "toRaw": "https://portaljs.org/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/docs", + "toRaw": "https://portaljs.org/docs", + "text": "PortalJS Documentation", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/", + "toRaw": "https://portaljs.org/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://discord.com/invite/EeyfGrGu4U", + "toRaw": "https://discord.com/invite/EeyfGrGu4U", + "text": "Discord channel", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "https://portaljs.org/", + "toRaw": "https://portaljs.org/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "static/img/blog/2023-07-18-Adding-maps-to-portaljs/2023-07-18-map-polygons-and-points.png", + "toRaw": "/static/img/blog/2023-07-18-Adding-maps-to-portaljs/2023-07-18-map-polygons-and-points.png", + "text": "Map with polygons and points", + "embed": true, + "internal": true + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "static/img/blog/2023-07-18-Adding-maps-to-portaljs/2023-07-18-map-tooltips.png", + "toRaw": "/static/img/blog/2023-07-18-Adding-maps-to-portaljs/2023-07-18-map-tooltips.png", + "text": "Map with tooltips", + "embed": true, + "internal": true + }, + { + "from": "blog/enhancing-geospatial-data-visualization-with-portaljs.md", + "to": "static/img/blog/2023-07-18-Adding-maps-to-portaljs/2023-07-18-map-polygons-on-region.png", + "toRaw": "/static/img/blog/2023-07-18-Adding-maps-to-portaljs/2023-07-18-map-polygons-on-region.png", + "text": "Map with polygons over a region", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "9f7feec333b43d6e5d3b40fea4ac7ac2b8aa0341", + "file_path": "content/blog/example-ckan-2021.md", + "extension": "md", + "url_path": "blog/example-ckan-2021", + "filetype": null, + "metadata": { + "title": "Setup Guide: How to create a full-featured custom data portal frontend for CKAN with PortalJS", + "authors": [ + "Luccas Mateus" + ], + "created": "2021-04-20T00:00:00.000Z", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/example-ckan-2021.md", + "to": "https://nextjs.org/docs/basic-features/built-in-css-support", + "toRaw": "https://nextjs.org/docs/basic-features/built-in-css-support", + "text": "https://nextjs.org/docs/basic-features/built-in-css-support", + "embed": false, + "internal": false + }, + { + "from": "blog/example-ckan-2021.md", + "to": "http://portal.datopian1.now.sh/", + "toRaw": "http://portal.datopian1.now.sh/", + "text": "http://portal.datopian1.now.sh/", + "embed": false, + "internal": false + }, + { + "from": "blog/example-ckan-2021.md", + "to": "https://www.apollographql.com/docs/link/links/rest/", + "toRaw": "https://www.apollographql.com/docs/link/links/rest/", + "text": "apollo-link-rest", + "embed": false, + "internal": false + }, + { + "from": "blog/example-ckan-2021.md", + "to": "https://github.com/datopian/portal/blob/master/lib/apolloClient.ts", + "toRaw": "https://github.com/datopian/portal/blob/master/lib/apolloClient.ts", + "text": "lib/apolloClient.ts", + "embed": false, + "internal": false + }, + { + "from": "blog/example-ckan-2021.md", + "to": "https://github.com/datopian/portal/blob/master/pages/_app.tsx", + "toRaw": "https://github.com/datopian/portal/blob/master/pages/_app.tsx", + "text": "pages/_app.tsx", + "embed": false, + "internal": false + }, + { + "from": "blog/example-ckan-2021.md", + "to": "https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm", + "toRaw": "https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm", + "text": "https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm", + "embed": false, + "internal": false + }, + { + "from": "blog/example-ckan-2021.md", + "to": "blog/https:/i.imgur.com/ai0VLS4.png", + "toRaw": "https://i.imgur.com/ai0VLS4.png", + "text": "Datahub Home page", + "embed": true, + "internal": false + }, + { + "from": "blog/example-ckan-2021.md", + "to": "blog/https:/i.imgur.com/3RhXOW4.png", + "toRaw": "https://i.imgur.com/3RhXOW4.png", + "text": "individual dataset page", + "embed": true, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "f993103438c95f7d42e0db6742de1659a0d1b7d7", + "file_path": "content/blog/excel-files-on-the-datahub-automated-previews-and-data-extraction.md", + "extension": "md", + "url_path": "blog/excel-files-on-the-datahub-automated-previews-and-data-extraction", + "filetype": null, + "metadata": { + "title": "Excel Files on the DataHub: Automated Previews and Data Extraction", + "created": "2017-10-16T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/excel-files-on-the-datahub-automated-previews-and-data-extraction.md", + "to": "static/img/docs/showcase-excel-1.png", + "toRaw": "/static/img/docs/showcase-excel-1.png", + "text": "your online data", + "embed": true, + "internal": true + }, + { + "from": "blog/excel-files-on-the-datahub-automated-previews-and-data-extraction.md", + "to": "static/img/docs/showcase-downloads-excel-1.png", + "toRaw": "/static/img/docs/showcase-downloads-excel-1.png", + "text": "download your original data in csv or json", + "embed": true, + "internal": true + }, + { + "from": "blog/excel-files-on-the-datahub-automated-previews-and-data-extraction.md", + "to": "static/img/docs/showcase-preview-excel-1.png", + "toRaw": "/static/img/docs/showcase-preview-excel-1.png", + "text": "preview table of your data", + "embed": true, + "internal": true + }, + { + "from": "blog/excel-files-on-the-datahub-automated-previews-and-data-extraction.md", + "to": "static/img/docs/showcase-excel-2.png", + "toRaw": "/static/img/docs/showcase-excel-2.png", + "text": "By opening the link, you would see the following page", + "embed": true, + "internal": true + }, + { + "from": "blog/excel-files-on-the-datahub-automated-previews-and-data-extraction.md", + "to": "static/img/docs/showcase-downloads-excel-2.png", + "toRaw": "/static/img/docs/showcase-downloads-excel-2.png", + "text": "converted all sheets of the file to CSV so now you can download each of them in CSV or JSON formats", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "0df0196d2c5299f813b77a4b1f8064db1e938aaf", + "file_path": "content/blog/frictionless-specs-european-commission.md", + "extension": "md", + "url_path": "blog/frictionless-specs-european-commission", + "filetype": null, + "metadata": { + "title": "A Short Case Study Involving Table Schema Frictionless Specs at the European Union", + "created": "2021-06-22T00:00:00.000Z", + "authors": [ + "sebastien.lavoie" + ], + "tags": [ + "table-schema", + "frictionless", + "specifications", + "validator", + "tabular-data" + ], + "tasks": [] + }, + "tags": [ + "table-schema", + "frictionless", + "specifications", + "validator", + "tabular-data" + ], + "links": [ + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://joinup.ec.europa.eu/user/73932", + "toRaw": "https://joinup.ec.europa.eu/user/73932", + "text": "Costas Simatos", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://joinup.ec.europa.eu/collection/interoperability-test-bed-repository", + "toRaw": "https://joinup.ec.europa.eu/collection/interoperability-test-bed-repository", + "text": "Interoperability Test Bed", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://www.youtube.com/watch?v=pJFsJW96fuA", + "toRaw": "https://www.youtube.com/watch?v=pJFsJW96fuA", + "text": "available on YouTube", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://joinup.ec.europa.eu/collection/interoperability-test-bed-repository/solution/csvvalidator", + "toRaw": "https://joinup.ec.europa.eu/collection/interoperability-test-bed-repository/solution/csvvalidator", + "text": "CSV validator", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://specs.frictionlessdata.io/table-schema/", + "toRaw": "https://specs.frictionlessdata.io/table-schema/", + "text": "Table Schema specifications", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://datatracker.ietf.org/doc/html/rfc4180", + "toRaw": "https://datatracker.ietf.org/doc/html/rfc4180", + "text": "RFC 4180", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://joinup.ec.europa.eu/collection/interoperability-test-bed-repository/solution/interoperability-test-bed/news/table-schema-validator", + "toRaw": "https://joinup.ec.europa.eu/collection/interoperability-test-bed-repository/solution/interoperability-test-bed/news/table-schema-validator", + "text": "when a beta version of the CSV validator was launched", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://joinup.ec.europa.eu/collection/interoperability-test-bed-repository/solution/interoperability-test-bed/news/test-bed-support-kohesio-pilot", + "toRaw": "https://joinup.ec.europa.eu/collection/interoperability-test-bed-repository/solution/interoperability-test-bed/news/test-bed-support-kohesio-pilot", + "text": "realise the validator for the Kohesio pilot phase of 2014-2020", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://kohesio.eu/", + "toRaw": "https://kohesio.eu/", + "text": "Kohesio", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://joinup.ec.europa.eu/collection/semantic-interoperability-community-semic/solution/kohesio-validator/specification", + "toRaw": "https://joinup.ec.europa.eu/collection/semantic-interoperability-community-semic/solution/kohesio-validator/specification", + "text": "CSV syntax rules", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://github.com/ISAITB/validator-resources-kohesio/blob/master/resources/schemas/schema.json", + "toRaw": "https://github.com/ISAITB/validator-resources-kohesio/blob/master/resources/schemas/schema.json", + "text": "schema used for the CSV validator", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://en.wikipedia.org/wiki/Regular_expression", + "toRaw": "https://en.wikipedia.org/wiki/Regular_expression", + "text": "regular expressions", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://www.itb.ec.europa.eu/docs/guides/latest/validatingCSV/index.html", + "toRaw": "https://www.itb.ec.europa.eu/docs/guides/latest/validatingCSV/index.html", + "text": "documented extensively", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://hub.docker.com/repository/docker/isaitb/validator-kohesio", + "toRaw": "https://hub.docker.com/repository/docker/isaitb/validator-kohesio", + "text": "Docker image", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://www.itb.ec.europa.eu/csv-offline/kohesio/validator.zip", + "toRaw": "https://www.itb.ec.europa.eu/csv-offline/kohesio/validator.zip", + "text": "command-line application", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://www.itb.ec.europa.eu/csv/kohesio/upload", + "toRaw": "https://www.itb.ec.europa.eu/csv/kohesio/upload", + "text": "web application", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "https://www.itb.ec.europa.eu/csv/soap/kohesio/validation?wsdl", + "toRaw": "https://www.itb.ec.europa.eu/csv/soap/kohesio/validation?wsdl", + "text": "SOAP API", + "embed": false, + "internal": false + }, + { + "from": "blog/frictionless-specs-european-commission.md", + "to": "static/img/blog/2021-06-21-frictionless-specs/clark-van-der-beken-596baa0MpyM-unsplash.jpg", + "toRaw": "/static/img/blog/2021-06-21-frictionless-specs/clark-van-der-beken-596baa0MpyM-unsplash.jpg", + "text": "Puzzle texture with negative space", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "182c658e19cfe38f00c122d240832bcd7c5a7465", + "file_path": "content/blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "extension": "md", + "url_path": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown", + "filetype": null, + "metadata": { + "title": "Generate an interactive webpage from CSV data and markdown", + "created": "2022-03-14T00:00:00.000Z", + "authors": [ + "Rising Odegua" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://datahub.io/collections/demographics", + "toRaw": "https://datahub.io/collections/demographics", + "text": "example of a hosted Datahub page", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://github.com/datopian/portal.js/blob/main/examples/data-literate/pages/demo.mdx", + "toRaw": "https://github.com/datopian/portal.js/blob/main/examples/data-literate/pages/demo.mdx", + "text": "this example", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "http://localhost:3000", + "toRaw": "http://localhost:3000", + "text": "http://localhost:3000", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://nextjs.org/docs/deployment#managed-nextjs-with-vercel", + "toRaw": "https://nextjs.org/docs/deployment#managed-nextjs-with-vercel", + "text": "Vercel", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://developers.cloudflare.com/pages/framework-guides/deploy-a-nextjs-site/", + "toRaw": "https://developers.cloudflare.com/pages/framework-guides/deploy-a-nextjs-site/", + "text": "Cloudfare pages", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://www.netlify.com/blog/2021/03/16/try-the-new-essential-next.js-plugin-now-with-auto-install/", + "toRaw": "https://www.netlify.com/blog/2021/03/16/try-the-new-essential-next.js-plugin-now-with-auto-install/", + "text": "Netlify", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://gregrickaby.blog/article/nextjs-github-pages", + "toRaw": "https://gregrickaby.blog/article/nextjs-github-pages", + "text": "Github pages", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://github.com/datopian/next.datahub.io/issues", + "toRaw": "https://github.com/datopian/next.datahub.io/issues", + "text": "here", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://github.com/datopian/portal.js#component-list", + "toRaw": "https://github.com/datopian/portal.js#component-list", + "text": "Portal.js", + "embed": false, + "internal": false + }, + { + "from": "blog/generate-an-interactive-webpage-from-csv-data-and-markdown.md", + "to": "https://datahub.io/collections/air-pollution", + "toRaw": "https://datahub.io/collections/air-pollution", + "text": "Demo page", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "01617110657c241b57363cbc959776495eb127fe", + "file_path": "content/blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs.md", + "extension": "md", + "url_path": "blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs", + "filetype": null, + "metadata": { + "title": "How Rich Metadata Powers Data Discovery in Modern Data Catalogs", + "created": "2025-06-25T00:00:00.000Z", + "description": "Learn how metadata transforms data discovery at scale—from search engines like Solr and Elasticsearch to standardized schemas that help users find exactly what they need among thousands of datasets.", + "authors": [ + "anuveyatsu" + ], + "image": "/static/img/blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs/metadata-search-discovery-illustration.png", + "filetype": "blog", + "faqs": [ + { + "question": "What's the difference between browsing and searching in a data catalog?", + "answer": "Browsing works well for small collections (dozens of datasets) where users can scan through categories. Searching becomes essential at scale—when you have hundreds or thousands of datasets, users need to query by keywords, filters, and metadata to find relevant data quickly." + }, + { + "question": "Why do different data catalogs use different search engines?", + "answer": "Different search engines excel at different tasks. Apache Solr is great for faceted search and text analysis, Elasticsearch excels at real-time indexing and complex queries, while others might prioritize simplicity or specific features. The choice depends on scale, performance needs, and existing infrastructure." + }, + { + "question": "How much metadata is \"enough\" for good discovery?", + "answer": "Start with title, description, tags, and category—these four fields dramatically improve discoverability. Add temporal (dates), spatial (geography), and provenance (source) metadata based on your users' needs. The key is consistency across all datasets rather than perfect completeness." + }, + { + "question": "Can I improve discovery without changing my existing data catalog software?", + "answer": "Often yes! Most catalog systems allow you to enrich existing datasets with better metadata. Focus on improving titles, descriptions, and tags for your most important datasets first. The search improvements will be immediate and noticeable." + } + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs.md", + "to": "blog/basics-of-metadata-how-it-helps-to-understand-your-data", + "toRaw": "/blog/basics-of-metadata-how-it-helps-to-understand-your-data", + "text": "previous post", + "embed": false, + "internal": true + }, + { + "from": "blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs.md", + "to": "https://frictionlessdata.io/", + "toRaw": "https://frictionlessdata.io/", + "text": "Frictionless Data", + "embed": false, + "internal": false + }, + { + "from": "blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs.md", + "to": "static/img/blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs/metadata-search-discovery-illustration.png", + "toRaw": "/static/img/blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs/metadata-search-discovery-illustration.png", + "text": "Metadata search discovey illustration", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "c55916d4a9fb80a55ac08a3367477267882aebc7", + "file_path": "content/blog/how-to-initialize-a-data-package-using-data-tool.md", + "extension": "md", + "url_path": "blog/how-to-initialize-a-data-package-using-data-tool", + "filetype": null, + "metadata": { + "title": "How to initialize a data package using data tool", + "created": "2018-05-14T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/how-to-initialize-a-data-package-using-data-tool.md", + "to": "https://datahub.io/download", + "toRaw": "https://datahub.io/download", + "text": "download it", + "embed": false, + "internal": false + }, + { + "from": "blog/how-to-initialize-a-data-package-using-data-tool.md", + "to": "https://datahub.io/docs/getting-started/installing-data", + "toRaw": "https://datahub.io/docs/getting-started/installing-data", + "text": "instructions", + "embed": false, + "internal": false + }, + { + "from": "blog/how-to-initialize-a-data-package-using-data-tool.md", + "to": "https://datahub.io/docs/data-packages", + "toRaw": "https://datahub.io/docs/data-packages", + "text": "https://datahub.io/docs/data-packages", + "embed": false, + "internal": false + }, + { + "from": "blog/how-to-initialize-a-data-package-using-data-tool.md", + "to": "https://datahub.io/docs", + "toRaw": "https://datahub.io/docs", + "text": "https://datahub.io/docs", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "b30a21f1619eba3a0cfdeacb5ed1bab5df28a730", + "file_path": "content/blog/how-to-reduce-data-portal-costs-by-90-percent.md", + "extension": "md", + "url_path": "blog/how-to-reduce-data-portal-costs-by-90-percent", + "filetype": null, + "metadata": { + "title": "How to Reduce Data Portal Costs by 90% or More", + "created": "2025-03-14T00:00:00.000Z", + "authors": [ + "Yoana Popova" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/how-to-reduce-data-portal-costs-by-90-percent.md", + "to": "https://portaljs.com/pricing", + "toRaw": "https://portaljs.com/pricing", + "text": "Start Your Free Trial", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "4807fbdf6bfd4a79215a7ad42239c45bd4e2d25d", + "file_path": "content/blog/how-to-use-data-packages-from-r.md", + "extension": "md", + "url_path": "blog/how-to-use-data-packages-from-r", + "filetype": null, + "metadata": { + "title": "How to use Data Packages from R", + "created": "2017-11-16T00:00:00.000Z", + "authors": [ + "mikanebu", + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/how-to-use-data-packages-from-r.md", + "to": "https://datahub.io/docs/data-packages", + "toRaw": "https://datahub.io/docs/data-packages", + "text": "Data Packages", + "embed": false, + "internal": false + }, + { + "from": "blog/how-to-use-data-packages-from-r.md", + "to": "https://frictionlessdata.io/specs/data-packages/", + "toRaw": "https://frictionlessdata.io/specs/data-packages/", + "text": "specifications", + "embed": false, + "internal": false + }, + { + "from": "blog/how-to-use-data-packages-from-r.md", + "to": "https://datahub.io/core/finance-vix", + "toRaw": "https://datahub.io/core/finance-vix", + "text": "https://datahub.io/core/finance-vix", + "embed": false, + "internal": false + }, + { + "from": "blog/how-to-use-data-packages-from-r.md", + "to": "static/img/docs/r-screenshot-resources.png", + "toRaw": "/static/img/docs/r-screenshot-resources.png", + "text": "list of all resources", + "embed": true, + "internal": true + }, + { + "from": "blog/how-to-use-data-packages-from-r.md", + "to": "static/img/docs/r-screenshot-data.png", + "toRaw": "/static/img/docs/r-screenshot-data.png", + "text": "all tabular printed data", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "57c7d9edf87f3fc21e77cdef912db8d64051a52c", + "file_path": "content/blog/how-to-use-multiple-datahub-accounts.md", + "extension": "md", + "url_path": "blog/how-to-use-multiple-datahub-accounts", + "filetype": null, + "metadata": { + "title": "How to use multiple DataHub accounts", + "created": "2018-07-18T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/how-to-use-multiple-datahub-accounts.md", + "to": "https://datahub.io/docs/tutorials/how-to-use-multiple-datahub-accounts", + "toRaw": "https://datahub.io/docs/tutorials/how-to-use-multiple-datahub-accounts", + "text": "https://datahub.io/docs/tutorials/how-to-use-multiple-datahub-accounts", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "836e7b028df925274170f1ab2d66faf878e71bed", + "file_path": "content/blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs.md", + "extension": "md", + "url_path": "blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs", + "filetype": null, + "metadata": { + "title": "How We Rebuilt a Legacy CKAN Portal into a Static, Read-Only Site with PortalJS", + "description": "Migrating from a heavy CKAN 2.6 portal to a fast, fully static frontend — and the technical journey behind it.", + "created": "2025-07-29T00:00:00.000Z", + "authors": [ + "baglanadaskhan" + ], + "filetype": "blog", + "faqs": [ + { + "question": "Why did you migrate from CKAN to a static site?", + "answer": "CKAN 2.6 was outdated and required significant maintenance with legacy plugins. We wanted to preserve data access while eliminating infrastructure complexity and costs." + }, + { + "question": "How do you handle search without a backend database?", + "answer": "We use Lunr.js, a client-side search engine that creates a compact index (~1MB) from all datapackage.json files at build time, providing fast in-browser search." + }, + { + "question": "What data format did you use for the migration?", + "answer": "We used the Frictionless Data Package specification, exporting each dataset as a datapackage.json file organized by publisher in a hierarchical structure." + }, + { + "question": "How many datasets were preserved in the migration?", + "answer": "Over 1,000 datasets were successfully preserved and made discoverable through the new static portal." + }, + { + "question": "What are the main benefits of the static approach?", + "answer": "The site loads in milliseconds, infrastructure costs are nearly eliminated, maintenance is reduced to GitHub workflows, and it's served entirely via CDN." + }, + { + "question": "What features were intentionally removed?", + "answer": "We removed CKAN's web UI, admin panel, Solr search engine, and all user authentication features, focusing purely on data access and discovery." + } + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs.md", + "to": "https://old.datahub.io/", + "toRaw": "https://old.datahub.io/", + "text": "DataHub v1", + "embed": false, + "internal": false + }, + { + "from": "blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs.md", + "to": "https://specs.frictionlessdata.io/data-package/", + "toRaw": "https://specs.frictionlessdata.io/data-package/", + "text": "Frictionless Data Package", + "embed": false, + "internal": false + }, + { + "from": "blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs.md", + "to": "https://portaljs.com/", + "toRaw": "https://portaljs.com/", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs.md", + "to": "https://lunrjs.com/", + "toRaw": "https://lunrjs.com/", + "text": "Lunr.js", + "embed": false, + "internal": false + }, + { + "from": "blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs.md", + "to": "https://old.datahub.io/", + "toRaw": "https://old.datahub.io/", + "text": "old.datahub.io", + "embed": false, + "internal": false + }, + { + "from": "blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs.md", + "to": "https://portaljs.com/", + "toRaw": "https://portaljs.com/", + "text": "PortalJS", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "17799ae20a4779e4ba5919a8053ccec56c177bbc", + "file_path": "content/blog/import-online-data-files-directly-with-scheduling.md", + "extension": "md", + "url_path": "blog/import-online-data-files-directly-with-scheduling", + "filetype": null, + "metadata": { + "title": "Import online data files directly with scheduling", + "created": "2017-11-14T00:00:00.000Z", + "authors": [ + "anuveyatsu", + "rufuspollock" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/import-online-data-files-directly-with-scheduling.md", + "to": "static/img/docs/scheduled-data.png", + "toRaw": "/static/img/docs/scheduled-data.png", + "text": "page generated with your name url", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "814811b917a61bda75a86ca8b1077ca571fc5ff8", + "file_path": "content/blog/improved-reporting-and-debugging-of-data-publishing.md", + "extension": "md", + "url_path": "blog/improved-reporting-and-debugging-of-data-publishing", + "filetype": null, + "metadata": { + "title": "Improved Reporting and Debugging of Data Publishing", + "created": "2018-01-29T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/improved-reporting-and-debugging-of-data-publishing.md", + "to": "static/img/docs/processing-dataset.gif", + "toRaw": "/static/img/docs/processing-dataset.gif", + "text": "dataset page with information about currently running steps", + "embed": true, + "internal": true + }, + { + "from": "blog/improved-reporting-and-debugging-of-data-publishing.md", + "to": "static/img/docs/succeeded-dataset.png", + "toRaw": "/static/img/docs/succeeded-dataset.png", + "text": "Regular dataset page", + "embed": true, + "internal": true + }, + { + "from": "blog/improved-reporting-and-debugging-of-data-publishing.md", + "to": "static/img/docs/failed-dataset.gif", + "toRaw": "/static/img/docs/failed-dataset.gif", + "text": "failed processing of dataset", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "2712677c8cd2553f3cc5adc7c54ee9478c8f3639", + "file_path": "content/blog/introducing-private-datasets-on-the-datahub.md", + "extension": "md", + "url_path": "blog/introducing-private-datasets-on-the-datahub", + "filetype": null, + "metadata": { + "title": "Introducing private datasets on the DataHub", + "created": "2017-12-13T00:00:00.000Z", + "authors": [ + "anuveyatsu", + "rufuspollock" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/introducing-private-datasets-on-the-datahub.md", + "to": "https://datahub.io/pricing", + "toRaw": "https://datahub.io/pricing", + "text": "https://datahub.io/pricing", + "embed": false, + "internal": false + }, + { + "from": "blog/introducing-private-datasets-on-the-datahub.md", + "to": "https://datahub.io/download", + "toRaw": "https://datahub.io/download", + "text": "https://datahub.io/download", + "embed": false, + "internal": false + }, + { + "from": "blog/introducing-private-datasets-on-the-datahub.md", + "to": "http://datahub.io/blog/data-desktop-app-alpha-release", + "toRaw": "http://datahub.io/blog/data-desktop-app-alpha-release", + "text": "here", + "embed": false, + "internal": false + }, + { + "from": "blog/introducing-private-datasets-on-the-datahub.md", + "to": "http://datahub.io/docs/getting-started/publishing-data", + "toRaw": "http://datahub.io/docs/getting-started/publishing-data", + "text": "here", + "embed": false, + "internal": false + }, + { + "from": "blog/introducing-private-datasets-on-the-datahub.md", + "to": "static/img/docs/push-private.png", + "toRaw": "/static/img/docs/push-private.png", + "text": "just select \"private\" option and then press \"Go\" button", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "df15237545ff437e0fab0796dcbfa182067180f2", + "file_path": "content/blog/introducing-visualizations-in-portaljs-cloud.md", + "extension": "md", + "url_path": "blog/introducing-visualizations-in-portaljs-cloud", + "filetype": null, + "metadata": { + "title": "Introducing Visualizations in PortalJS Cloud: Publish and Share Insights Alongside Your Datasets", + "description": "Empower your data portal with an insights catalog — a new way to explore, share, and communicate findings alongside your datasets.", + "created": "2025-10-13T00:00:00.000Z", + "authors": [ + "João Demenech" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/introducing-visualizations-in-portaljs-cloud.md", + "to": "https://observablehq.com/framework/", + "toRaw": "https://observablehq.com/framework/", + "text": "Observable Framework", + "embed": false, + "internal": false + }, + { + "from": "blog/introducing-visualizations-in-portaljs-cloud.md", + "to": "https://github.com/datopian/portaljs-data-app-starter", + "toRaw": "https://github.com/datopian/portaljs-data-app-starter", + "text": "PortalJS Data App Starter template", + "embed": false, + "internal": false + }, + { + "from": "blog/introducing-visualizations-in-portaljs-cloud.md", + "to": "static/img/blog/introducing-visualizations-in-portaljs-cloud/spreadsheet-to-viz.png", + "toRaw": "/static/img/blog/introducing-visualizations-in-portaljs-cloud/spreadsheet-to-viz.png", + "text": "Data to Insight", + "embed": true, + "internal": true + }, + { + "from": "blog/introducing-visualizations-in-portaljs-cloud.md", + "to": "static/img/blog/introducing-visualizations-in-portaljs-cloud/code-to-viz.png", + "toRaw": "/static/img/blog/introducing-visualizations-in-portaljs-cloud/code-to-viz.png", + "text": "Code to Insight", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "fcf60c78cd0813f8dabb31a6db8d037979034a96", + "file_path": "content/blog/javascript-sdk-for-data-deployment.md", + "extension": "md", + "url_path": "blog/javascript-sdk-for-data-deployment", + "filetype": null, + "metadata": { + "title": "JavaScript SDK for data deployment", + "created": "2018-05-15T00:00:00.000Z", + "authors": [ + "acckiygerman", + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/javascript-sdk-for-data-deployment.md", + "to": "https://datahub.io/docs/tutorials/js-sdk-tutorial", + "toRaw": "https://datahub.io/docs/tutorials/js-sdk-tutorial", + "text": "https://datahub.io/docs/tutorials/js-sdk-tutorial", + "embed": false, + "internal": false + }, + { + "from": "blog/javascript-sdk-for-data-deployment.md", + "to": "https://datahub.io/download", + "toRaw": "https://datahub.io/download", + "text": "the CLI tool", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "b249e37018b0f682242550623bd9427c6096aee5", + "file_path": "content/blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api.md", + "extension": "md", + "url_path": "blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api", + "filetype": null, + "metadata": { + "title": "Keep Your Portal Data Fresh: A Hands-On Guide to the PortalJS Cloud API", + "description": "This guide walks through using the PortalJS Cloud API to programatically create datasets, add resources, upload and replace data files, and update metadata—showing how to build repeatable data update pipelines with code examples.", + "created": "2026-01-22T00:00:00.000Z", + "authors": [ + "João Demenech" + ], + "tags": [ + "PortalJS", + "PortalJS Cloud", + "ETL", + "API", + "Guide" + ], + "image": "/static/img/blog/2026-01-22-keep-your-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api/api-docs.png", + "filetype": "blog", + "tasks": [] + }, + "tags": [ + "PortalJS", + "PortalJS Cloud", + "ETL", + "API", + "Guide" + ], + "links": [ + { + "from": "blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api.md", + "to": "https://cloud.portaljs.com/auth/signin", + "toRaw": "https://cloud.portaljs.com/auth/signin", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api.md", + "to": "https://cloud.portaljs.com/profile/api-keys", + "toRaw": "https://cloud.portaljs.com/profile/api-keys", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api.md", + "to": "static/img/blog/2026-01-22-keep-your-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api/api-docs.png", + "toRaw": "/static/img/blog/2026-01-22-keep-your-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api/api-docs.png", + "text": "Interactive API docs", + "embed": true, + "internal": true + }, + { + "from": "blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api.md", + "to": "static/img/blog/2026-01-22-keep-your-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api/api-token.png", + "toRaw": "/static/img/blog/2026-01-22-keep-your-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api/api-token.png", + "text": "Interactive API docs", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "e60211c01322327b2320f327e002c0b04c0f0122", + "file_path": "content/blog/machine-learning-datasets.md", + "extension": "md", + "url_path": "blog/machine-learning-datasets", + "filetype": null, + "metadata": { + "title": "Machine learning datasets", + "created": "2018-05-25T00:00:00.000Z", + "authors": [ + "svetozarstojkovic", + "branko-dj" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning", + "toRaw": "https://datahub.io/machine-learning", + "text": "https://datahub.io/machine-learning", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/awesome#machine-learning-statistical", + "toRaw": "https://datahub.io/awesome#machine-learning-statistical", + "text": "https://datahub.io/awesome#machine-learning-statistical", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/seismic-bumps", + "toRaw": "https://datahub.io/machine-learning/seismic-bumps", + "text": "Seismic bumps", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/hepatitis", + "toRaw": "https://datahub.io/machine-learning/hepatitis", + "text": "Hepatitis", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/cervical-cancer", + "toRaw": "https://datahub.io/machine-learning/cervical-cancer", + "text": "Cervical cancer", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/primary-tumor", + "toRaw": "https://datahub.io/machine-learning/primary-tumor", + "text": "Primary tumor", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/fertility", + "toRaw": "https://datahub.io/machine-learning/fertility", + "text": "Fertility", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/breast-cancer", + "toRaw": "https://datahub.io/machine-learning/breast-cancer", + "text": "Breast cancer", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/speed-dating", + "toRaw": "https://datahub.io/machine-learning/speed-dating", + "text": "Speed dating", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/dermatology", + "toRaw": "https://datahub.io/machine-learning/dermatology", + "text": "Dermatology", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/lymph", + "toRaw": "https://datahub.io/machine-learning/lymph", + "text": "Lymph", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/tic-tac-toe-endgame", + "toRaw": "https://datahub.io/machine-learning/tic-tac-toe-endgame", + "text": "Tic Tac Toe Endgame", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/eeg-eye-state", + "toRaw": "https://datahub.io/machine-learning/eeg-eye-state", + "text": "EEG Eye State", + "embed": false, + "internal": false + }, + { + "from": "blog/machine-learning-datasets.md", + "to": "https://datahub.io/machine-learning/hepatitis#python", + "toRaw": "https://datahub.io/machine-learning/hepatitis#python", + "text": "https://datahub.io/machine-learning/hepatitis#python", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "f510950d1d64a8cf4fb1d048f0a7fd55f48bc455", + "file_path": "content/blog/making-portalJS-cloud-admin-panel-accessible.md", + "extension": "md", + "url_path": "blog/making-portalJS-cloud-admin-panel-accessible", + "filetype": null, + "metadata": { + "title": "Making PortalJS Cloud Admin Panel Accessible: The Digital Ramp Everyone Deserves", + "description": "Learn how PortalJS Cloud’s commitment to accessibility enhances the user experience for everyone.", + "created": "2025-01-26T00:00:00.000Z", + "authors": [ + "popovayoana", + "shreyas" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/making-portalJS-cloud-admin-panel-accessible.md", + "to": "https://wave.webaim.org/", + "toRaw": "https://wave.webaim.org/", + "text": "WAVE", + "embed": false, + "internal": false + }, + { + "from": "blog/making-portalJS-cloud-admin-panel-accessible.md", + "to": "https://www.deque.com/axe/", + "toRaw": "https://www.deque.com/axe/", + "text": "axe DevTools", + "embed": false, + "internal": false + }, + { + "from": "blog/making-portalJS-cloud-admin-panel-accessible.md", + "to": "https://developer.chrome.com/docs/lighthouse/accessibility/", + "toRaw": "https://developer.chrome.com/docs/lighthouse/accessibility/", + "text": "Lighthouse", + "embed": false, + "internal": false + }, + { + "from": "blog/making-portalJS-cloud-admin-panel-accessible.md", + "to": "https://www.w3.org/WAI/standards-guidelines/wcag/", + "toRaw": "https://www.w3.org/WAI/standards-guidelines/wcag/", + "text": "official WCAG guidelines", + "embed": false, + "internal": false + }, + { + "from": "blog/making-portalJS-cloud-admin-panel-accessible.md", + "to": "images/blog/lighthouse.png", + "toRaw": "/images/blog/lighthouse.png", + "text": "Lighthouse accessibility check image", + "embed": true, + "internal": true + }, + { + "from": "blog/making-portalJS-cloud-admin-panel-accessible.md", + "to": "images/blog/keyboard-navigation-1.png", + "toRaw": "/images/blog/keyboard-navigation-1.png", + "text": "Keyboard navigation image", + "embed": true, + "internal": true + }, + { + "from": "blog/making-portalJS-cloud-admin-panel-accessible.md", + "to": "images/blog/error-message-1.png", + "toRaw": "/images/blog/error-message-1.png", + "text": "Error message image", + "embed": true, + "internal": true + }, + { + "from": "blog/making-portalJS-cloud-admin-panel-accessible.md", + "to": "images/blog/color-contrast.png", + "toRaw": "/images/blog/color-contrast.png", + "text": "Colour contrast image", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "9305938363708a2bdc91c490ff6d99b3f4d169c2", + "file_path": "content/blog/markdowndb-basics-tutorial-2023.md", + "extension": "md", + "url_path": "blog/markdowndb-basics-tutorial-2023", + "filetype": null, + "metadata": { + "title": "Learn how to use MarkdownDB with our First Tutorial!", + "description": "We've just released our first tutorial that covers the fundamentals of MarkdownDB - our new package for treating markdown files as a database. If you've been curious about how to manage your markdown files more effectively, check it out!", + "created": "2023-05-26T00:00:00.000Z", + "authors": [ + "Ola Rubaj" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/markdowndb-basics-tutorial-2023.md", + "to": "https://github.com/datopian/markdowndb", + "toRaw": "https://github.com/datopian/markdowndb", + "text": "MarkdownDB", + "embed": false, + "internal": false + }, + { + "from": "blog/markdowndb-basics-tutorial-2023.md", + "to": "https://github.com/datopian/markdowndb", + "toRaw": "https://github.com/datopian/markdowndb", + "text": "🔍 Click here to learn more!", + "embed": false, + "internal": false + }, + { + "from": "blog/markdowndb-basics-tutorial-2023.md", + "to": "https://sqlitebrowser.org/", + "toRaw": "https://sqlitebrowser.org/", + "text": "https://sqlitebrowser.org/", + "embed": false, + "internal": false + }, + { + "from": "blog/markdowndb-basics-tutorial-2023.md", + "to": "https://github.com/datopian/markdowndb/tree/main/examples/basic-example", + "toRaw": "https://github.com/datopian/markdowndb/tree/main/examples/basic-example", + "text": "full code for this tutorial here", + "embed": false, + "internal": false + }, + { + "from": "blog/markdowndb-basics-tutorial-2023.md", + "to": "static/img/blog/2023-05-26-lean-how-to-use-markdown/markdowndb.gif", + "toRaw": "/static/img/blog/2023-05-26-lean-how-to-use-markdown/markdowndb.gif", + "text": "Gif", + "embed": true, + "internal": true + }, + { + "from": "blog/markdowndb-basics-tutorial-2023.md", + "to": "static/img/blog/2023-05-26-lean-how-to-use-markdown/sqlite-viewer.png", + "toRaw": "/static/img/blog/2023-05-26-lean-how-to-use-markdown/sqlite-viewer.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/markdowndb-basics-tutorial-2023.md", + "to": "static/img/blog/2023-05-26-lean-how-to-use-markdown/output.png", + "toRaw": "/static/img/blog/2023-05-26-lean-how-to-use-markdown/output.png", + "text": "", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "3c2cfd0ea40df896b25a85cd97c33b3df09ef193", + "file_path": "content/blog/markdowndb-launch.md", + "extension": "md", + "url_path": "blog/markdowndb-launch", + "filetype": null, + "metadata": { + "title": "Announcing MarkdownDB: an open source tool to create an SQL API to your markdown files! 🚀", + "description": "MarkdownDB - an open source library to transform markdown content into sql-queryable data. Build rich markdown-powered sites easily and reliably. New dedicated website at markdowndb.com", + "created": "2023-10-11T00:00:00.000Z", + "authors": [ + "Ola Rubaj" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/markdowndb-launch.md", + "to": "https://markdowndb.com/", + "toRaw": "https://markdowndb.com/", + "text": "https://markdowndb.com/", + "embed": false, + "internal": false + }, + { + "from": "blog/markdowndb-launch.md", + "to": "https://markdowndb.com/blog/basic-tutorial", + "toRaw": "https://markdowndb.com/blog/basic-tutorial", + "text": "Read the full tutorial", + "embed": false, + "internal": false + }, + { + "from": "blog/markdowndb-launch.md", + "to": "https://markdowndb.com/", + "toRaw": "https://markdowndb.com/", + "text": "https://markdowndb.com/", + "embed": false, + "internal": false + }, + { + "from": "blog/markdowndb-launch.md", + "to": "https://github.com/datopian/markdowndb", + "toRaw": "https://github.com/datopian/markdowndb", + "text": "https://github.com/datopian/markdowndb", + "embed": false, + "internal": false + }, + { + "from": "blog/markdowndb-launch.md", + "to": "static/img/blog/markdowbdb-launch-site-example.png", + "toRaw": "/static/img/blog/markdowbdb-launch-site-example.png", + "text": "", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "c83eb05d416cb140a198144920ecbba896b1ca47", + "file_path": "content/blog/mcp-server-ai-assistants-to-improve-data-portals.md", + "extension": "md", + "url_path": "blog/mcp-server-ai-assistants-to-improve-data-portals", + "filetype": null, + "metadata": { + "title": "MCP Server: A better way to connect AI assistants to data portals", + "description": "How an MCP server bridges AI assistants and data portals, enabling seamless, efficient data discovery for ChatGPT, Claude, and other AI tools.", + "created": "2025-09-17T00:00:00.000Z", + "authors": [ + "Theo Bertol" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/mcp-server-ai-assistants-to-improve-data-portals.md", + "to": "static/img/blog/mcp-server-ai-assistants-to-improve-data-portals/mcp-llm.png", + "toRaw": "/static/img/blog/mcp-server-ai-assistants-to-improve-data-portals/mcp-llm.png", + "text": "MCP to LLM Connection", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "470144caaaab91f3ef3ac4aae0e022fe13269c02", + "file_path": "content/blog/new-features-and-improvements.md", + "extension": "md", + "url_path": "blog/new-features-and-improvements", + "filetype": null, + "metadata": { + "title": "New Features and Improvements", + "created": "2018-03-26T00:00:00.000Z", + "authors": [ + "acckiygerman" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/new-features-and-improvements.md", + "to": "https://datahub.io/docs/getting-started/publishing-data", + "toRaw": "https://datahub.io/docs/getting-started/publishing-data", + "text": "upload your data", + "embed": false, + "internal": false + }, + { + "from": "blog/new-features-and-improvements.md", + "to": "https://datahub.io/docs/features/api", + "toRaw": "https://datahub.io/docs/features/api", + "text": "API documentation", + "embed": false, + "internal": false + }, + { + "from": "blog/new-features-and-improvements.md", + "to": "static/img/docs/share-embed-tables.png", + "toRaw": "/static/img/docs/share-embed-tables.png", + "text": "preview tables for tabular data. Now you can share or embed them", + "embed": true, + "internal": true + }, + { + "from": "blog/new-features-and-improvements.md", + "to": "static/img/docs/share-embed-graphs.png", + "toRaw": "/static/img/docs/share-embed-graphs.png", + "text": "each view for a dataset could be easily shared or embedded into your web-page using the links", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "5145cd862f42ed5d4b19d2a8aa78cf7eee696a67", + "file_path": "content/blog/new-machine-learning-datasets.md", + "extension": "md", + "url_path": "blog/new-machine-learning-datasets", + "filetype": null, + "metadata": { + "title": "New Machine Learning Datasets", + "created": "2018-09-10T00:00:00.000Z", + "authors": [ + "branko-dj" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/new-machine-learning-datasets.md", + "to": "https://www.openml.org/home", + "toRaw": "https://www.openml.org/home", + "text": "open-ml", + "embed": false, + "internal": false + }, + { + "from": "blog/new-machine-learning-datasets.md", + "to": "https://www.datahub.io/machine-learning", + "toRaw": "https://www.datahub.io/machine-learning", + "text": "page", + "embed": false, + "internal": false + }, + { + "from": "blog/new-machine-learning-datasets.md", + "to": "https://www.datahub.io/machine-learning/vehicle", + "toRaw": "https://www.datahub.io/machine-learning/vehicle", + "text": "Vehicle silhouettes", + "embed": false, + "internal": false + }, + { + "from": "blog/new-machine-learning-datasets.md", + "to": "https://www.datahub.io/machine-learning/diabetes", + "toRaw": "https://www.datahub.io/machine-learning/diabetes", + "text": "Diabetes", + "embed": false, + "internal": false + }, + { + "from": "blog/new-machine-learning-datasets.md", + "to": "https://www.datahub.io/machine-learning/musk", + "toRaw": "https://www.datahub.io/machine-learning/musk", + "text": "Musk", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "6c2342e14248f4c236d7bc3e460df74ae35ccd79", + "file_path": "content/blog/online-validation-tool.md", + "extension": "md", + "url_path": "blog/online-validation-tool", + "filetype": null, + "metadata": { + "title": "Validate your Data Package descriptor online", + "created": "2018-04-19T00:00:00.000Z", + "authors": [ + "acckiygerman" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/online-validation-tool.md", + "to": "https://datahub.io/tools/validate", + "toRaw": "https://datahub.io/tools/validate", + "text": "https://datahub.io/tools/validate", + "embed": false, + "internal": false + }, + { + "from": "blog/online-validation-tool.md", + "to": "https://datahub.io/blog/data-validation-in-the-datahub", + "toRaw": "https://datahub.io/blog/data-validation-in-the-datahub", + "text": "full data validation on the DataHub", + "embed": false, + "internal": false + }, + { + "from": "blog/online-validation-tool.md", + "to": "https://github.com/frictionlessdata/datapackage-js", + "toRaw": "https://github.com/frictionlessdata/datapackage-js", + "text": "datapackage-js", + "embed": false, + "internal": false + }, + { + "from": "blog/online-validation-tool.md", + "to": "https://raw.githubusercontent.com/frictionlessdata/test-data/master/packages/invalid-descriptor/datapackage.json", + "toRaw": "https://raw.githubusercontent.com/frictionlessdata/test-data/master/packages/invalid-descriptor/datapackage.json", + "text": "datapackage.json", + "embed": false, + "internal": false + }, + { + "from": "blog/online-validation-tool.md", + "to": "https://frictionlessdata.io/docs/data-package/", + "toRaw": "https://frictionlessdata.io/docs/data-package/", + "text": "https://frictionlessdata.io/docs/data-package/", + "embed": false, + "internal": false + }, + { + "from": "blog/online-validation-tool.md", + "to": "static/img/docs/online-validation-tool-invalid-package.png", + "toRaw": "/static/img/docs/online-validation-tool-invalid-package.png", + "text": "online-validation-tool-invalid-package", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "dbd9c58101b8d0ffb305be80191859ed166446ce", + "file_path": "content/blog/open-data-day-covid-19.md", + "extension": "md", + "url_path": "blog/open-data-day-covid-19", + "filetype": null, + "metadata": { + "title": "Open Data Day 2020 and COVID-19 data", + "authors": [ + "michael.polidori" + ], + "created": "2020-03-17T00:00:00.000Z", + "tags": [ + "COVID-19", + "Open Data Day" + ], + "tasks": [] + }, + "tags": [ + "COVID-19", + "Open Data Day" + ], + "links": [ + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://www.datopian.com/", + "toRaw": "https://www.datopian.com/", + "text": "Datopian", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://opendataday.org/", + "toRaw": "https://opendataday.org/", + "text": "Open Data Day 2020", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://github.com/CSSEGISandData/COVID-19", + "toRaw": "https://github.com/CSSEGISandData/COVID-19", + "text": "Data Repository by Johns Hopkins CSSE", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://systems.jhu.edu/", + "toRaw": "https://systems.jhu.edu/", + "text": "Johns Hopkins Whiting School of Engineering", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://pypi.org/project/dataflows/", + "toRaw": "https://pypi.org/project/dataflows/", + "text": "PyPI", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://github.com/datahq/dataflows", + "toRaw": "https://github.com/datahq/dataflows", + "text": "GitHub", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv", + "toRaw": "https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv", + "text": "confirmed", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Recovered.csv", + "toRaw": "https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Recovered.csv", + "text": "recovered", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Deaths.csv", + "toRaw": "https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Deaths.csv", + "text": "deaths", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://github.com/datasets/covid-19", + "toRaw": "https://github.com/datasets/covid-19", + "text": "GitHub", + "embed": false, + "internal": false + }, + { + "from": "blog/open-data-day-covid-19.md", + "to": "https://datahub.io/core/covid-19", + "toRaw": "https://datahub.io/core/covid-19", + "text": "DataHub", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "6d545d41ab989ff5dd37879dd41d4f5dc8745de2", + "file_path": "content/blog/pharmaceutical-drug-spending.md", + "extension": "md", + "url_path": "blog/pharmaceutical-drug-spending", + "filetype": null, + "metadata": { + "title": "Which country spends the most on pharmaceutical drugs?", + "created": "2018-01-23T00:00:00.000Z", + "authors": [ + "mikanebu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/pharmaceutical-drug-spending.md", + "to": "https://data.oecd.org/healthres/pharmaceutical-spending.htm", + "toRaw": "https://data.oecd.org/healthres/pharmaceutical-spending.htm", + "text": "click here to read more", + "embed": false, + "internal": false + }, + { + "from": "blog/pharmaceutical-drug-spending.md", + "to": "https://datahub.io/core/pharmaceutical-drug-spending", + "toRaw": "https://datahub.io/core/pharmaceutical-drug-spending", + "text": "DataHub", + "embed": false, + "internal": false + }, + { + "from": "blog/pharmaceutical-drug-spending.md", + "to": "http://datahub.io/search?q=core", + "toRaw": "http://datahub.io/search?q=core", + "text": "DataHub", + "embed": false, + "internal": false + }, + { + "from": "blog/pharmaceutical-drug-spending.md", + "to": "static/img/docs/pharma-dataset1.png", + "toRaw": "/static/img/docs/pharma-dataset1.png", + "text": "This chart illustrates total spending by country in 2015", + "embed": true, + "internal": true + }, + { + "from": "blog/pharmaceutical-drug-spending.md", + "to": "static/img/docs/pharma-dataset2.png", + "toRaw": "/static/img/docs/pharma-dataset2.png", + "text": "spendings per capita in the same year", + "embed": true, + "internal": true + }, + { + "from": "blog/pharmaceutical-drug-spending.md", + "to": "static/img/docs/pharma-dataset3.png", + "toRaw": "/static/img/docs/pharma-dataset3.png", + "text": "chart that breaks down total spendings in the United States since 2000 and it is growing gradually", + "embed": true, + "internal": true + }, + { + "from": "blog/pharmaceutical-drug-spending.md", + "to": "static/img/docs/pharma-dataset4.png", + "toRaw": "/static/img/docs/pharma-dataset4.png", + "text": "table describes Pharmaceutical Drug Spending dataset by countries in USD per capita as a share of GDP and total spending since 1970.", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "2259835c54eec9f81e63991cd71bdf73b21da071", + "file_path": "content/blog/previews-for-large-datasets.md", + "extension": "md", + "url_path": "blog/previews-for-large-datasets", + "filetype": null, + "metadata": { + "title": "Previews for large datasets", + "created": "2017-10-18T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/previews-for-large-datasets.md", + "to": "static/img/docs/preview-table.png", + "toRaw": "/static/img/docs/preview-table.png", + "text": "finance-vix dataset", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "bd45585d566a3f594b29adb32ab32764e9c0bec0", + "file_path": "content/blog/q1-2018-review.md", + "extension": "md", + "url_path": "blog/q1-2018-review", + "filetype": null, + "metadata": { + "title": "Q1 2018 Review", + "created": "2018-04-11T00:00:00.000Z", + "modified": "2020-06-24T00:00:00.000Z", + "authors": [ + "anuveyatsu", + "rufuspollock", + "akariv" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/q1-2018-review.md", + "to": "https://github.com/datahq/datahub-qa/issues", + "toRaw": "https://github.com/datahq/datahub-qa/issues", + "text": "https://github.com/datahq/datahub-qa/issues", + "embed": false, + "internal": false + }, + { + "from": "blog/q1-2018-review.md", + "to": "https://datahub.io/examples/datahub-qa-issues-tracker", + "toRaw": "https://datahub.io/examples/datahub-qa-issues-tracker", + "text": "https://datahub.io/examples/datahub-qa-issues-tracker", + "embed": false, + "internal": false + }, + { + "from": "blog/q1-2018-review.md", + "to": "https://datahub.io/blog/new-features-and-improvements", + "toRaw": "https://datahub.io/blog/new-features-and-improvements", + "text": "https://datahub.io/blog/new-features-and-improvements", + "embed": false, + "internal": false + }, + { + "from": "blog/q1-2018-review.md", + "to": "https://datahub.io/core", + "toRaw": "https://datahub.io/core", + "text": "https://datahub.io/core", + "embed": false, + "internal": false + }, + { + "from": "blog/q1-2018-review.md", + "to": "https://datahub.io/docs/features/views#axis-titles-and-suffixes-for-axis-ticks", + "toRaw": "https://datahub.io/docs/features/views#axis-titles-and-suffixes-for-axis-ticks", + "text": "https://datahub.io/docs/features/views#axis-titles-and-suffixes-for-axis-ticks", + "embed": false, + "internal": false + }, + { + "from": "blog/q1-2018-review.md", + "to": "https://datahub.io/docs/getting-started/installing-data", + "toRaw": "https://datahub.io/docs/getting-started/installing-data", + "text": "https://datahub.io/docs/getting-started/installing-data", + "embed": false, + "internal": false + }, + { + "from": "blog/q1-2018-review.md", + "to": "https://datahub.io/docs/getting-started/publishing-data", + "toRaw": "https://datahub.io/docs/getting-started/publishing-data", + "text": "https://datahub.io/docs/getting-started/publishing-data", + "embed": false, + "internal": false + }, + { + "from": "blog/q1-2018-review.md", + "to": "static/img/docs/upload-progress-bar.png", + "toRaw": "/static/img/docs/upload-progress-bar.png", + "text": "Progress bar on push so publishers have better UX while their files are being uploaded", + "embed": true, + "internal": true + }, + { + "from": "blog/q1-2018-review.md", + "to": "static/img/docs/validate-details.png", + "toRaw": "/static/img/docs/validate-details.png", + "text": "validate command improvements: useful when your data package has lots of files", + "embed": true, + "internal": true + }, + { + "from": "blog/q1-2018-review.md", + "to": "static/img/docs/info-output.png", + "toRaw": "/static/img/docs/info-output.png", + "text": "info command improvements: support for non-tabular files and improved information about datasets", + "embed": true, + "internal": true + }, + { + "from": "blog/q1-2018-review.md", + "to": "static/img/docs/cat-streamed-data.png", + "toRaw": "/static/img/docs/cat-streamed-data.png", + "text": "cat command works with streamed data", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "4740ebaac0f325dbfef2051aa5c316c64fbc62c0", + "file_path": "content/blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "extension": "md", + "url_path": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject", + "filetype": null, + "metadata": { + "title": "Revamped awesome collections: data sets that are grouped by subject", + "created": "2018-06-11T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "to": "blog/#contribute", + "toRaw": "#contribute", + "text": "suggest", + "embed": false, + "internal": true + }, + { + "from": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "to": "https://datahub.io/awesome", + "toRaw": "https://datahub.io/awesome", + "text": "https://datahub.io/awesome", + "embed": false, + "internal": false + }, + { + "from": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "to": "https://datahub.io/awesome/economic-data", + "toRaw": "https://datahub.io/awesome/economic-data", + "text": "https://datahub.io/awesome/economic-data", + "embed": false, + "internal": false + }, + { + "from": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "to": "https://datahub.io/awesome/reference-data", + "toRaw": "https://datahub.io/awesome/reference-data", + "text": "https://datahub.io/awesome/reference-data", + "embed": false, + "internal": false + }, + { + "from": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "to": "https://datahub.io/awesome/demographics", + "toRaw": "https://datahub.io/awesome/demographics", + "text": "https://datahub.io/awesome/demographics", + "embed": false, + "internal": false + }, + { + "from": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "to": "https://datahub.io/awesome/stock-market-data", + "toRaw": "https://datahub.io/awesome/stock-market-data", + "text": "https://datahub.io/awesome/stock-market-data", + "embed": false, + "internal": false + }, + { + "from": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "to": "https://datahub.io/awesome", + "toRaw": "https://datahub.io/awesome", + "text": "https://datahub.io/awesome", + "embed": false, + "internal": false + }, + { + "from": "blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject.md", + "to": "https://github.com/datahq/awesome-data", + "toRaw": "https://github.com/datahq/awesome-data", + "text": "https://github.com/datahq/awesome-data", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "098bd292a136b07a8a1005175ef6f2aa8e9337c1", + "file_path": "content/blog/see-events-and-activity-related-to-datasets-or-publishers.md", + "extension": "md", + "url_path": "blog/see-events-and-activity-related-to-datasets-or-publishers", + "filetype": null, + "metadata": { + "title": "See events and activity related to datasets or publishers", + "created": "2017-10-31T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/see-events-and-activity-related-to-datasets-or-publishers.md", + "to": "https://datahub.io/core/finance-vix/events", + "toRaw": "https://datahub.io/core/finance-vix/events", + "text": "https://datahub.io/core/finance-vix/events", + "embed": false, + "internal": false + }, + { + "from": "blog/see-events-and-activity-related-to-datasets-or-publishers.md", + "to": "static/img/docs/dashboard-events.png", + "toRaw": "/static/img/docs/dashboard-events.png", + "text": "dashboard page, users can monitor their own private activity as well as their datasets' statuses", + "embed": true, + "internal": true + }, + { + "from": "blog/see-events-and-activity-related-to-datasets-or-publishers.md", + "to": "static/img/docs/publisher-events.png", + "toRaw": "/static/img/docs/publisher-events.png", + "text": "Publisher page has information about recent operations related to his/her datasets", + "embed": true, + "internal": true + }, + { + "from": "blog/see-events-and-activity-related-to-datasets-or-publishers.md", + "to": "static/img/docs/events-page.png", + "toRaw": "/static/img/docs/events-page.png", + "text": "most recent events for the dataset", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "c8027bfc59e810c6b7d012fed76343597230eb2f", + "file_path": "content/blog/sports-data-on-datahub.md", + "extension": "md", + "url_path": "blog/sports-data-on-datahub", + "filetype": null, + "metadata": { + "title": "Sports data on DataHub", + "created": "2018-08-31T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/sports-data-on-datahub.md", + "to": "https://datahub.io/sports-data", + "toRaw": "https://datahub.io/sports-data", + "text": "https://datahub.io/sports-data", + "embed": false, + "internal": false + }, + { + "from": "blog/sports-data-on-datahub.md", + "to": "pricing", + "toRaw": "/pricing", + "text": "pricing page", + "embed": false, + "internal": true + }, + { + "from": "blog/sports-data-on-datahub.md", + "to": "sports-data/atp-world-tour-tennis-data", + "toRaw": "/sports-data/atp-world-tour-tennis-data", + "text": "ATP World Tour tennis data", + "embed": false, + "internal": true + }, + { + "from": "blog/sports-data-on-datahub.md", + "to": "sports-data/english-premier-league", + "toRaw": "/sports-data/english-premier-league", + "text": "English Premier League (football)", + "embed": false, + "internal": true + }, + { + "from": "blog/sports-data-on-datahub.md", + "to": "sports-data/spanish-la-liga", + "toRaw": "/sports-data/spanish-la-liga", + "text": "Spanish La Liga (football)", + "embed": false, + "internal": true + }, + { + "from": "blog/sports-data-on-datahub.md", + "to": "sports-data/italian-serie-a", + "toRaw": "/sports-data/italian-serie-a", + "text": "Italian Serie A (football)", + "embed": false, + "internal": true + }, + { + "from": "blog/sports-data-on-datahub.md", + "to": "sports-data/german-bundesliga", + "toRaw": "/sports-data/german-bundesliga", + "text": "German Bundesliga (football)", + "embed": false, + "internal": true + }, + { + "from": "blog/sports-data-on-datahub.md", + "to": "sports-data/french-ligue-1", + "toRaw": "/sports-data/french-ligue-1", + "text": "French Ligue 1 (football)", + "embed": false, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "41cdb29e9a59070b9c9b9c7185c5652e39545c0e", + "file_path": "content/blog/summer-updates-2023.md", + "extension": "md", + "url_path": "blog/summer-updates-2023", + "filetype": null, + "metadata": { + "title": "What We Shipped in Jul-Aug 2023", + "authors": [ + "ola-rubaj" + ], + "created": "2023-09-2", + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/summer-updates-2023.md", + "to": "https://flowershow.app/", + "toRaw": "https://flowershow.app/", + "text": "https://flowershow.app/", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://github.com/datopian/obsidian-flowershow", + "toRaw": "https://github.com/datopian/obsidian-flowershow", + "text": "Flowershow Obsidian plugin", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://flowershow.app/docs/publish-howto", + "toRaw": "https://flowershow.app/docs/publish-howto", + "text": "self-publish tutorial", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://flowershow.app#cloud-publish", + "toRaw": "https://flowershow.app#cloud-publish", + "text": "Check out the overview", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://github.com/datopian/flowershow/issues/545", + "toRaw": "https://github.com/datopian/flowershow/issues/545", + "text": "Learn more", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://github.com/datopian/flowershow/issues/543", + "toRaw": "https://github.com/datopian/flowershow/issues/543", + "text": "Learn more", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://github.com/datopian/markdowndb", + "toRaw": "https://github.com/datopian/markdowndb", + "text": "https://github.com/datopian/markdowndb", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://portaljs.org/guide", + "toRaw": "https://portaljs.org/guide", + "text": "https://portaljs.org/guide", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://portaljs.org/guide#tutorial-3-collaborating-with-others-on-your-website-project", + "toRaw": "https://portaljs.org/guide#tutorial-3-collaborating-with-others-on-your-website-project", + "text": "See it here", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://portaljs.org/guide#tutorial-4-customising-your-website-locally-and-previewing-your-changes-locally", + "toRaw": "https://portaljs.org/guide#tutorial-4-customising-your-website-locally-and-previewing-your-changes-locally", + "text": "See it here", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://lifeitself.org/", + "toRaw": "https://lifeitself.org/", + "text": "https://lifeitself.org/", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "https://lifeitself.org/blog", + "toRaw": "https://lifeitself.org/blog", + "text": "👉 Check out the changes!", + "embed": false, + "internal": false + }, + { + "from": "blog/summer-updates-2023.md", + "to": "static/img/blog/2023-09-02-what-we-shipped-in-june-aug/life-itself-top-picks.png", + "toRaw": "/static/img/blog/2023-09-02-what-we-shipped-in-june-aug/life-itself-top-picks.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/summer-updates-2023.md", + "to": "static/img/blog/2023-09-02-what-we-shipped-in-june-aug/life-itself-latest-blogs.png", + "toRaw": "/static/img/blog/2023-09-02-what-we-shipped-in-june-aug/life-itself-latest-blogs.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/summer-updates-2023.md", + "to": "static/img/blog/2023-09-02-what-we-shipped-in-june-aug/life-itself-categories.png", + "toRaw": "/static/img/blog/2023-09-02-what-we-shipped-in-june-aug/life-itself-categories.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/summer-updates-2023.md", + "to": "static/img/blog/2023-09-02-what-we-shipped-in-june-aug/life-itself-blog-post.png", + "toRaw": "/static/img/blog/2023-09-02-what-we-shipped-in-june-aug/life-itself-blog-post.png", + "text": "", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "0efcab582983a136b829b095a87e0e6444779fec", + "file_path": "content/blog/supercharging-data-portals-with-the-portaljs-mcp-server.md", + "extension": "md", + "url_path": "blog/supercharging-data-portals-with-the-portaljs-mcp-server", + "filetype": null, + "metadata": { + "title": "Supercharging Data Portals with the PortalJS MCP Server", + "description": "Explore how the PortalJS MCP server unlocks AI-native discovery, metadata exploration, and data previews for modern portals — now open sourced and easy to integrate.", + "created": "2025-11-25T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [ + "MCP", + "PortalJS Cloud", + "AI", + "data portals" + ], + "image": "/static/img/blog/supercharging-data-portals.png", + "filetype": "blog", + "tasks": [] + }, + "tags": [ + "MCP", + "PortalJS Cloud", + "AI", + "data portals" + ], + "links": [ + { + "from": "blog/supercharging-data-portals-with-the-portaljs-mcp-server.md", + "to": "blog/mcp-server-ai-assistants-to-improve-data-portals", + "toRaw": "/blog/mcp-server-ai-assistants-to-improve-data-portals", + "text": "our first look at using MCP (Model Context Protocol) servers", + "embed": false, + "internal": true + }, + { + "from": "blog/supercharging-data-portals-with-the-portaljs-mcp-server.md", + "to": "https://github.com/datopian/portaljs-mcp-server", + "toRaw": "https://github.com/datopian/portaljs-mcp-server", + "text": "https://github.com/datopian/portaljs-mcp-server", + "embed": false, + "internal": false + }, + { + "from": "blog/supercharging-data-portals-with-the-portaljs-mcp-server.md", + "to": "https://mermaid.live/edit#pako:eNpNjl9PgzAUxb9Kc580YYQxKLQxJhs8GU0WF19c91Dt3VgClJTWqITvbhm6eJ_un_M75w7wrhUCh5ORXUUen0VLfK33Lz2aA1ks7slmL6CopCXrruvJDZ4CUtTSKbwVcJjlm4uw2D8VW7JD8-HR-dC7t9l4q42V9cPOo9qp-ThV8a8ld5NL6eNKaeUvcs3AVkHg3zwr4NY4DKBB08hphGGSCLAVNiiA-1bhUbraChDt6LFOtq9aN3-k0e5UAT_KuveT65S0WJ6lf7W5bo0PRFNo11rgaXbxAD7AJ3DGQrqiGY3yPMnSnAXwBXxJozBKknQV53FMo4iNAXxfMqOQspwtaZzSJM4ymrDxBwREbd4", + "toRaw": "https://mermaid.live/edit#pako:eNpNjl9PgzAUxb9Kc580YYQxKLQxJhs8GU0WF19c91Dt3VgClJTWqITvbhm6eJ_un_M75w7wrhUCh5ORXUUen0VLfK33Lz2aA1ks7slmL6CopCXrruvJDZ4CUtTSKbwVcJjlm4uw2D8VW7JD8-HR-dC7t9l4q42V9cPOo9qp-ThV8a8ld5NL6eNKaeUvcs3AVkHg3zwr4NY4DKBB08hphGGSCLAVNiiA-1bhUbraChDt6LFOtq9aN3-k0e5UAT_KuveT65S0WJ6lf7W5bo0PRFNo11rgaXbxAD7AJ3DGQrqiGY3yPMnSnAXwBXxJozBKknQV53FMo4iNAXxfMqOQspwtaZzSJM4ymrDxBwREbd4", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "blog/supercharging-data-portals-with-the-portaljs-mcp-server.md", + "to": "blog/https:/mermaid.ink/img/pako:eNpNjl9PgzAUxb9Kc580YYQxKLQxJhs8GU0WF19c91Dt3VgClJTWqITvbhm6eJ_un_M75w7wrhUCh5ORXUUen0VLfK33Lz2aA1ks7slmL6CopCXrruvJDZ4CUtTSKbwVcJjlm4uw2D8VW7JD8-HR-dC7t9l4q42V9cPOo9qp-ThV8a8ld5NL6eNKaeUvcs3AVkHg3zwr4NY4DKBB08hphGGSCLAVNiiA-1bhUbraChDt6LFOtq9aN3-k0e5UAT_KuveT65S0WJ6lf7W5bo0PRFNo11rgaXbxAD7AJ3DGQrqiGY3yPMnSnAXwBXxJozBKknQV53FMo4iNAXxfMqOQspwtaZzSJM4ymrDxBwREbd4?type=png", + "toRaw": "https://mermaid.ink/img/pako:eNpNjl9PgzAUxb9Kc580YYQxKLQxJhs8GU0WF19c91Dt3VgClJTWqITvbhm6eJ_un_M75w7wrhUCh5ORXUUen0VLfK33Lz2aA1ks7slmL6CopCXrruvJDZ4CUtTSKbwVcJjlm4uw2D8VW7JD8-HR-dC7t9l4q42V9cPOo9qp-ThV8a8ld5NL6eNKaeUvcs3AVkHg3zwr4NY4DKBB08hphGGSCLAVNiiA-1bhUbraChDt6LFOtq9aN3-k0e5UAT_KuveT65S0WJ6lf7W5bo0PRFNo11rgaXbxAD7AJ3DGQrqiGY3yPMnSnAXwBXxJozBKknQV53FMo4iNAXxfMqOQspwtaZzSJM4ymrDxBwREbd4?type=png", + "text": "Architecture diagram", + "embed": true, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "b6114336b857429c2c09ffc5e3170f70670df51f", + "file_path": "content/blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations.md", + "extension": "md", + "url_path": "blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations", + "filetype": null, + "metadata": { + "title": "The Metadata Standards Landscape: Making Data Discoverable Across Organizations", + "created": "2025-07-08T00:00:00.000Z", + "description": "Navigate the world of metadata standards from Dublin Core to DCAT to Frictionless Data. Learn which standards work best for government, academic, and enterprise data portals, and how to choose the right approach for your organization.", + "authors": [ + "anuveyatsu" + ], + "image": "/static/img/blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations/metadata-standards-landscape-illustration.png", + "filetype": "blog", + "faqs": [ + { + "question": "Should I use multiple metadata standards together?", + "answer": "Yes, this is common and recommended. Start with Dublin Core for basic fields, add DCAT for data catalog specifics, and include Schema.org for web discoverability. Many organizations use a \"layered\" approach where standards complement rather than compete with each other." + }, + { + "question": "Which metadata standard is best for government data portals?", + "answer": "DCAT is the most widely adopted for government data portals, often with regional extensions like DCAT-AP in Europe or Project Open Data Schema in the US. These are built on Dublin Core foundations but add data catalog-specific features like distribution formats and update frequencies." + }, + { + "question": "How do I migrate from one metadata standard to another?", + "answer": "Plan for a gradual migration with field mapping between standards. Most standards share common elements (title, description, keywords), making core migration straightforward. Focus on high-value datasets first, and consider using tools like Frictionless Data that can bridge multiple standards." + }, + { + "question": "What's the difference between metadata standards and metadata schemas?", + "answer": "Standards define the conceptual framework and rules (like DCAT or Dublin Core), while schemas are the technical implementation (like JSON schemas or XML schemas). You can implement the same standard using different technical schemas depending on your platform needs." + } + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations.md", + "to": "blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs", + "toRaw": "/blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs", + "text": "previous exploration of metadata and data discovery", + "embed": false, + "internal": true + }, + { + "from": "blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations.md", + "to": "https://datasetsearch.research.google.com/", + "toRaw": "https://datasetsearch.research.google.com/", + "text": "https://datasetsearch.research.google.com/", + "embed": false, + "internal": false + }, + { + "from": "blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations.md", + "to": "static/img/blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations/metadata-standards-landscape-illustration.png", + "toRaw": "/static/img/blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations/metadata-standards-landscape-illustration.png", + "text": "Metadata standards landscape illustration", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "3c3ce3ae00b32423b7eb7e1d5f492f88c719d26e", + "file_path": "content/blog/the-new-look-of-portaljs-cloud.md", + "extension": "md", + "url_path": "blog/the-new-look-of-portaljs-cloud", + "filetype": null, + "metadata": { + "title": "The New Look of PortalJS Cloud", + "created": "2025-04-01T00:00:00.000Z", + "description": "Discover how the redesigned PortalJS Cloud helps you launch a modern, WCAG 2.1/2.2-compliant open data portal—fully responsive, customizable, and optimized for lightning-fast search and data sharing. Built for governments, non-profits, academic institutions, and private organizations, it's the easiest way to deploy a user-friendly data platform in minutes.", + "authors": [ + "williamlima", + "popovayoana" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "https://react.dev/learn/passing-data-deeply-with-context", + "toRaw": "https://react.dev/learn/passing-data-deeply-with-context", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "https://docs.google.com/document/d/1nOBBnGbvPot30MAGonG7dOBxkXWSavVNmEb2o9ZzLBw/edit?tab=t.0#heading=h.1rkstvo96k3f", + "toRaw": "https://docs.google.com/document/d/1nOBBnGbvPot30MAGonG7dOBxkXWSavVNmEb2o9ZzLBw/edit?tab=t.0#heading=h.1rkstvo96k3f", + "text": "accessibility article", + "embed": false, + "internal": false + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "https://www.portaljs.com/blog/making-portalJS-cloud-admin-panel-accessible", + "toRaw": "https://www.portaljs.com/blog/making-portalJS-cloud-admin-panel-accessible", + "text": "accessibility article.", + "embed": false, + "internal": false + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "https://cloud.portaljs.com/dashboard", + "toRaw": "https://cloud.portaljs.com/dashboard", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image14.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image14.webp", + "text": "Home page", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image9.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image9.webp", + "text": "Search page", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image3.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image3.webp", + "text": "Dataset page", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image7.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image7.webp", + "text": "Resource Preview Page", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image2.gif", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image2.gif", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image6.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image6.webp", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image8.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image8.webp", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image5.gif", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image5.gif", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image1.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image1.webp", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image10.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image10.webp", + "text": "Homepage before", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image11.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image11.webp", + "text": "Homepage after", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image12.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image12.webp", + "text": "Search page before", + "embed": true, + "internal": true + }, + { + "from": "blog/the-new-look-of-portaljs-cloud.md", + "to": "static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image13.webp", + "toRaw": "/static/img/blog/2025-04-01-the-new-look-of-portaljs-cloud/image13.webp", + "text": "Search page after", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "5754e538ea2f5c5c4f94a4bade48cd8c44e6d8da", + "file_path": "content/blog/the-open-spending-revamp-behind-the-scenes.md", + "extension": "md", + "url_path": "blog/the-open-spending-revamp-behind-the-scenes", + "filetype": null, + "metadata": { + "title": "The OpenSpending Revamp: Behind the Scenes", + "created": "2023-10-13T00:00:00.000Z", + "authors": [ + "Luccas Mateus", + "João Demenech" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "http://datopian.com/blog/the-open-spending-revamp-behind-the-scenes", + "toRaw": "http://datopian.com/blog/the-open-spending-revamp-behind-the-scenes", + "text": "the Datopian blog", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://www.datopian.com/blog/the-open-spending-revamp", + "toRaw": "https://www.datopian.com/blog/the-open-spending-revamp", + "text": "the Open Spending revamp", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://portaljs.org", + "toRaw": "https://portaljs.org", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://storybook.portaljs.org/?path=/story/components-flatuitable--from-url", + "toRaw": "https://storybook.portaljs.org/?path=/story/components-flatuitable--from-url", + "text": "FlatUI Component", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://portaljs.org", + "toRaw": "https://portaljs.org", + "text": "official PortalJS website", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://framework.frictionlessdata.io/", + "toRaw": "https://framework.frictionlessdata.io/", + "text": "official documentation", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://github.com/octokit/octokit.js", + "toRaw": "https://github.com/octokit/octokit.js", + "text": "GitHub repository", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://github.com/os-data", + "toRaw": "https://github.com/os-data", + "text": "OpenSpending Datasets", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://cloudflare.net/news/news-details/2021/Cloudflare-Announces-R2-Storage-Rapid-and-Reliable-S3-Compatible-Object-Storage-Designed-for-the-Edge/default.aspx", + "toRaw": "https://cloudflare.net/news/news-details/2021/Cloudflare-Announces-R2-Storage-Rapid-and-Reliable-S3-Compatible-Object-Storage-Designed-for-the-Edge/default.aspx", + "text": "blog post", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://github.com/datopian/portaljs/tree/main/examples/openspending", + "toRaw": "https://github.com/datopian/portaljs/tree/main/examples/openspending", + "text": "GitHub repository", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://www.openspending.org/", + "toRaw": "https://www.openspending.org/", + "text": "openspending.org", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://github.com/datopian/portaljs/issues", + "toRaw": "https://github.com/datopian/portaljs/issues", + "text": "GitHub issues page", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "https://discord.com/invite/EeyfGrGu4U", + "toRaw": "https://discord.com/invite/EeyfGrGu4U", + "text": "Discord Channel", + "embed": false, + "internal": false + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "static/img/blog/2023-10-13-the-open-spending-revamp-behind-the-scenes/data-visualization.png", + "toRaw": "/static/img/blog/2023-10-13-the-open-spending-revamp-behind-the-scenes/data-visualization.png", + "text": "Data visualization", + "embed": true, + "internal": true + }, + { + "from": "blog/the-open-spending-revamp-behind-the-scenes.md", + "to": "static/img/blog/2023-10-13-the-open-spending-revamp-behind-the-scenes/code-example.png", + "toRaw": "/static/img/blog/2023-10-13-the-open-spending-revamp-behind-the-scenes/code-example.png", + "text": "FlatUiTable Code Snippet", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "99c85085384d25a0bf0018a7576aefba72daf54d", + "file_path": "content/blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs.md", + "extension": "md", + "url_path": "blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs", + "filetype": null, + "metadata": { + "title": "Turning OpenMetadata into a User-Friendly Data Portal with PortalJS", + "description": "OpenMetadata is excellent for governance and power users, but difficult for broader audiences. Learn how PortalJS turns OpenMetadata into a user-friendly data portal focused on discovery and navigation.", + "created": "2026-01-09T00:00:00.000Z", + "authors": [ + "João Demenech" + ], + "tags": [ + "PortalJS", + "data portals", + "OpenMetadata" + ], + "image": "/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-search-page.png", + "filetype": "blog", + "tasks": [] + }, + "tags": [ + "PortalJS", + "data portals", + "OpenMetadata" + ], + "links": [ + { + "from": "blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs.md", + "to": "https://github.com/datopian/portaljs-frontend-starter-omd", + "toRaw": "https://github.com/datopian/portaljs-frontend-starter-omd", + "text": "https://github.com/datopian/portaljs-frontend-starter-omd", + "embed": false, + "internal": false + }, + { + "from": "blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs.md", + "to": "https://www.datopian.com/showcase/case-studies/simple-frontend-for-openmetadata-with-portaljs", + "toRaw": "https://www.datopian.com/showcase/case-studies/simple-frontend-for-openmetadata-with-portaljs", + "text": "Helping Researchers Find The Right Data Faster — With A Simple Frontend For OpenMetadata", + "embed": false, + "internal": false + }, + { + "from": "blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs.md", + "to": "https://github.com/datopian/portaljs-frontend-starter-omd", + "toRaw": "https://github.com/datopian/portaljs-frontend-starter-omd", + "text": "https://github.com/datopian/portaljs-frontend-starter-omd", + "embed": false, + "internal": false + }, + { + "from": "blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs.md", + "to": "static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-search-page.png", + "toRaw": "/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-search-page.png", + "text": "PortalJS Search Page", + "embed": true, + "internal": true + }, + { + "from": "blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs.md", + "to": "static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-dataset-details-page.png", + "toRaw": "/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-dataset-details-page.png", + "text": "PortalJS Dataset Details Page", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "d348fd4314378c049eb8d53ebb327a5a39e33724", + "file_path": "content/blog/upgrade-to-data-package-specs-v1.md", + "extension": "md", + "url_path": "blog/upgrade-to-data-package-specs-v1", + "filetype": null, + "metadata": { + "title": "Data Package v1 Specifications. What has Changed and how to Upgrade", + "created": "2017-10-11T00:00:00.000Z", + "authors": [ + "mikanebu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/upgrade-to-data-package-specs-v1.md", + "to": "https://specs.frictionlessdata.io/table-schema/", + "toRaw": "https://specs.frictionlessdata.io/table-schema/", + "text": "https://specs.frictionlessdata.io/table-schema/", + "embed": false, + "internal": false + }, + { + "from": "blog/upgrade-to-data-package-specs-v1.md", + "to": "https://specs.frictionlessdata.io/data-resource/", + "toRaw": "https://specs.frictionlessdata.io/data-resource/", + "text": "https://specs.frictionlessdata.io/data-resource/", + "embed": false, + "internal": false + }, + { + "from": "blog/upgrade-to-data-package-specs-v1.md", + "to": "https://specs.frictionlessdata.io/data-resource/", + "toRaw": "https://specs.frictionlessdata.io/data-resource/", + "text": "https://specs.frictionlessdata.io/data-resource/", + "embed": false, + "internal": false + }, + { + "from": "blog/upgrade-to-data-package-specs-v1.md", + "to": "https://specs.frictionlessdata.io/data-package/", + "toRaw": "https://specs.frictionlessdata.io/data-package/", + "text": "https://specs.frictionlessdata.io/data-package/", + "embed": false, + "internal": false + }, + { + "from": "blog/upgrade-to-data-package-specs-v1.md", + "to": "https://specs.frictionlessdata.io/tabular-data-package/", + "toRaw": "https://specs.frictionlessdata.io/tabular-data-package/", + "text": "https://specs.frictionlessdata.io/tabular-data-package/", + "embed": false, + "internal": false + }, + { + "from": "blog/upgrade-to-data-package-specs-v1.md", + "to": "http://specs.frictionlessdata.io/profiles/", + "toRaw": "http://specs.frictionlessdata.io/profiles/", + "text": "http://specs.frictionlessdata.io/profiles/", + "embed": false, + "internal": false + }, + { + "from": "blog/upgrade-to-data-package-specs-v1.md", + "to": "https://raw.githubusercontent.com/datahq/datapackage-normalize-js/master/normalize.js", + "toRaw": "https://raw.githubusercontent.com/datahq/datapackage-normalize-js/master/normalize.js", + "text": "https://raw.githubusercontent.com/datahq/datapackage-normalize-js/master/normalize.js", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "fd97566f57f0fad6d2c2edae50f95d4da5b16c5d", + "file_path": "content/blog/vega-upgrade-spec-v3.md", + "extension": "md", + "url_path": "blog/vega-upgrade-spec-v3", + "filetype": null, + "metadata": { + "title": "Vega views upgrade - now using v3", + "created": "2017-10-17T00:00:00.000Z", + "authors": [ + "anuveyatsu" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/vega-upgrade-spec-v3.md", + "to": "static/img/docs/vega-graph-example.png", + "toRaw": "/static/img/docs/vega-graph-example.png", + "text": "vega graph example", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "d4043ae8fdb629581fc4a584d2c857b9f0dda592", + "file_path": "content/blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS.md", + "extension": "md", + "url_path": "blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS", + "filetype": null, + "metadata": { + "title": "Why NASA — and Anyone Using CKAN — Should Consider a Decoupled Front-End with PortalJS", + "created": "2025-05-19T00:00:00.000Z", + "description": "NASA’s open data portal is powered by CKAN—but what if its user experience could match its scientific depth? This post explores how a decoupled frontend using PortalJS can transform performance, design flexibility, and scalability—without changing the backend. Learn how CKAN and PortalJS can work together to deliver a faster, smarter, and more user-friendly data experience.", + "authors": [ + "anuveyatsu", + "popovayoana" + ], + "filetype": "blog", + "image": "/static/img/blog/2025-05-19-why-anyone-should-consider-decoupled-frontend/image2.webp", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS.md", + "to": "https://data.nasa.gov", + "toRaw": "https://data.nasa.gov", + "text": "data.nasa.gov", + "embed": false, + "internal": false + }, + { + "from": "blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS.md", + "to": "https://data.nasa.gov", + "toRaw": "https://data.nasa.gov", + "text": "NASA’s portal", + "embed": false, + "internal": false + }, + { + "from": "blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS.md", + "to": "https://www.portaljs.com", + "toRaw": "https://www.portaljs.com", + "text": "site", + "embed": false, + "internal": false + }, + { + "from": "blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS.md", + "to": "https://calendar.app.google/sn2PU7ZvzjCPo1ok6", + "toRaw": "https://calendar.app.google/sn2PU7ZvzjCPo1ok6", + "text": "Talk to us", + "embed": false, + "internal": false + }, + { + "from": "blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS.md", + "to": "static/img/blog/2025-05-19-why-anyone-should-consider-decoupled-frontend/image2.webp", + "toRaw": "/static/img/blog/2025-05-19-why-anyone-should-consider-decoupled-frontend/image2.webp", + "text": "CKAN", + "embed": true, + "internal": true + }, + { + "from": "blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS.md", + "to": "static/img/blog/2025-05-19-why-anyone-should-consider-decoupled-frontend/PortalJS.gif", + "toRaw": "/static/img/blog/2025-05-19-why-anyone-should-consider-decoupled-frontend/PortalJS.gif", + "text": "PortalJS", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "333319b5973830cbd8a80ed0d19737a5f48b9763", + "file_path": "content/blog/why-portaljs-is-the-future-of-decoupled-frontend-for-data-portals.md", + "extension": "md", + "url_path": "blog/why-portaljs-is-the-future-of-decoupled-frontend-for-data-portals", + "filetype": null, + "metadata": { + "title": "Why PortalJS is the Future of Decoupled Frontend for Data Portals", + "description": "Let’s take a look at how PortalJS based decoupled frontend can improve your data portal, its performance, user experience and more.", + "created": "2024-12-06T00:00:00.000Z", + "authors": [ + "Anuar Ustayev" + ], + "filetype": "blog", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "651c81990d38c09efa0478d5ff1494393bd2b5a0", + "file_path": "content/blog/why-we-decoupled-CKAN-frontend.md", + "extension": "md", + "url_path": "blog/why-we-decoupled-CKAN-frontend", + "filetype": null, + "metadata": { + "title": "Why We Decoupled CKAN’s Frontend — And What We Gained with PortalJS", + "metatitle": "Decoupling CKAN’s Frontend with PortalJS: Performance, UX, Dev Speed.", + "created": "2025-05-28T00:00:00.000Z", + "description": "We explain why we chose to decouple CKAN’s frontend and how PortalJS made our data portal faster, more flexible, and easier to maintain. A practical look at SSG, serverless scaling, and modern dev workflows with CKAN.", + "metadescription": "Discover how decoupling CKAN’s frontend with PortalJS unlocks faster load times, better UX, easier dev workflows, and scalable data portals.", + "authors": [ + "popovayoana", + "anuveyatsu" + ], + "filetype": "blog", + "image": "/static/img/blog/2025-05-28-Why-we-decoupled-CKAN’s-frontend/image1.png", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/why-we-decoupled-CKAN-frontend.md", + "to": "https://www.datopian.com/solutions/ckan", + "toRaw": "https://www.datopian.com/solutions/ckan", + "text": "CKAN", + "embed": false, + "internal": false + }, + { + "from": "blog/why-we-decoupled-CKAN-frontend.md", + "to": "https://www.datopian.com/solutions/ckan", + "toRaw": "https://www.datopian.com/solutions/ckan", + "text": "CKAN", + "embed": false, + "internal": false + }, + { + "from": "blog/why-we-decoupled-CKAN-frontend.md", + "to": "https://www.portaljs.com/blog/why-portaljs-is-the-future-of-decoupled-frontend-for-data-portals", + "toRaw": "https://www.portaljs.com/blog/why-portaljs-is-the-future-of-decoupled-frontend-for-data-portals", + "text": "🔗 Explore the full technical breakdown", + "embed": false, + "internal": false + }, + { + "from": "blog/why-we-decoupled-CKAN-frontend.md", + "to": "static/img/blog/2025-05-28-Why-we-decoupled-CKAN’s-frontend/image1.png", + "toRaw": "/static/img/blog/2025-05-28-Why-we-decoupled-CKAN’s-frontend/image1.png", + "text": "CKAN", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "6dd6a7b23a740ed29e554175c7b66beb188ac69b", + "file_path": "content/blog/world-bank-indicators-on-datahub.md", + "extension": "md", + "url_path": "blog/world-bank-indicators-on-datahub", + "filetype": null, + "metadata": { + "title": "World Bank Indicators on DataHub", + "created": "2018-07-16T00:00:00.000Z", + "authors": [ + "branko-dj" + ], + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "blog/world-bank-indicators-on-datahub.md", + "to": "https://datahub.io/world-bank", + "toRaw": "https://datahub.io/world-bank", + "text": "https://datahub.io/world-bank", + "embed": false, + "internal": false + }, + { + "from": "blog/world-bank-indicators-on-datahub.md", + "to": "https://data.worldbank.org/indicator?tab=all", + "toRaw": "https://data.worldbank.org/indicator?tab=all", + "text": "https://data.worldbank.org/indicator?tab=all", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "89b133cabb6954bb9b1ccf6137e1de401e36b204", + "file_path": "content/case-studies/a-global-transport-hub-building-a-shared-open-data-infrastructure-for-30-plus-transport-organizations.md", + "extension": "md", + "url_path": "case-studies/a-global-transport-hub-building-a-shared-open-data-infrastructure-for-30-plus-transport-organizations", + "filetype": null, + "metadata": { + "filetype": "casestudy", + "created": "2025-06-07T00:00:00.000Z", + "title": "A Global Transport Hub - Building a shared, open data infrastructure for 30+ transport organizations", + "metatitle": "Transport Data Commons Open Data Portal Built with PortalJS and CKAN", + "metaDescription": "See how Transport Data Commons used PortalJS and CKAN to launch a global open data portal—automating ingestion, standardizing SDMX metadata, and improving data access.", + "description": "We helped the Transport Data Commons (TDC) transform fragmented transport and sustainability data into a unified, public-facing portal. Using CKAN and PortalJS, we built a user-friendly platform that standardizes metadata, automates data ingestion, and enables seamless access and collaboration across 30+ global organizations.", + "image": "/static/img/showcases/2025-06-06-TDC/featured-image.jpg", + "images": [ + "/static/img/showcases/2025-06-06-TDC/image1.png", + "/static/img/showcases/2025-06-06-TDC/image2.png", + "/static/img/showcases/2025-06-06-TDC/image3.png", + "/static/img/showcases/2025-06-06-TDC/image4.png", + "/static/img/showcases/2025-06-06-TDC/image5.png" + ], + "authors": [ + "williamlima" + ], + "keystats": [ + "30+ organizations/n sharing one shared portal", + "100% custom frontend/n built entirely with PortalJS", + "80% less manual work/n through automation and workflows" + ], + "faqs": [ + { + "question": "Is PortalJS only for CKAN?", + "answer": "No — PortalJS is backend-agnostic. It works equally well with CKAN, OpenMetadata, or custom APIs." + }, + { + "question": "Do I need a developer to manage the portal?", + "answer": "Not for everyday content. Editors can manage FAQs, About pages, and more via GitHub or your preferred CMS." + }, + { + "question": "How long does a PortalJS portal take to launch?", + "answer": "Most deployments go live in 1–2 weeks, depending on the features needed." + }, + { + "question": "Can we manage our own hosting later?", + "answer": "Yes. Many clients start with Datopian-hosted and then move to internal infrastructure. We help with migration." + }, + { + "question": "What makes this better than just CKAN?", + "answer": "CKAN is great for metadata and APIs. PortalJS adds the human layer — modern search, visualizations, dashboards, and guided user experiences." + } + ], + "problem": "Transport and sustainability data was scattered across disconnected systems—PDFs, spreadsheets, and portals with limited structure. There was no unified place to find consistent, high-quality datasets. Without shared metadata standards or clear contribution processes, organizations struggled to collaborate, often duplicating work. Analysts spent more time cleaning data than analyzing it.", + "solution": "Datopian delivered a unified open data platform using CKAN for the backend and PortalJS for the frontend. We replaced the default UI with a custom, fully decoupled interface tailored to non-technical users. The platform includes automated data ingestion pipelines, SDMX-compliant metadata, rich search and filter tools, onboarding flows, and role-based publishing workflows—making data management and access faster, simpler, and more reliable.", + "results": "TDC now operates a centralized, public data portal where 30+ organizations can contribute, manage, and explore datasets efficiently. The platform enables faster decision-making, reduces duplication, and supports international collaboration. Contributors follow structured publishing flows; users benefit from intuitive discovery tools. By standardizing data and simplifying workflows, the portal turns fragmented inputs into a shared, trusted resource.", + "features": [ + { + "title": "Built for multi-organization publishing", + "text": "PortalJS is ideal for coalitions like TDC — enabling role-based access, contributor dashboards, and streamlined publishing across 30+ organizations.", + "icon": "hexagonal" + }, + { + "title": "Supports structured metadata like SDMX", + "text": "TDC needed metadata aligned with SDMX standards. PortalJS made it easy to surface, search, and display structured datasets clearly.", + "icon": "presentation-1" + }, + { + "title": "Turned disconnected data into a unified platform", + "text": "From scattered PDFs to a live, searchable portal — PortalJS helped TDC centralize transport and sustainability data in one public space.", + "icon": "rocket" + }, + { + "title": "Frontend flexibility without backend changes", + "text": "All workflows — including dataset approval, visibility toggling, and publishing flows — were built on the frontend with no backend rewrites.", + "icon": "repair-tools" + }, + { + "title": "Visual exploration through filters and maps", + "text": "Users can search by region, sector, or keyword — or use an interactive map to explore country-specific datasets.", + "icon": "magnify" + }, + { + "title": "Custom contributor onboarding flow", + "text": "We built a guided onboarding experience tailored to TDC: helping users follow topics, join organizations, and start contributing with confidence.", + "icon": "presentation-4" + } + ], + "quote": [ + "This isn’t just a frontend — it’s a public infrastructure for collaboration on transport data.", + "/static/img/showcases/2025-06-06-TDC/logo.png", + "Transport Data Commons" + ], + "portal": [ + "The Transport Data Commons Portal", + "A clean, intuitive frontend built for contributors and analysts.", + "https://portal.transport-data.org/" + ], + "table": false, + "longRead": false, + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "case-studies/a-global-transport-hub-building-a-shared-open-data-infrastructure-for-30-plus-transport-organizations.md", + "to": "https://portal.transport-data.org/", + "toRaw": "https://portal.transport-data.org/", + "text": "https://portal.transport-data.org/", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "e6ff800e4a3cc82bc9b8d9dc29ecc095bcd0ebeb", + "file_path": "content/case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "extension": "md", + "url_path": "case-studies/eiti-fully-customizable-data-portal-in-minutes", + "filetype": null, + "metadata": { + "filetype": "casestudy", + "created": "2025-02-10T00:00:00.000Z", + "title": "Empowering EITI / Through a Fully Customizable Open Data Portal in Minutes", + "description": "Discover how the [The Extractive Industries Transparency Initiative (EITI)](https://eiti.org/) partnered with the [Civic Literacy Initiative](https://civicliteraci.es/) and PortalJS Cloud to create a fully customizable open data portal. Access in-depth, reliable datasets on extractive industries worldwide, explore intuitive data visualizations, and enjoy a responsive, user-friendly experience.", + "image": "/images/case3.webp", + "images": [ + "/images/casestudies/eiti-home.webp", + "/images/casestudies/eiti-search.webp" + ], + "authors": [ + "popovayoana", + "lucasbispo" + ], + "keystats": [ + "5-Minute/n portal setup", + "Zero/n maintenance", + "100% Scalable,/n secure infrastructure" + ], + "problem": "[EITI](https://eiti.org/), as the global leader in promoting extractive industry transparency, required a robust, scalable, and **customizable digital platform**. Their goal was to consolidate vast datasets into an easy-to-navigate, user-friendly portal while ensuring seamless **data dissemination** to policymakers, journalists, and the public. Additionally, they needed full control over design and functionality without a dedicated IT team. Some of their challenges included:\n- **Outdated Infrastructure**: EITI’s prior tools lacked scalability and customization.\n- **Limited Accessibility**: Stakeholders struggled to navigate and analyze complex datasets.\n- **Rigid UI/UX**: The platform couldn’t evolve to meet the needs of a diverse global audience.", + "solution": "PortalJS Cloud provided EITI with a flexible, cloud-based solution, enabling the creation of a centralized open data portal **in minutes**. With its full access to the underlying source code, EITI can easily tailor the platform’s UI/UX, ensuring continuous improvements and a seamless path toward greater transparency, accountability, and civic engagement.\n- **Developer-Friendly Environment**: Full access to source code for seamless iteration.\n- **Intuitive Design**: Enhanced navigation, responsive layouts, and data visualization tools.\n- **Scalable & Secure**: Infrastructure that grows alongside data and user demands.", + "results": "The new EITI open data portal became a **central hub** for stakeholders to access detailed reports, visualize extractive industry data, and explore global datasets effortlessly. The scalable infrastructure and rapid deployment empowered EITI to focus on their mission of transparency without being burdened by IT complexities.", + "features": [ + { + "title": "Rapid Deployment with Zero Maintenance", + "text": "EITI launched their fully functional open data portal in less than a day using PortalJS Cloud. The platform eliminates the need for manual IT setup and ongoing maintenance, freeing up resources to focus on critical tasks.", + "icon": "rocket" + }, + { + "title": "Comprehensive Data Repository", + "text": "The portal hosts a wide array of open datasets, including country-level reports, production figures, and revenue distributions. This makes it a one-stop shop for anyone seeking reliable extractive industry data.", + "icon": "database" + }, + { + "title": "Full Customization & Developer-Friendly Access", + "text": "EITI leveraged the platform’s **public GitHub repository**, tailoring the portal to align with their branding and mission. They redesigned the UI/UX, integrated advanced data visualizations, and implemented features like **custom search filters** for better data discovery.", + "icon": "browser" + }, + { + "title": "Scalable, Secure Infrastructure", + "text": "The portal’s infrastructure supports large data volumes and high user traffic without compromising on performance or data security, ensuring reliable access at all times.", + "icon": "api" + }, + { + "title": "Continuous Improvement", + "text": "With access to the portal’s underlying source code, EITI continuously evolves their platform by responding to user feedback, adding new features, and refining the user experience.", + "icon": "verified" + } + ], + "quote": [ + "PortalJS Cloud allowed us to create a robust, user-friendly open data portal that meets our transparency goals while being adaptable to our evolving needs.", + "/images/casestudies/hounslow-logo.webp", + "EITI Representative" + ], + "portal": [ + "The EITI Open Data Portal", + "As part of its open data strategy, EITI officially launches the data portal built on PortalJS with consulting by Datopian.", + "https://eiti.portaljs.com" + ], + "table": "default", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://eiti.org/", + "toRaw": "https://eiti.org/", + "text": "The Extractive Industries Transparency Initiative (EITI)", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://civicliteraci.es/", + "toRaw": "https://civicliteraci.es/", + "text": "Civic Literacy Initiative", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://eiti.org/", + "toRaw": "https://eiti.org/", + "text": "EITI", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://eiti.portaljs.com", + "toRaw": "https://eiti.portaljs.com", + "text": "https://eiti.portaljs.com", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://eiti.org/", + "toRaw": "https://eiti.org/", + "text": "The Extractive Industries Transparency Initiative (EITI)", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://civicliteraci.es/", + "toRaw": "https://civicliteraci.es/", + "text": "Civic Literacy Initiative", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://eiti.org/", + "toRaw": "https://eiti.org/", + "text": "EITI", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://civicliteraci.es/", + "toRaw": "https://civicliteraci.es/", + "text": "Civic Literacy Initiative", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://portaljs.com", + "toRaw": "https://portaljs.com", + "text": "PortalJS Cloud Team", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://eiti.portaljs.com", + "toRaw": "https://eiti.portaljs.com", + "text": "https://eiti.portaljs.com", + "embed": false, + "internal": false + }, + { + "from": "case-studies/eiti-fully-customizable-data-portal-in-minutes.md", + "to": "https://cloud.portaljs.com", + "toRaw": "https://cloud.portaljs.com", + "text": "Get started with PortalJS Cloud today", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "13aa9b582f9df4249a2372df5b8d4ca8961db4c7", + "file_path": "content/case-studies/london-borough-of-hounslow.md", + "extension": "md", + "url_path": "case-studies/london-borough-of-hounslow", + "filetype": null, + "metadata": { + "filetype": "casestudy", + "created": "2025-01-27T00:00:00.000Z", + "title": "London Borough of Hounslow / Cuts Costs with PortalJS Cloud", + "description": "Discover how the London Borough of Hounslow transformed its open data management by migrating from self-hosted CKAN to PortalJS Cloud. Learn how to launch your open data portal in 5 minutes, reduce AWS costs, and boost data accessibility and civic engagement.", + "image": "/images/case2.webp", + "images": [ + "/images/casestudies/hounslow-screenshot.webp", + "/images/casestudies/hounslow-search.webp", + "/images/casestudies/hounslow-dataset.webp", + "/images/casestudies/hounslow-groups.webp" + ], + "authors": [ + "popovayoana", + "lucasbispo" + ], + "keystats": [ + "50% reduction/n in cloud costs", + "Zero maintenance/n overhead", + "Enhanced UI/UX/n & accessibility" + ], + "problem": "### The Challenge: Scaling Open Data Without Operational Overhead\n- **Infrastructure Complexity** – Managing a self-hosted CKAN platform on AWS required significant resources and expertise.\n- **High Maintenance Overhead** – Security patches, updates, and server management were consuming valuable IT bandwidth.\n- **Escalating Cloud Costs** – AWS infrastructure expenses increased as data demands grew, making cost control a challenge.", + "solution": "### PortalJS Cloud: A Fully Managed, Cost-Effective Solution\n#### Key Features & Benefits:\n- **Zero Infrastructure Management**: Fully managed hosting and support.\n- **Cost Optimization**: Lower cloud & staffing costs with a pay-as-you-go model.\n- **Custom UI/UX Design**: Enhanced accessibility & branding.\n- **Scalability & Security**: Future-proof, automated updates & compliance.", + "results": "### Results:\nMigrating to PortalJS Cloud allowed the Borough to eliminate infrastructure maintenance, cut costs, and allocate resources more effectively. The open data portal remains accessible, reliable, and cost-efficient without requiring ongoing technical oversight.", + "features": [ + { + "title": "No Infrastructure Maintenance", + "text": "PortalJS Cloud manages updates, security, and hosting.", + "icon": "server" + }, + { + "title": "Cost Optimization", + "text": "Pay-as-you-go model reduces cloud and staffing expenses.", + "icon": "ewallet" + }, + { + "title": "Seamless Scaling", + "text": "Adapts automatically to increasing data demands.", + "icon": "expand" + }, + { + "title": "Improved UI/UX", + "text": "Faster load times, modern design, and better navigation.", + "icon": "browser" + } + ], + "quote": [ + "With PortalJS Cloud, we no longer worry about infrastructure. We’ve cut costs and improved our platform’s usability for citizens and researchers alike.", + "/images/casestudies/hounslow-logo.webp", + "London Borough of Hounslow" + ], + "portal": [ + "The Hounslow Open Data Portal", + "The London Borough of Hounslow collaborated with Datopian to deploy a fully managed data portal leveraging the capabilities of PortalJS Cloud.", + "https://data.hounslow.gov.uk" + ], + "table": "default", + "fullCaseStudy": "", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "case-studies/london-borough-of-hounslow.md", + "to": "https://data.hounslow.gov.uk", + "toRaw": "https://data.hounslow.gov.uk", + "text": "https://data.hounslow.gov.uk", + "embed": false, + "internal": false + }, + { + "from": "case-studies/london-borough-of-hounslow.md", + "to": "https://data.hounslow.gov.uk", + "toRaw": "https://data.hounslow.gov.uk", + "text": "https://data.hounslow.gov.uk/", + "embed": false, + "internal": false + }, + { + "from": "case-studies/london-borough-of-hounslow.md", + "to": "https://cloud.portaljs.com", + "toRaw": "https://cloud.portaljs.com", + "text": "Get started with PortalJS Cloud today", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "48db7e4edc866abe4bdf7a380648b5be24821cfc", + "file_path": "content/case-studies/modernizing-lincolnshire-county-council39s-open-data-portal.md", + "extension": "md", + "url_path": "case-studies/modernizing-lincolnshire-county-council39s-open-data-portal", + "filetype": null, + "metadata": { + "filetype": "casestudy", + "created": "2026-03-03T00:00:00.000Z", + "title": "Modernizing Lincolnshire County Council / From Dedicated CKAN Instance to Managed PortalJS Cloud Service", + "description": "Discover how Lincolnshire County Council transformed their data publishing approach, migrating from a dedicated CKAN instance to PortalJS Cloud. Reduced operational costs, simplified administration, and delivered a modern user experience without compromising their established catalogue.", + "image": "/images/casestudies/linconshire0.jpg", + "images": [ + "/images/casestudies/lincolnshire1.png", + "/images/casestudies/lincolnshire2.png", + "/images/casestudies/lincolnshire3.png", + "/images/casestudies/lincolnshire4.png" + ], + "authors": [ + "popovayoana" + ], + "keystats": [ + "Seamless/n catalogue migration", + "Zero/n infrastructure overhead", + "100%/n Budget-friendly solution" + ], + "problem": " Lincolnshire County Council had built a solid open data programme on CKAN, serving their community with 60+ datasets across essential public services. As a smaller authority, however, they found themselves managing infrastructure complexity that was better suited to larger organizations with dedicated technical teams. Their challenges centered around operational fit rather than technology limitations:\n\n- **Infrastructure Management Overhead**: Running a dedicated instance required server administration and technical maintenance that consumed staff time.\n- **Admin Interface Complexity**: CKAN's powerful admin dashboard was designed for technical users, creating friction for council staff who needed to focus on data rather than platform management.\n\n- **Limited Self-Service Capability**: Routine updates and content management required technical intervention, slowing down day-to-day operations. ", + "solution": " PortalJS Cloud delivered exactly what Lincolnshire needed: a managed service that eliminated infrastructure costs while providing a modern, customizable frontend. The migration preserved their entire CKAN catalogue while giving council staff direct control over day-to-day operations through an intuitive admin dashboard..\n- **Complete Data Migration**: Every dataset, resource, organization, and metadata element transferred seamlessly from CKAN to PortalJS Cloud.\n\n- **Modern, Branded Interface**: Fully customised frontend reflecting Lincolnshire County Council''s visual identity and accessibility requirements.\n\n- **Staff Empowerment**: Admin workflows simplified so council staff can manage content, users, and configurations without technical support.", + "results": "Lincolnshire's open data portal is now both more cost-effective and easier to operate. The modern interface serves their community of residents, researchers, and developers through clean data discovery tools, while the simplified admin experience lets council staff focus on data quality rather than platform maintenance.", + "features": [ + { + "title": "Cost-Effective Managed Service", + "text": "Lincolnshire moved from managing their own infrastructure to a fully managed service model with PortalJS Cloud. This eliminated the need for server administration and technical maintenance, letting council staff focus on their data rather than the platform underneath it.", + "icon": "rocket" + }, + { + "title": "Complete Catalogue Preservation", + "text": "The migration transferred all 60 published datasets, 10 topic categories, and 6 organizational structures without data loss. Download links, metadata relationships, and search functionality remained fully intact.", + "icon": "database" + }, + { + "title": "Intuitive Self-Service Administration", + "text": "Council staff now manage datasets, users, and portal configuration through PortalJS Cloud's purpose-built dashboard—no need to navigate CKAN's complex admin interface or route requests through developers.", + "icon": "browser" + }, + { + "title": "Modern User Experience", + "text": "Built on Next.js and Tailwind CSS, the new portal delivers faster performance, responsive design, and accessibility compliance that meets contemporary web standards.", + "icon": "verified" + }, + { + "title": "Simplified Customization", + "text": "Frontend updates, branding changes, and feature additions can be implemented directly by the council team without specialist development resources.", + "icon": "paint-roller" + } + ], + "quote": [ + "\"PortalJS Cloud allowed us to maintain our data publishing commitments while working within our budget constraints. The migration was seamless and the ongoing operational savings have been significant.\"", + "/images/casestudies/lincon.svg", + "Lincolnshire County Council Representative" + ], + "portal": [ + "Lincolnshire Open Data Portal", + "As part of its digital transformation strategy, Lincolnshire County Council migrated to PortalJS Cloud with consulting and migration services by Datopian.", + "https://data.lincolnshire.gov.uk" + ], + "table": "default", + "longReadLink": "https://www.datopian.com/showcase/case-studies/lincolnshire-county-council-portaljs-cloud-migration", + "longReadTitle": "How Lincolnshire County Council Modernised Its Open Data Portal with PortalJS Cloud", + "longReadSummary": "Read the complete breakdown of architecture, migration approach, and outcomes — from dedicated CKAN instance to fully managed PortalJS Cloud.", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "case-studies/modernizing-lincolnshire-county-council39s-open-data-portal.md", + "to": "https://data.lincolnshire.gov.uk", + "toRaw": "https://data.lincolnshire.gov.uk", + "text": "https://data.lincolnshire.gov.uk", + "embed": false, + "internal": false + }, + { + "from": "case-studies/modernizing-lincolnshire-county-council39s-open-data-portal.md", + "to": "https://www.datopian.com/showcase/case-studies/lincolnshire-county-council-portaljs-cloud-migration", + "toRaw": "https://www.datopian.com/showcase/case-studies/lincolnshire-county-council-portaljs-cloud-migration", + "text": "https://www.datopian.com/showcase/case-studies/lincolnshire-county-council-portaljs-cloud-migration", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "c5742354d650ef8bacf23073076799c4799313ed", + "file_path": "content/case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "extension": "md", + "url_path": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan", + "filetype": null, + "metadata": { + "filetype": "casestudy", + "created": "2025-01-27T00:00:00.000Z", + "title": "Open Energy Data / How SSEN Tackled Massive Energy Data Challenges with PortalJS and CKAN", + "description": "Learn how Scottish & Southern Electricity Networks partnered with us at Datopian to create a user-first open data portal that handles millions of data points daily, enhances energy management, and supports sustainable goals.", + "image": "/images/casestudies/ssen-feature.webp", + "images": [ + "/images/casestudies/ssen1.webp", + "/images/casestudies/ssen2.webp", + "/images/casestudies/ssen3.webp" + ], + "authors": [ + "popovayoana", + "lucasbispo" + ], + "keystats": [ + "3.8M/n endpoints seamlessly managed", + "1TB+/n of data processed every day", + "10K+/n datasets published" + ], + "problem": "### Wrangling endless energy data was draining resources\n- **Massive Datasets** – SSEN needed to manage and query terabytes of energy data daily, including data from 3.8 million endpoints.\n- **Operational Bottlenecks** – Outdated tools struggled with complex data queries, hampering decision-making.\n- **Security Risks** – Sensitive data lacked robust access controls, raising concerns for both administrators and users.", + "solution": "### A data portal built for efficiency, security, and scale\n- **PortalJS Frontend**: A fast, responsive interface designed to make data exploration intuitive.\n- **CKAN Backend**: A data powerhouse to organize, store, and share energy datasets with precision.\n- **ETL Workflow**: Prefect and BigQuery enable efficient data ingestion and analysis, turning massive data loads into actionable insights.\n- **Enhanced Security**: Extensions like ckanext-noanonaccess protect sensitive data while allowing seamless administrative controls.", + "results": "### Making energy data work smarter, not harder\n- SSEN’s new portal can process and query over 1TB of data daily without breaking a sweat.\n- User satisfaction skyrocketed with faster queries and better access to critical insights.\n- The portal supports sustainability initiatives, paving the way for net-zero goals.", + "features": [ + { + "title": "Lightning-Fast Frontend", + "text": "PortalJS delivers a sleek, intuitive interface that’s built for usability.", + "icon": "favorite" + }, + { + "title": "Reliable Data Backbone", + "text": "[CKAN](https://www.datopian.com/solutions/ckan) ensures large datasets are stored, organized, and shared efficiently.", + "icon": "database" + }, + { + "title": "Powerful Add-Ons", + "text": "Extensions like ckanext-dcat and ckanext-scheming boost interoperability and customization.", + "icon": "layers" + }, + { + "title": "Scalable Infrastructure", + "text": "BigQuery and Prefect make processing and analyzing huge datasets (over 1TB of data) effortless.", + "icon": "cloud-network" + } + ], + "quote": [ + "I would like to take this opportunity to extend my heartfelt gratitude for the outstanding support and collaboration your team has offered over the past year. The agility, technical prowess, and steadfast dedication you have demonstrated are truly commendable. Your efforts have been integral to our successes, and I am deeply appreciative. I am hopeful that there will be opportunities for me to engage with future projects and contribute. Thank you once again for your exemplary contribution and for the positive spirit you bring to our work.", + "/images/casestudies/ssen-logo.png", + "Shailesh Kumar, Analytics and Data Architect - SSEN" + ], + "portal": [ + "SSEN Open Data Portal", + "Designed for flexibility and scalability, PortalJS allows the frontend to evolve independently from the backend, ensuring seamless updates and a user-centric experience.", + "https://data.ssen.co.uk" + ], + "table": "ssen", + "fullCaseStudy": "https://www.datopian.com/showcase/case-studies/empowering-energy-sector-ckan-portaljs-scottish-southern-electricity-networks", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.datopian.com/solutions/ckan", + "toRaw": "https://www.datopian.com/solutions/ckan", + "text": "CKAN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://data.ssen.co.uk", + "toRaw": "https://data.ssen.co.uk", + "text": "https://data.ssen.co.uk", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.datopian.com/showcase/case-studies/empowering-energy-sector-ckan-portaljs-scottish-southern-electricity-networks", + "toRaw": "https://www.datopian.com/showcase/case-studies/empowering-energy-sector-ckan-portaljs-scottish-southern-electricity-networks", + "text": "https://www.datopian.com/showcase/case-studies/empowering-energy-sector-ckan-portaljs-scottish-southern-electricity-networks", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "Scottish and Southern Electricity Networks (SSEN)", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://datopian.com", + "toRaw": "https://datopian.com", + "text": "Datopian", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://datopian.com", + "toRaw": "https://datopian.com", + "text": "Datopian", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.datopian.com/solutions/ckan", + "toRaw": "https://www.datopian.com/solutions/ckan", + "text": "CKAN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://datopian.com", + "toRaw": "https://datopian.com", + "text": "Datopian", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://datopian.com", + "toRaw": "https://datopian.com", + "text": "Datopian", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.datopian.com/solutions/ckan", + "toRaw": "https://www.datopian.com/solutions/ckan", + "text": "CKAN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://datopian.com", + "toRaw": "https://datopian.com", + "text": "Datopian", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://data.ssen.co.uk/", + "toRaw": "https://data.ssen.co.uk/", + "text": "The SSEN Data Portal", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/", + "toRaw": "https://www.ssen.co.uk/", + "text": "SSEN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://datopian.com", + "toRaw": "https://datopian.com", + "text": "Datopian", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.datopian.com/solutions/ckan", + "toRaw": "https://www.datopian.com/solutions/ckan", + "text": "CKAN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.ssen.co.uk/’s", + "toRaw": "https://www.ssen.co.uk/’s", + "text": "https://www.ssen.co.uk/’s", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.datopian.com/showcase/case-studies/empowering-energy-sector-ckan-portaljs-scottish-southern-electricity-networks", + "toRaw": "https://www.datopian.com/showcase/case-studies/empowering-energy-sector-ckan-portaljs-scottish-southern-electricity-networks", + "text": "https://www.datopian.com/showcase/case-studies/empowering-energy-sector-ckan-portaljs-scottish-southern-electricity-networks", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://www.datopian.com/showcase/case-studies/enhancing-energy-efficiency-scottish-southern-electricity-networks", + "toRaw": "https://www.datopian.com/showcase/case-studies/enhancing-energy-efficiency-scottish-southern-electricity-networks", + "text": "https://www.datopian.com/showcase/case-studies/enhancing-energy-efficiency-scottish-southern-electricity-networks", + "embed": false, + "internal": false + }, + { + "from": "case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md", + "to": "https://cloud.portaljs.com", + "toRaw": "https://cloud.portaljs.com", + "text": "Get started with PortalJS Cloud today", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "4c979d971cc80edaf8bb13e5d5b8095a87dea3c7", + "file_path": "content/case-studies/simplifying-healthcare-metadata.md", + "extension": "md", + "url_path": "case-studies/simplifying-healthcare-metadata", + "filetype": null, + "metadata": { + "filetype": "casestudy", + "created": "2025-06-07T00:00:00.000Z", + "title": "Simplifying Healthcare Metadata / Making Sensitive Data Usable — Without Changing the Backend", + "metatitle": "PortalJS for OpenMetadata | Simple, Secure Frontend for Healthcare Data", + "metaDescription": "A UK public health agency used PortalJS to build a clean, searchable frontend over OpenMetadata—enabling non-technical researchers to securely discover and request 300+ datasets via Azure.", + "description": "Discover how a UK public health organization transformed complex metadata into a searchable, user-friendly experience. Built with PortalJS over OpenMetadata, this frontend gives non-technical researchers secure access to 300+ datasets — no backend overhaul required.", + "image": "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/featured-image.jpg", + "images": [ + "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/image1.jpg", + "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/image2.jpg", + "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/image3.jpg", + "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/image4.jpg", + "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/image5.jpg", + "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/image6.jpg", + "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/image7.jpg", + "/static/img/showcases/2025-06-05-simplifying-healthcare-metadata/image8.jpg" + ], + "authors": [ + "luccasmateus" + ], + "keystats": [ + "100% Secure/n Entra ID login, Azure-hosted", + "300+ Datasets/n searchable via PortalJS", + "60% Fewer Tickets/n metadata-related support requests down" + ], + "faqs": [ + { + "question": "Does this replace OpenMetadata?", + "answer": "No — it extends it. PortalJS acts as a frontend layer while OpenMetadata remains the backend." + }, + { + "question": "Is this secure enough for healthcare data?", + "answer": "Yes. All access is governed via Microsoft Entra ID. No data is exposed unless authorized." + }, + { + "question": "Can I deploy this on my own infrastructure?", + "answer": "Absolutely. The solution is delivered as a Docker container and works seamlessly with Azure-based environments." + }, + { + "question": "What if I'm not in healthcare?", + "answer": "No problem — PortalJS works across sectors: government, energy, finance, climate, and more." + } + ], + "problem": "### Sensitive healthcare data was locked behind technical barriers\n- **Hidden Catalog**- Researchers couldn’t view or search the full dataset inventory across virtual machines.\n- **Fragmented Access**- Each user only saw a limited slice of the data, causing duplicated work and missed insights.\n- **Technical Interfaces**- OpenMetadata’s UI was built for engineers, not clinicians or public health researchers — resulting in friction and delays.", + "solution": "### A user-friendly PortalJS frontend over OpenMetadata\n- **PortalJS Interface**- A lightweight, intuitive frontend tailored for non-technical researchers to explore and request data.\n- **OpenMetadata Backbone**- Metadata, access control, and governance handled via robust backend APIs — invisible to end users.\n- **Smart Features**- Secure login with Microsoft Entra ID, built-in glossary, dataset Q&A, and one-click publishing to virtual workspaces.", + "results": "### Healthcare research workflows — simplified and accelerated\n- **Unified Discovery**- Researchers can now search and filter across the full dataset catalog with ease.\n- **Human-Centric UX**- Q&A threads and glossary terms reduce confusion and support tickets.\n- **Operational Boost**- Faster dataset provisioning, better data reuse, and less friction in onboarding new researchers.", + "features": [ + { + "title": "Api-first, backend-agnostic", + "text": "Build modern data portals on any backend — from CKAN to OpenMetadata — using a clean, decoupled, API-first architecture.", + "icon": "standards" + }, + { + "title": "Modern web stack", + "text": "Built with Next.js, TailwindCSS, and React — PortalJS offers a lightweight, maintainable, developer-friendly foundation.", + "icon": "api" + }, + { + "title": "Dockerized for speed", + "text": "Deploy fast with containerized builds that fit neatly into your DevOps pipelines — on cloud or on-prem.", + "icon": "rocket" + }, + { + "title": "Designed for non-technical users", + "text": "Make data usable for everyone — researchers, citizens, analysts — with intuitive, clean UI tailored to real-world needs.", + "icon": "presentation-3" + }, + { + "title": "Secure by design", + "text": "Integrates easily with identity providers like Microsoft Entra ID to ensure secure, role-based access control.", + "icon": "key" + }, + { + "title": "Pluggable and extensible", + "text": "Adapt and grow your portal with reusable components, custom layouts, and rich integration options — all without vendor lock-in.", + "icon": "puzzle" + } + ], + "quote": [ + "We needed a simple way to bridge usability gaps without rebuilding infrastructure. PortalJS delivered exactly that.", + "", + " Project Stakeholder, Public Health Data Service " + ], + "portal": [ + "The Public Health Data Portal", + "A clean, Azure-integrated data portal built with researchers in mind." + ], + "table": "healthcare", + "longRead": false, + "fullCaseStudy": "https://www.datopian.com/showcase/case-studies/simple-frontend-for-openmetadata-with-portaljs", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "case-studies/simplifying-healthcare-metadata.md", + "to": "https://www.datopian.com/showcase/case-studies/simple-frontend-for-openmetadata-with-portaljs", + "toRaw": "https://www.datopian.com/showcase/case-studies/simple-frontend-for-openmetadata-with-portaljs", + "text": "https://www.datopian.com/showcase/case-studies/simple-frontend-for-openmetadata-with-portaljs", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "e09935b4776ac4a9dc38e54923402771d3179509", + "file_path": "content/case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "extension": "md", + "url_path": "case-studies/uae-moei-scalable-platform-government-data-publishing", + "filetype": null, + "metadata": { + "filetype": "casestudy", + "created": "2025-01-27T00:00:00.000Z", + "title": "UAE MOEI Open Data Portal / A Scalable Platform for Government Data Publishing", + "description": "How MOEI launched a fully branded, scalable, and user-friendly data platform using PortalJS + CKAN—built for citizens, researchers, and developers. A fully managed, bilingual open data portal—custom-branded, API-first, and built for real public use. Delivered on MOEI’s infrastructure with zero maintenance required and full control for non-technical staff.", + "image": "/images/casestudies/moei-featured.webp", + "images": [ + "/images/casestudies/moei-5.webp", + "/images/casestudies/moei-4.webp", + "/images/casestudies/moei-7.webp" + ], + "authors": [ + "popovayoana", + "lucasbispo" + ], + "keystats": [ + "2 languages/n natively supported", + "50+ datasets/n published and growing", + "100% integration/n with Azure and ministry branding" + ], + "problem": "MOEI needed a modern, public-facing open data portal to serve citizens, developers, and analysts. Their legacy setup lacked a centralized system, real-time data access, API connectivity, and full bilingual support. Data publishing was fragmented and difficult to manage. The lack of interactive tools and scalable infrastructure limited their ability to meet public transparency goals and support digital government initiatives.", + "solution": "Datopian delivered a full-stack solution using **PortalJS** for the frontend and **CKAN** for the backend, deployed on MOEI’s existing **Azure infrastructure**. The portal is fully bilingual (Arabic \\+ English, with RTL support), mobile-friendly, and aligned with the Ministry’s digital brand.\nUsers can search, preview, and visualize datasets, request new data, and submit feedback—all within a clean, intuitive interface.\nMOEI’s non-technical staff manage content and datasets directly, without needing developers. The platform is fully hosted and maintained by Datopian, requiring zero operational effort from the Ministry. It’s a scalable, secure, and API-first solution that delivers on both transparency and usability.", + "results": "The MOEI Open Data Portal now serves as a **trusted digital resource**, offering public access to clean, categorized, and searchable datasets. The platform simplifies data discovery, empowers developers through APIs, and enables non-technical staff to manage content effortlessly—while maintaining full security and performance at scale.", + "features": [ + { + "title": "Zero maintenance burden for the MOEI team", + "text": "", + "icon": "database" + }, + { + "title": "Managed hosting with ongoing updates and security patches", + "text": "", + "icon": "menu" + }, + { + "title": "Scalable infrastructure, compatible with Azure", + "text": "", + "icon": "expand" + }, + { + "title": "Rapid delivery and branding alignment out of the box", + "text": "", + "icon": "verified" + } + ], + "quote": [ + "The platform gives us exactly what we needed—bilingual access, strong data infrastructure, and zero maintenance on our end. It’s been a reliable tool for sharing our datasets with the public.", + "/static/img/social-proof/uae-logo.webp", + "MOEI" + ], + "highlight": "- **CKAN** provides a battle-tested backend for structured data, metadata management, and API endpoints.\n- **PortalJS** adds a powerful, modern frontend with a React-based UI, multilingual layout support, and customizable design.\n- **The result**: a flexible, performant data portal that non-technical teams can manage and the public can trust.", + "portal": [ + "The MOEI Open Data Portal", + "MOEI unveils a cutting-edge open data portal, developed with Datopian using PortalJS and CKAN, to empower citizens, researchers, and developers with seamless access to bilingual, structured, and actionable government data.", + "https://opendata.moei.gov.ae" + ], + "table": "moei", + "fullCaseStudy": "https://www.datopian.com/showcase/case-studies/making-government-data-usable-moei-ckan-open-data-portal", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://opendata.moei.gov.ae", + "toRaw": "https://opendata.moei.gov.ae", + "text": "https://opendata.moei.gov.ae", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://www.datopian.com/showcase/case-studies/making-government-data-usable-moei-ckan-open-data-portal", + "toRaw": "https://www.datopian.com/showcase/case-studies/making-government-data-usable-moei-ckan-open-data-portal", + "text": "https://www.datopian.com/showcase/case-studies/making-government-data-usable-moei-ckan-open-data-portal", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://www.moei.gov.ae/", + "toRaw": "https://www.moei.gov.ae/", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://u.ae/en/about-the-uae/strategies-initiatives-and-awards/strategies-plans-and-visions/innovation-and-future-shaping/uae-centennial-2071", + "toRaw": "https://u.ae/en/about-the-uae/strategies-initiatives-and-awards/strategies-plans-and-visions/innovation-and-future-shaping/uae-centennial-2071", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://www.datopian.com/showcase/case-studies/revolutionizing-open-data-fcsc", + "toRaw": "https://www.datopian.com/showcase/case-studies/revolutionizing-open-data-fcsc", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://moei.gov.ae/", + "toRaw": "https://moei.gov.ae/", + "text": "main ministry website", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://www.datopian.com/solutions/ckan", + "toRaw": "https://www.datopian.com/solutions/ckan", + "text": "CKAN", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://portaljs.com", + "toRaw": "https://portaljs.com", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://portaljs.com", + "toRaw": "https://portaljs.com", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://portaljs.com", + "toRaw": "https://portaljs.com", + "text": "PortalJS", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "https://portaljs.com", + "toRaw": "https://portaljs.com", + "text": "here", + "embed": false, + "internal": false + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image3.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image3.webp", + "text": "Ministry Website", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image1.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image1.webp", + "text": "Open Data Portal", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image6.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image6.webp", + "text": "Open Data Portal", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image10.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image10.webp", + "text": "Ghost CMS Dashboard", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image5.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image5.webp", + "text": "English Homepage", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image4.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image4.webp", + "text": "Arabic Homepage", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image7.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image7.webp", + "text": "Dataset page with feedback button", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image2.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image2.webp", + "text": "Chart builder", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image8.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image8.webp", + "text": "Developer experience component", + "embed": true, + "internal": true + }, + { + "from": "case-studies/uae-moei-scalable-platform-government-data-publishing.md", + "to": "images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image9.webp", + "toRaw": "/images/casestudies/2025-03-11-making-government-data-usable-moei-ckan-open-data-portal/image9.webp", + "text": "Explore similar datasets component", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "574ea1b190fd1b4c6c51ab87ece0642c55760745", + "file_path": "content/opensource/developers/automating-ckan-resource-cloudflare-r2-workers.md", + "extension": "md", + "url_path": "opensource/developers/automating-ckan-resource-cloudflare-r2-workers", + "filetype": null, + "metadata": { + "metatitle": "How to automate CKAN resource creation with Cloudflare Workers", + "metadescription": "How to set up and integrate Cloudflare Workers, Queues, and Notifications to automate the linking of uploaded resources in CKAN.", + "title": "Automating CKAN Resource Uploads with Cloudflare R2, Queues, and Workers", + "description": "How to set up and integrate Cloudflare Workers, Queues, and Notifications to automate the linking of uploaded resources in CKAN.", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "3d612ca76b6b8fb3ba8d32a4f90dc66879ce6a34", + "file_path": "content/opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "extension": "md", + "url_path": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan", + "filetype": null, + "metadata": { + "title": "A Comprehensive Guide to Building a Robust Data Portal using CKAN", + "metatitle": "Build a data portal with CKAN", + "description": "The PortalJS CKAN example intends to provide users with an easy way to bootstrap a data catalog and share data stories backed by a CKAN back end. The configuration is simple, being a matter of simply setting up an environment variable, which determines from which CKAN instance the data is going to be pulled.", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fdatahub%2Ftree%2Fmain%2Fexamples%2Fckan&env=DMS&envDescription=URL%20For%20the%20CKAN%20Backend%20Ex%3A%20https%3A%2F%2Fdemo.dev.datopian.com", + "toRaw": "https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fdatahub%2Ftree%2Fmain%2Fexamples%2Fckan&env=DMS&envDescription=URL%20For%20the%20CKAN%20Backend%20Ex%3A%20https%3A%2F%2Fdemo.dev.datopian.com", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "https://mdxjs.com/docs/what-is-mdx/", + "toRaw": "https://mdxjs.com/docs/what-is-mdx/", + "text": "MDX syntax", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "https://storybook.portaljs.org/", + "toRaw": "https://storybook.portaljs.org/", + "text": "PortalJS components library", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "https://storybook.portaljs.org/", + "toRaw": "https://storybook.portaljs.org/", + "text": "components", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "https://github.com/datopian/datahub/tree/main/examples/ckan", + "toRaw": "https://github.com/datopian/datahub/tree/main/examples/ckan", + "text": "Repo", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "http://ckan.portaljs.org/", + "toRaw": "http://ckan.portaljs.org/", + "text": "Live Demo", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "static/img/docs/dataapp-search.webp", + "toRaw": "/static/img/docs/dataapp-search.webp", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "static/img/docs/dataapp-dataset.webp", + "toRaw": "/static/img/docs/dataapp-dataset.webp", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "opensource/developers/https:/vercel.com/button", + "toRaw": "https://vercel.com/button", + "text": "Deploy with Vercel", + "embed": true, + "internal": false + }, + { + "from": "opensource/developers/comprehensive-guide-building-robust-data-portal-ckan.md", + "to": "static/img/docs/dataapp-test.webp", + "toRaw": "/static/img/docs/dataapp-test.webp", + "text": "Test", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "f441a8b581daf0e9bf8009fb5612aa38d7b8ff64", + "file_path": "content/opensource/developers/create-data-catalog-portaljs-ckan.md", + "extension": "md", + "url_path": "opensource/developers/create-data-catalog-portaljs-ckan", + "filetype": null, + "metadata": { + "title": "Create a data catalog with PortalJS and CKAN", + "metatitle": "Create a data catalog with PortalJS and CKAN to share your data stories", + "description": "The ckan-example added to PortalJS is intended to provide users with an easy way to set up a data catalog that can be used to display and share data stores behind a CKAN Backend. With this example, users can quickly set up a web-based portal that allows them to showcase their data and make it accessible to others, all this being done just by adding a simple env variable pointing to a CKAN Deployment.", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "https://ckan-example.portaljs.org", + "toRaw": "https://ckan-example.portaljs.org", + "text": "live deployment", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fdatahub%2Ftree%2Fmain%2Fexamples%2Fckan-example&env=DMS&envDescription=URL%20For%20the%20CKAN%20Backend%20Ex%3A%20https%3A%2F%2Fdemo.dev.datopian.com", + "toRaw": "https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fdatahub%2Ftree%2Fmain%2Fexamples%2Fckan-example&env=DMS&envDescription=URL%20For%20the%20CKAN%20Backend%20Ex%3A%20https%3A%2F%2Fdemo.dev.datopian.com", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "https://github.com/datopian/datahub/tree/main/examples/ckan-example", + "toRaw": "https://github.com/datopian/datahub/tree/main/examples/ckan-example", + "text": "Repo", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "https://ckan-example.portaljs.org", + "toRaw": "https://ckan-example.portaljs.org", + "text": "Live Demo", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "opensource/developers/https:/i.imgur.com/NlTAIAg.png", + "toRaw": "https://i.imgur.com/NlTAIAg.png", + "text": "", + "embed": true, + "internal": false + }, + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "opensource/developers/https:/i.imgur.com/RRoIlGf.png", + "toRaw": "https://i.imgur.com/RRoIlGf.png", + "text": "", + "embed": true, + "internal": false + }, + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "opensource/developers/https:/media.discordapp.net/attachments/1069718983604977754/1098252297726865408/image.png?width=853&height=461", + "toRaw": "https://media.discordapp.net/attachments/1069718983604977754/1098252297726865408/image.png?width=853&height=461", + "text": "", + "embed": true, + "internal": false + }, + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "opensource/developers/https:/media.discordapp.net/attachments/1069718983604977754/1098252298074988595/image.png?width=853&height=461", + "toRaw": "https://media.discordapp.net/attachments/1069718983604977754/1098252298074988595/image.png?width=853&height=461", + "text": "", + "embed": true, + "internal": false + }, + { + "from": "opensource/developers/create-data-catalog-portaljs-ckan.md", + "to": "opensource/developers/https:/vercel.com/button", + "toRaw": "https://vercel.com/button", + "text": "Deploy with Vercel", + "embed": true, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "e5980e74f49c8a158c63e8de860e3c8b775c5bb4", + "file_path": "content/opensource/developers/create-github-backed-data-catalog-portaljs.md", + "extension": "md", + "url_path": "opensource/developers/create-github-backed-data-catalog-portaljs", + "filetype": null, + "metadata": { + "title": "Setup Guide: Create a data catalog to display and share your GitHub datasets with PortalJS", + "metatitle": "Create a data catalog with GitHub datasets", + "description": "The github-backed example added to PortalJS is intended to provide users with an easy way to set up a data catalog that can be used to display and share data stored in GitHub repositories. With this example, users can quickly set up a web-based portal that allows them to showcase their data and make it accessible to others, all this being done thru the configuration of a simple `datasets.json` file.", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "https://example.portaljs.org", + "toRaw": "https://example.portaljs.org", + "text": "live deployment", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token", + "toRaw": "https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token", + "text": "Personal Access Token", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "https://github.com/datasets", + "toRaw": "https://github.com/datasets", + "text": "repo", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "http://localhost:3000", + "toRaw": "http://localhost:3000", + "text": "http://localhost:3000", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fdatahub%2Ftree%2Fmain%2Fexamples%2Fgithub-backed-catalog", + "toRaw": "https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fdatahub%2Ftree%2Fmain%2Fexamples%2Fgithub-backed-catalog", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "opensource/developers/#setup-a-github-token", + "toRaw": "#setup-a-github-token", + "text": "previous section", + "embed": false, + "internal": true + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "opensource/developers/#how-to-use-this-example-as-a-template", + "toRaw": "#how-to-use-this-example-as-a-template", + "text": "\"How to use this example as a template\" section", + "embed": false, + "internal": true + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "https://github.com/datopian/datahub/tree/main/examples/github-backed-catalog", + "toRaw": "https://github.com/datopian/datahub/tree/main/examples/github-backed-catalog", + "text": "Repo", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "https://example.portaljs.org", + "toRaw": "https://example.portaljs.org", + "text": "Live Demo", + "embed": false, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "opensource/developers/https:/i.imgur.com/jAljJ9C.png", + "toRaw": "https://i.imgur.com/jAljJ9C.png", + "text": "", + "embed": true, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "opensource/developers/https:/i.imgur.com/AoJd4O0.png", + "toRaw": "https://i.imgur.com/AoJd4O0.png", + "text": "", + "embed": true, + "internal": false + }, + { + "from": "opensource/developers/create-github-backed-data-catalog-portaljs.md", + "to": "opensource/developers/https:/vercel.com/button", + "toRaw": "https://vercel.com/button", + "text": "Deploy with Vercel", + "embed": true, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "f5e4986c0f8c0a41d3475affe0fb32eda36bf79b", + "file_path": "content/opensource/developers/enabling-direct-file-uploads-api-ckan-cloudflare.md", + "extension": "md", + "url_path": "opensource/developers/enabling-direct-file-uploads-api-ckan-cloudflare", + "filetype": null, + "metadata": { + "metatitle": "How to enable direct file uploads to Cloudflare on CKAN", + "metadescription": "This setup allows users to upload resources directly via the API while seamlessly integrating with Cloudflare R2 storage.", + "title": "Enabling Direct File Uploads via API in CKAN with Cloudflare R2", + "description": "This setup allows users to upload resources directly via the API while seamlessly integrating with Cloudflare R2 storage. ", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "6246227dbe9ac62f63ff8dbff2a3b22e60f0b73f", + "file_path": "content/opensource/docs/creating-new-datasets.md", + "extension": "md", + "url_path": "opensource/docs/creating-new-datasets", + "filetype": null, + "metadata": { + "metatitle": "Creating new datasets", + "metadescription": "Learn how to create and manage datasets in PortalJS. Follow our documentation for step-by-step instructions.", + "title": "PortalJS - Creating new datasets", + "description": "Learn how to create new datasets and an index for all datasets on a data portal built with PortalJS", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/docs/creating-new-datasets.md", + "to": "http://localhost:3000/my-incredible-dataset", + "toRaw": "http://localhost:3000/my-incredible-dataset", + "text": "http://localhost:3000/my-incredible-dataset", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/creating-new-datasets.md", + "to": "http://localhost:3000", + "toRaw": "http://localhost:3000", + "text": "http://localhost:3000", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "49b2a088c99429dfe59cf64d205d4b2f1823502a", + "file_path": "content/opensource/docs/deploying-your-portaljs-app.md", + "extension": "md", + "url_path": "opensource/docs/deploying-your-portaljs-app", + "filetype": null, + "metadata": { + "metatitle": "Deploy Your PortalJS App", + "metadescription": "Learn how to deploy your PortalJS app seamlessly. Follow our step-by-step guide for deployment best practices.", + "title": "PortalJS - Deploying your PortalJS app", + "description": "Learn how to deploy PortalJS apps to Vercel and Cloudflare", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/docs/deploying-your-portaljs-app.md", + "to": "https://nextjs.org/learn/basics/deploying-nextjs-app/github", + "toRaw": "https://nextjs.org/learn/basics/deploying-nextjs-app/github", + "text": "https://nextjs.org/learn/basics/deploying-nextjs-app/github", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/deploying-your-portaljs-app.md", + "to": "opensource/docs/#one-click-deploy", + "toRaw": "#one-click-deploy", + "text": "Click here", + "embed": false, + "internal": true + }, + { + "from": "opensource/docs/deploying-your-portaljs-app.md", + "to": "https://vercel.com/signup", + "toRaw": "https://vercel.com/signup", + "text": "https://vercel.com/signup", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/deploying-your-portaljs-app.md", + "to": "https://vercel.com/new", + "toRaw": "https://vercel.com/new", + "text": "https://vercel.com/new", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/deploying-your-portaljs-app.md", + "to": "https://nextjs.org/learn/basics/deploying-nextjs-app/deploy", + "toRaw": "https://nextjs.org/learn/basics/deploying-nextjs-app/deploy", + "text": "https://nextjs.org/learn/basics/deploying-nextjs-app/deploy", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/deploying-your-portaljs-app.md", + "to": "https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fportaljs%2Ftree%2Fmain%2Fexamples%2Flearn-example&project-name=my-data-portal&repository-name=my-data-portal&demo-title=PortalJS%20Learn%20Example&demo-description=PortalJS%20Learn%20Example%20-%20https%3A%2F%2Fportaljs.org%2Fdocs&demo-url=learn-example.portaljs.org&demo-image=https%3A%2F%2Fportaljs.org%2Fassets%2Fexamples%2Fbasic-example.png", + "toRaw": "https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatopian%2Fportaljs%2Ftree%2Fmain%2Fexamples%2Flearn-example&project-name=my-data-portal&repository-name=my-data-portal&demo-title=PortalJS%20Learn%20Example&demo-description=PortalJS%20Learn%20Example%20-%20https%3A%2F%2Fportaljs.org%2Fdocs&demo-url=learn-example.portaljs.org&demo-image=https%3A%2F%2Fportaljs.org%2Fassets%2Fexamples%2Fbasic-example.png", + "text": "", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/deploying-your-portaljs-app.md", + "to": "https://developers.cloudflare.com/pages/framework-guides/deploy-a-nextjs-site/#deploy-with-cloudflare-pages-1", + "toRaw": "https://developers.cloudflare.com/pages/framework-guides/deploy-a-nextjs-site/#deploy-with-cloudflare-pages-1", + "text": "https://developers.cloudflare.com/pages/framework-guides/deploy-a-nextjs-site/#deploy-with-cloudflare-pages-1", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/deploying-your-portaljs-app.md", + "to": "opensource/docs/https:/vercel.com/button", + "toRaw": "https://vercel.com/button", + "text": "Deploy with Vercel", + "embed": true, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "d4e2b1c66b3c158cdb724b5c98fcd5b29f92999f", + "file_path": "content/opensource/docs/index.md", + "extension": "md", + "url_path": "opensource/docs", + "filetype": null, + "metadata": { + "title": "PortalJS Open Source Framework – Rapidly Build Rich Data Portals", + "description": "PortalJS is a JavaScript framework for rapidly building rich data portal frontends using a modern frontend approach.", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [], + "tasks": [] + }, + { + "_id": "0f36634349ccd45a541ed9e0500e500ab9156aa9", + "file_path": "content/opensource/docs/searching-datasets.md", + "extension": "md", + "url_path": "opensource/docs/searching-datasets", + "filetype": null, + "metadata": { + "metatitle": "Searching Datasets", + "metadescription": "Optimize your data portal with advanced search features. Learn how to enable and customize dataset search with PortalJS.", + "title": "PortalJS - Searching datasets", + "description": "Learn how to create a searchable datasets index with facets on a PortalJs data portal", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/docs/searching-datasets.md", + "to": "https://github.com/datopian/markdowndb", + "toRaw": "https://github.com/datopian/markdowndb", + "text": "markdowndb", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/searching-datasets.md", + "to": "http://localhost:3000", + "toRaw": "http://localhost:3000", + "text": "http://localhost:3000", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/searching-datasets.md", + "to": "https://daily-dev-tips.com/posts/what-exactly-is-frontmatter/", + "toRaw": "https://daily-dev-tips.com/posts/what-exactly-is-frontmatter/", + "text": "frontmatter field", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/searching-datasets.md", + "to": "http://localhost:3000", + "toRaw": "http://localhost:3000", + "text": "http://localhost:3000", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/searching-datasets.md", + "to": "opensource/docs/https:/i.imgur.com/9HfSPIx.png", + "toRaw": "https://i.imgur.com/9HfSPIx.png", + "text": "Simple data catalog built with PortalJS", + "embed": true, + "internal": false + }, + { + "from": "opensource/docs/searching-datasets.md", + "to": "opensource/docs/https:/i.imgur.com/nvmSnJ5.png", + "toRaw": "https://i.imgur.com/nvmSnJ5.png", + "text": "Example of a newly added dataset on a data catalog built with PortalJS", + "embed": true, + "internal": false + }, + { + "from": "opensource/docs/searching-datasets.md", + "to": "opensource/docs/https:/i.imgur.com/p2miSdg.png", + "toRaw": "https://i.imgur.com/p2miSdg.png", + "text": "Data catalog with facets built with PortalJS", + "embed": true, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "ed47088902d5f2570be0d4993007290b9456d490", + "file_path": "content/opensource/docs/setup.md", + "extension": "md", + "url_path": "opensource/docs/setup", + "filetype": null, + "metadata": { + "metatitle": "Setup", + "metadescription": "Follow our setup guide to get started with PortalJS. Learn how to install, configure, and launch your data portal in minutes.", + "title": "PortalJS Setup – Quick Start Guide for Developers", + "description": "Getting started guide and tutorial about data portal-building with PortalJS!", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/docs/setup.md", + "to": "https://github.com/datopian/datahub/discussions", + "toRaw": "https://github.com/datopian/datahub/discussions", + "text": "GitHub Discussions", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/setup.md", + "to": "https://discord.gg/krmj5HM6He", + "toRaw": "https://discord.gg/krmj5HM6He", + "text": "our chat channel on Discord", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/setup.md", + "to": "http://localhost:3000", + "toRaw": "http://localhost:3000", + "text": "http://localhost:3000", + "embed": false, + "internal": false + }, + { + "from": "opensource/docs/setup.md", + "to": "http://localhost:3000", + "toRaw": "http://localhost:3000", + "text": "http://localhost:3000", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "7897225656ca96f7ed69b8aacf9f5b818a771b86", + "file_path": "content/opensource/docs/showing-metadata.md", + "extension": "md", + "url_path": "opensource/docs/showing-metadata", + "filetype": null, + "metadata": { + "metatitle": "Showing Metadata", + "metadesciption": "Display dataset metadata effectively with PortalJS. Access our documentation to implement and customize metadata views.", + "title": "PortalJS - Showing metadata", + "description": "Learn how to display metadata on the dataset page of a data portal built with PortalJS", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/docs/showing-metadata.md", + "to": "opensource/docs/https:/i.imgur.com/O145uuc.png", + "toRaw": "https://i.imgur.com/O145uuc.png", + "text": "Example of a page displaying the title metadata twice", + "embed": true, + "internal": false + }, + { + "from": "opensource/docs/showing-metadata.md", + "to": "opensource/docs/https:/i.imgur.com/nvDYJQT.png", + "toRaw": "https://i.imgur.com/nvDYJQT.png", + "text": "Example of a dataset page displaying metadata", + "embed": true, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "f684b742c48bcdf12b5e7825b8dc14cdb022ee70", + "file_path": "content/opensource/guide/index.md", + "extension": "md", + "url_path": "opensource/guide", + "filetype": null, + "metadata": { + "title": "Dataset Management in PortalJS Cloud", + "description": "Learn how to use PortalJS Cloud via Admin panel or API", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/guide/index.md", + "to": "static/img/docs/portaljs-login.webp", + "toRaw": "/static/img/docs/portaljs-login.webp", + "text": "PortalJS Cloud Login", + "embed": true, + "internal": true + }, + { + "from": "opensource/guide/index.md", + "to": "static/img/docs/portaljs-add-dataset.webp", + "toRaw": "/static/img/docs/portaljs-add-dataset.webp", + "text": "Add Dataset", + "embed": true, + "internal": true + }, + { + "from": "opensource/guide/index.md", + "to": "static/img/docs/portaljs-create-resource.webp", + "toRaw": "/static/img/docs/portaljs-create-resource.webp", + "text": "Upload Resource", + "embed": true, + "internal": true + }, + { + "from": "opensource/guide/index.md", + "to": "static/img/docs/portaljs-dataset-metadata.webp", + "toRaw": "/static/img/docs/portaljs-dataset-metadata.webp", + "text": "Dataset Metadata", + "embed": true, + "internal": true + }, + { + "from": "opensource/guide/index.md", + "to": "static/img/docs/portaljs-ai-metadata.webp", + "toRaw": "/static/img/docs/portaljs-ai-metadata.webp", + "text": "AI Metadata", + "embed": true, + "internal": true + }, + { + "from": "opensource/guide/index.md", + "to": "static/img/docs/portaljs-dashboard.webp", + "toRaw": "/static/img/docs/portaljs-dashboard.webp", + "text": "PortalJS Cloud Dashboard", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "63de3f49d2eb83bc98f7008258e452837fde432b", + "file_path": "content/opensource/howtos/analytics.md", + "extension": "md", + "url_path": "opensource/howtos/analytics", + "filetype": null, + "metadata": { + "metatitle": "Add Web Analytics", + "metadescription": "Learn how to integrate web analytics into your PortalJS data portal. Follow our step-by-step guide to track user behavior.", + "title": "How to add Google Analytics?", + "description": "Learn how to implement Google Analytics on PortalJS data portals", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/howtos/analytics.md", + "to": "https://support.google.com/analytics/answer/9304153?hl=en", + "toRaw": "https://support.google.com/analytics/answer/9304153?hl=en", + "text": "Google Analytics account", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/analytics.md", + "to": "https://support.google.com/analytics/answer/12270356?hl=en#:~:text=A%20Measurement%20ID%20is%20an,same%20as%20your%20destination%20ID.", + "toRaw": "https://support.google.com/analytics/answer/12270356?hl=en#:~:text=A%20Measurement%20ID%20is%20an,same%20as%20your%20destination%20ID.", + "text": "Google tag ID", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/analytics.md", + "to": "https://developers.google.com/analytics", + "toRaw": "https://developers.google.com/analytics", + "text": "Google Analytics documentation", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "6ea48110b97ad81b25ebd231ab0de71442c60f67", + "file_path": "content/opensource/howtos/blog.md", + "extension": "md", + "url_path": "opensource/howtos/blog", + "filetype": null, + "metadata": { + "metatitle": "Add a Blog to Your Portal", + "metadescription": "Create a simple blog in your PortalJS data portal. Follow our tutorial to set up a blog quickly and easily.", + "title": "How to add a simple blog?", + "description": "Learn how to add a simple blog on a PortalJS data portal", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/howtos/blog.md", + "to": "https://www.npmjs.com/package/@portaljs/core", + "toRaw": "https://www.npmjs.com/package/@portaljs/core", + "text": "@portaljs/core", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "c8b88be536cf7fc72e4619bfc3b2d0c5da43d58b", + "file_path": "content/opensource/howtos/comments.md", + "extension": "md", + "url_path": "opensource/howtos/comments", + "filetype": null, + "metadata": { + "metatitle": "Add User Comments", + "metadescription": "Enable user comments on your data portal. Follow our tutorial to integrate comments and boost user engagement.", + "title": "How to add user comments?", + "description": "Learn how to add user comments on a PortalJS data portal", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/howtos/comments.md", + "to": "https://giscus.app/", + "toRaw": "https://giscus.app/", + "text": "giscus", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://utteranc.es/", + "toRaw": "https://utteranc.es/", + "text": "utterances", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://disqus.com/", + "toRaw": "https://disqus.com/", + "text": "disqus", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://giscus.app/", + "toRaw": "https://giscus.app/", + "text": "Giscus", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://docs.github.com/en/get-started/quickstart/create-a-repo", + "toRaw": "https://docs.github.com/en/get-started/quickstart/create-a-repo", + "text": "github repository", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/enabling-or-disabling-github-discussions-for-a-repository", + "toRaw": "https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/enabling-or-disabling-github-discussions-for-a-repository", + "text": "discussions", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://github.com/apps/giscus", + "toRaw": "https://github.com/apps/giscus", + "text": "giscus app", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://giscus.app/", + "toRaw": "https://giscus.app/", + "text": "https://giscus.app/", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://giscus.app/", + "toRaw": "https://giscus.app/", + "text": "https://giscus.app", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://github.com/giscus/giscus#how-it-works", + "toRaw": "https://github.com/giscus/giscus#how-it-works", + "text": "https://github.com/giscus/giscus#how-it-works", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://giscus.app/", + "toRaw": "https://giscus.app/", + "text": "https://giscus.app/", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://utteranc.es/", + "toRaw": "https://utteranc.es/", + "text": "Utterances", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://docs.github.com/en/get-started/quickstart/create-a-repo", + "toRaw": "https://docs.github.com/en/get-started/quickstart/create-a-repo", + "text": "github repository", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://utteranc.es/", + "toRaw": "https://utteranc.es/", + "text": "https://utteranc.es/", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://disqus.com/", + "toRaw": "https://disqus.com/", + "text": "Disqus", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/comments.md", + "to": "https://disqus.com/", + "toRaw": "https://disqus.com/", + "text": "Disqus", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "d11366ed7b4aea8bec6469f425c450ad4d8c09c4", + "file_path": "content/opensource/howtos/data-rich-documents.md", + "extension": "md", + "url_path": "opensource/howtos/data-rich-documents", + "filetype": null, + "metadata": { + "metatitle": "Create Data-Rich Documents", + "metadescription": "Add data-rich documents with charts and tables to your portal. Learn how to enhance content presentation with PortalJS.", + "title": "How to create data-rich documents with charts and tables?", + "description": "Learn how to create a data-rich document with charts and tables on a PortalJS data portal", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "https://storybook.portaljs.org/", + "toRaw": "https://storybook.portaljs.org/", + "text": "Storybook", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "https://storybook.portaljs.org/?path=/docs/components-table--docs", + "toRaw": "https://storybook.portaljs.org/?path=/docs/components-table--docs", + "text": "storybook page", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "https://storybook.portaljs.org/?path=/docs/components-linechart--docs", + "toRaw": "https://storybook.portaljs.org/?path=/docs/components-linechart--docs", + "text": "storybook page", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "https://vega.github.io/vega/", + "toRaw": "https://vega.github.io/vega/", + "text": "Vega specification", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "https://storybook.portaljs.org/?path=/docs/components-vega--docs", + "toRaw": "https://storybook.portaljs.org/?path=/docs/components-vega--docs", + "text": "storybook page", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "https://vega.github.io/vega-lite/", + "toRaw": "https://vega.github.io/vega-lite/", + "text": "Vega Lite specification", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "https://storybook.portaljs.org/?path=/docs/components-vegalite--docs", + "toRaw": "https://storybook.portaljs.org/?path=/docs/components-vegalite--docs", + "text": "storybook page", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "https://storybook.portaljs.org/?path=/docs/components-catalog--docs", + "toRaw": "https://storybook.portaljs.org/?path=/docs/components-catalog--docs", + "text": "storybook page", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "opensource/howtos/https:/hackmd.io/_uploads/ryN5mYmSh.png", + "toRaw": "https://hackmd.io/_uploads/ryN5mYmSh.png", + "text": "simple chat built with vega", + "embed": true, + "internal": false + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "opensource/howtos/markdown", + "toRaw": "markdown", + "text": "", + "embed": false, + "internal": true + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "opensource/howtos/markdown#import,-parse-and-render-your-markdown-files", + "toRaw": "markdown#import,-parse-and-render-your-markdown-files", + "text": "", + "embed": false, + "internal": true + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "opensource/howtos/table-example.png", + "toRaw": "table-example.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "opensource/howtos/linechart-example.png", + "toRaw": "linechart-example.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "opensource/howtos/catalog-example.png", + "toRaw": "catalog-example.png", + "text": "", + "embed": true, + "internal": true + }, + { + "from": "opensource/howtos/data-rich-documents.md", + "to": "opensource/howtos/catalog-facets-example.png", + "toRaw": "catalog-facets-example.png", + "text": "", + "embed": true, + "internal": true + } + ], + "tasks": [] + }, + { + "_id": "6f6dcea379d61738060db851812e134ca3175839", + "file_path": "content/opensource/howtos/markdown.md", + "extension": "md", + "url_path": "opensource/howtos/markdown", + "filetype": null, + "metadata": { + "metatitle": "Markdown Pages – PortalJS Tutorial", + "metadescription": "Add and manage markdown-based content pages in PortalJS. Learn how to extend your data portal with rich content.", + "title": "How to add markdown-based content pages?", + "description": "Learn how to add markdown-based content pages on PortalJS data portals", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/howtos/markdown.md", + "to": "https://github.com/datopian/markdowndb", + "toRaw": "https://github.com/datopian/markdowndb", + "text": "MarkdownDB", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/markdown.md", + "to": "https://github.com/hashicorp/next-mdx-remote", + "toRaw": "https://github.com/hashicorp/next-mdx-remote", + "text": "next-mdx-remote", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "dd07bccc1d7c6141ce64417652ad0e631abca56f", + "file_path": "content/opensource/howtos/seo.md", + "extension": "md", + "url_path": "opensource/howtos/seo", + "filetype": null, + "metadata": { + "metatitle": "SEO Metadata – Optimize PortalJS Pages", + "metadescription": "Improve your data portal's SEO by customizing page metadata. Follow our guide to boost search engine rankings.", + "title": "How to customize page metadata for SEO?", + "description": "Learn how to customize page metadata for SEO on data portals built with PortalJS", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/howtos/seo.md", + "to": "https://github.com/garmeeh/next-seo", + "toRaw": "https://github.com/garmeeh/next-seo", + "text": "next-seo", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/seo.md", + "to": "https://github.com/garmeeh/next-seo#default-seo-configuration", + "toRaw": "https://github.com/garmeeh/next-seo#default-seo-configuration", + "text": "this docs section", + "embed": false, + "internal": false + }, + { + "from": "opensource/howtos/seo.md", + "to": "https://github.com/garmeeh/next-seo#add-seo-to-page", + "toRaw": "https://github.com/garmeeh/next-seo#add-seo-to-page", + "text": "this docs section", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "8d839174d35dd7edf8df120f7e3b0f2c96f47c54", + "file_path": "content/opensource/howtos/sitemap.md", + "extension": "md", + "url_path": "opensource/howtos/sitemap", + "filetype": null, + "metadata": { + "metatitle": "Build a Sitemap", + "metadescription": "Learn how to create and submit a sitemap for your PortalJS data portal. Enhance your site's SEO with our easy-to-follow guide.", + "title": "How to build a sitemap?", + "description": "Learn how to build a sitemap for a data portal built with PortalJS", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "opensource/howtos/sitemap.md", + "to": "https://github.com/datopian/markdowndb", + "toRaw": "https://github.com/datopian/markdowndb", + "text": "MarkdownDB", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "4f1a775792665b69e8a060bfad6c8bd8f4ab1374", + "file_path": "content/people/anuveyatsu.md", + "extension": "md", + "url_path": "people/anuveyatsu", + "filetype": null, + "metadata": { + "id": "anuveyatsu", + "name": "Anuar Ustayev", + "avatar": "https://avatars.githubusercontent.com/anuveyatsu", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/anuveyatsu.md", + "to": "https://avatars.githubusercontent.com/anuveyatsu", + "toRaw": "https://avatars.githubusercontent.com/anuveyatsu", + "text": "https://avatars.githubusercontent.com/anuveyatsu", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "14c3d58a270408e079b76b689324d95f537cdb1c", + "file_path": "content/people/baglanadaskhan.md", + "extension": "md", + "url_path": "people/baglanadaskhan", + "filetype": null, + "metadata": { + "id": "baglanadaskhan", + "name": "Baglan Adaskhan", + "avatar": "https://avatars.githubusercontent.com/baglanadaskhan", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/baglanadaskhan.md", + "to": "https://avatars.githubusercontent.com/baglanadaskhan", + "toRaw": "https://avatars.githubusercontent.com/baglanadaskhan", + "text": "https://avatars.githubusercontent.com/baglanadaskhan", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "e84ef37b78b82f6dc192392a160a5f471a4126c7", + "file_path": "content/people/joao-demenech.md", + "extension": "md", + "url_path": "people/joao-demenech", + "filetype": null, + "metadata": { + "id": "joaodemenech", + "name": "João Demenech", + "avatar": "https://avatars.githubusercontent.com/demenech", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/joao-demenech.md", + "to": "https://avatars.githubusercontent.com/demenech", + "toRaw": "https://avatars.githubusercontent.com/demenech", + "text": "https://avatars.githubusercontent.com/demenech", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "2ba6dc494a861c5f9d20fd95320fed3f3a046f6d", + "file_path": "content/people/lucasbispo.md", + "extension": "md", + "url_path": "people/lucasbispo", + "filetype": null, + "metadata": { + "id": "lucasbispo", + "name": "Lucas Bispo", + "avatar": "https://avatars.githubusercontent.com/lucasmbispo", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/lucasbispo.md", + "to": "https://avatars.githubusercontent.com/lucasmbispo", + "toRaw": "https://avatars.githubusercontent.com/lucasmbispo", + "text": "https://avatars.githubusercontent.com/lucasmbispo", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "310cf3deb189d0b52f09ade95cc20e6727c09885", + "file_path": "content/people/luccas-mateus.md", + "extension": "md", + "url_path": "people/luccas-mateus", + "filetype": null, + "metadata": { + "id": "luccasmateus", + "name": "Luccas Mateus", + "avatar": "https://avatars.githubusercontent.com/luccasmmg", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/luccas-mateus.md", + "to": "https://avatars.githubusercontent.com/luccasmmg", + "toRaw": "https://avatars.githubusercontent.com/luccasmmg", + "text": "https://avatars.githubusercontent.com/luccasmmg", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "c3f405f4c9a35b16b3c865954056abdfefd44d53", + "file_path": "content/people/mikanebu.md", + "extension": "md", + "url_path": "people/mikanebu", + "filetype": null, + "metadata": { + "id": "mikanebu", + "name": "Meiran Zhiyenbayev", + "avatar": "https://avatars.githubusercontent.com/mikanebu", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/mikanebu.md", + "to": "https://avatars.githubusercontent.com/mikanebu", + "toRaw": "https://avatars.githubusercontent.com/mikanebu", + "text": "https://avatars.githubusercontent.com/mikanebu", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "08d84204504116087fd19e3753166712d1891c70", + "file_path": "content/people/ola-rubaj.md", + "extension": "md", + "url_path": "people/ola-rubaj", + "filetype": null, + "metadata": { + "id": "ola-rubaj", + "name": "Ola Rubaj", + "avatar": "https://avatars.githubusercontent.com/olayway", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/ola-rubaj.md", + "to": "https://avatars.githubusercontent.com/olayway", + "toRaw": "https://avatars.githubusercontent.com/olayway", + "text": "https://avatars.githubusercontent.com/olayway", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "1a1f78b8324c5ace4cd2391f301560c203c1b40c", + "file_path": "content/people/popovayoana.md", + "extension": "md", + "url_path": "people/popovayoana", + "filetype": null, + "metadata": { + "id": "popovayoana", + "name": "Yoana Popova", + "avatar": "https://avatars.githubusercontent.com/popovayoana", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/popovayoana.md", + "to": "https://avatars.githubusercontent.com/popovayoana", + "toRaw": "https://avatars.githubusercontent.com/popovayoana", + "text": "https://avatars.githubusercontent.com/popovayoana", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "370ac530734c5c564500ae46a0204b89548b3a4b", + "file_path": "content/people/rufus-pollock.md", + "extension": "md", + "url_path": "people/rufus-pollock", + "filetype": null, + "metadata": { + "id": "rufuspollock", + "name": "Rufus Pollock", + "avatar": "https://avatars.githubusercontent.com/rufuspollock", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/rufus-pollock.md", + "to": "https://avatars.githubusercontent.com/rufuspollock", + "toRaw": "https://avatars.githubusercontent.com/rufuspollock", + "text": "https://avatars.githubusercontent.com/rufuspollock", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "0bb5af4c2edcf6a5a1b8d89f6d4c47d42deced9f", + "file_path": "content/people/shreyas.md", + "extension": "md", + "url_path": "people/shreyas", + "filetype": null, + "metadata": { + "id": "shreyas", + "name": "Shreyas Munyiappa", + "avatar": "https://avatars.githubusercontent.com/Datopian-Shreyas", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/shreyas.md", + "to": "https://avatars.githubusercontent.com/Datopian-Shreyas", + "toRaw": "https://avatars.githubusercontent.com/Datopian-Shreyas", + "text": "https://avatars.githubusercontent.com/Datopian-Shreyas", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "74f3f867cc1ee620ad93593e09b9d0bef7c4be9d", + "file_path": "content/people/theo-bertol.md", + "extension": "md", + "url_path": "people/theo-bertol", + "filetype": null, + "metadata": { + "id": "theobertol", + "name": "Theo Bertol", + "avatar": "https://avatars.githubusercontent.com/abeelha", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/theo-bertol.md", + "to": "https://avatars.githubusercontent.com/abeelha", + "toRaw": "https://avatars.githubusercontent.com/abeelha", + "text": "https://avatars.githubusercontent.com/abeelha", + "embed": false, + "internal": false + } + ], + "tasks": [] + }, + { + "_id": "fa9b37224b662875ca3343c4e05e647d3ed4ccc0", + "file_path": "content/people/william-lima.md", + "extension": "md", + "url_path": "people/william-lima", + "filetype": null, + "metadata": { + "id": "williamlima", + "name": "William Lima", + "avatar": "https://avatars.githubusercontent.com/willy1989cv", + "tags": [], + "tasks": [] + }, + "tags": [], + "links": [ + { + "from": "people/william-lima.md", + "to": "https://avatars.githubusercontent.com/willy1989cv", + "toRaw": "https://avatars.githubusercontent.com/willy1989cv", + "text": "https://avatars.githubusercontent.com/willy1989cv", + "embed": false, + "internal": false + } + ], + "tasks": [] + } +] \ No newline at end of file diff --git a/site/content/case-studies/modernizing-lincolnshire-county-council39s-open-data-portal.md b/site/content/case-studies/modernizing-lincolnshire-county-council39s-open-data-portal.md new file mode 100644 index 000000000..dc358e3cd --- /dev/null +++ b/site/content/case-studies/modernizing-lincolnshire-county-council39s-open-data-portal.md @@ -0,0 +1,57 @@ +--- +filetype: 'casestudy' +created: 2026-03-03 +title: Modernizing Lincolnshire County Council / From Dedicated CKAN Instance to Managed PortalJS Cloud Service +description: 'Discover how Lincolnshire County Council transformed their data publishing approach, migrating from a dedicated CKAN instance to PortalJS Cloud. Reduced operational costs, simplified administration, and delivered a modern user experience without compromising their established catalogue.' +image: /images/casestudies/linconshire0.jpg +images: ['/images/casestudies/lincolnshire1.png', '/images/casestudies/lincolnshire2.png', '/images/casestudies/lincolnshire3.png', '/images/casestudies/lincolnshire4.png'] +authors: ['popovayoana'] +keystats: [ + 'Seamless/n catalogue migration', + 'Zero/n infrastructure overhead', + '100%/n Budget-friendly solution', +] +problem: " +Lincolnshire County Council had built a solid open data programme on CKAN, serving their community with 60+ datasets across essential public services. As a smaller authority, however, they found themselves managing infrastructure complexity that was better suited to larger organizations with dedicated technical teams. Their challenges centered around operational fit rather than technology limitations: + + +- **Infrastructure Management Overhead**: Running a dedicated instance required server administration and technical maintenance that consumed staff time. + +- **Admin Interface Complexity**: CKAN's powerful admin dashboard was designed for technical users, creating friction for council staff who needed to focus on data rather than platform management. + + +- **Limited Self-Service Capability**: Routine updates and content management required technical intervention, slowing down day-to-day operations. +" +solution: " +PortalJS Cloud delivered exactly what Lincolnshire needed: a managed service that eliminated infrastructure costs while providing a modern, customizable frontend. The migration preserved their entire CKAN catalogue while giving council staff direct control over day-to-day operations through an intuitive admin dashboard.. + +- **Complete Data Migration**: Every dataset, resource, organization, and metadata element transferred seamlessly from CKAN to PortalJS Cloud. + + +- **Modern, Branded Interface**: Fully customised frontend reflecting Lincolnshire County Council''s visual identity and accessibility requirements. + + +- **Staff Empowerment**: Admin workflows simplified so council staff can manage content, users, and configurations without technical support." +results: "Lincolnshire's open data portal is now both more cost-effective and easier to operate. The modern interface serves their community of residents, researchers, and developers through clean data discovery tools, while the simplified admin experience lets council staff focus on data quality rather than platform maintenance." +features: [ + { title: "Cost-Effective Managed Service", text: "Lincolnshire moved from managing their own infrastructure to a fully managed service model with PortalJS Cloud. This eliminated the need for server administration and technical maintenance, letting council staff focus on their data rather than the platform underneath it.", icon: "rocket" }, + { title: "Complete Catalogue Preservation", text: "The migration transferred all 60 published datasets, 10 topic categories, and 6 organizational structures without data loss. Download links, metadata relationships, and search functionality remained fully intact.", icon: "database" }, + { title: "Intuitive Self-Service Administration", text: "Council staff now manage datasets, users, and portal configuration through PortalJS Cloud's purpose-built dashboard—no need to navigate CKAN's complex admin interface or route requests through developers.", icon: "browser" }, + { title: "Modern User Experience", text: "Built on Next.js and Tailwind CSS, the new portal delivers faster performance, responsive design, and accessibility compliance that meets contemporary web standards.", icon: "verified" }, + { title: "Simplified Customization", text: "Frontend updates, branding changes, and feature additions can be implemented directly by the council team without specialist development resources.", icon: "paint-roller" }, +] +quote: [ + '"PortalJS Cloud allowed us to maintain our data publishing commitments while working within our budget constraints. The migration was seamless and the ongoing operational savings have been significant."', + '/images/casestudies/lincon.svg', + 'Lincolnshire County Council Representative', +] +portal: [ + 'Lincolnshire Open Data Portal', + 'As part of its digital transformation strategy, Lincolnshire County Council migrated to PortalJS Cloud with consulting and migration services by Datopian.', + 'https://data.lincolnshire.gov.uk', +] +table: default +longReadLink: 'https://www.datopian.com/showcase/case-studies/lincolnshire-county-council-portaljs-cloud-migration' +longReadTitle: 'How Lincolnshire County Council Modernised Its Open Data Portal with PortalJS Cloud' +longReadSummary: 'Read the complete breakdown of architecture, migration approach, and outcomes — from dedicated CKAN instance to fully managed PortalJS Cloud.' +--- diff --git a/site/layouts/casestudy.tsx b/site/layouts/casestudy.tsx index 7bab4c88c..fcff6f4f2 100644 --- a/site/layouts/casestudy.tsx +++ b/site/layouts/casestudy.tsx @@ -81,6 +81,9 @@ export default function CaseStudyLayout({ children, ...frontMatter }) { table, highlight, longRead = true, + longReadLink, + longReadTitle, + longReadSummary, fullCaseStudy = false, faqs } = frontMatter @@ -539,46 +542,77 @@ export default function CaseStudyLayout({ children, ...frontMatter }) {
- {longRead && !fullCaseStudy &&
- - {({ open }) => ( - <> - - {open ? ( -
-

LONG READ

-
-

Hide

- + {longRead && !fullCaseStudy && (longReadLink ? ( +
+
+
+

+ Full Case Study +

+

+ {longReadTitle || 'Read the full case study'} +

+ {longReadSummary && ( +

+ {longReadSummary} +

+ )} +
+ + Read the full story + + + + +
+
+ ) : ( +
+ + {({ open }) => ( + <> + + {open ? ( +
+

LONG READ

+
+

Hide

+ +
-
- ) : ( -
-

LONG READ

-
-

- Click to read the detailed case study{' '} - -

+ ) : ( +
+

LONG READ

+
+

+ Click to read the detailed case study{' '} + +

+
+ )} + + +
+ A Detailed Case Study for a Deep Dive
- )} - - -
- A Detailed Case Study for a Deep Dive -
-
- {' '} -
- {children} +
+ {' '} +
+ {children} +
-
- - - )} - -
} + + + )} + + + ))}
diff --git a/site/public/atom.xml b/site/public/atom.xml index ac455cb11..cd1efe815 100644 --- a/site/public/atom.xml +++ b/site/public/atom.xml @@ -5,13 +5,1013 @@ https://portaljs.com/ - 2025-07-08T00:00:00.000Z + 2026-01-22T00:00:00.000Z Datopian contact@datopian.com - Copyright 2025 Datopian + Copyright 2026 Datopian PortalJS + + Keep Your Portal Data Fresh: A Hands-On Guide to the PortalJS Cloud API + https://portaljs.com/blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api + + 2026-01-22T00:00:00.000Z + 2026-01-22T00:00:00.000Z + + João Demenech + + +Keeping data portals up to date is harder than it looks. Files change, metadata drifts, and manual uploads don’t scale once updates become frequent or automated. + +PortalJS Cloud solves this by exposing a powerful API that lets you manage datasets, resources, and data files programmatically. In this guide, we’ll walk through how to use the **PortalJS Cloud API** to automatically create datasets, upload data, and keep both data and metadata in sync—using real Python code. + +By the end, you’ll have all the pieces needed to build a repeatable, automated data publishing pipeline. + +## The Problem with Manual Data Updates + +Many portals start with a simple workflow: + +- Upload a CSV through the UI +- Update the description +- Repeat next week + +Over time, this approach breaks down: + +- Files are updated, but metadata isn’t +- Uploads become repetitive and error-prone +- Data refreshes depend on someone remembering to do them + +What we want instead is: + +- A fully automated flow +- Consistent dataset and resource metadata +- The ability to update data on a schedule + +That’s exactly what the PortalJS Cloud API enables. + +## Finding Your PortalJS Cloud API + +Every PortalJS Cloud portal comes with its **own API**. + +You can access your portal’s API documentation using the following pattern: + +``` +https://api.cloud.portaljs.com/{your-portal}/api/3/docs +``` + +For example, for the Datopian portal: + +``` +https://api.cloud.portaljs.com/@datopian/api/3/docs +``` + +![Interactive API docs](/static/img/blog/2026-01-22-keep-your-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api/api-docs.png) + +This interactive documentation lets you: + +- Explore all available endpoints +- See required parameters and response schemas +- Test requests directly from the browser + +> **Tip:** Bookmark this page—you’ll use it constantly when building and debugging integrations. + +## Authentication and API Keys + +### Public access (no API key) + +Without an API key, anyone can: + +- Read public datasets +- Access public resources and data files + +For example, a simple public read request: + +```python +import requests + +response = requests.get( + "https://api.cloud.portaljs.com/@datopian/api/3/action/package_search" +) + +result = response.json() +print(result) +``` + +### Authenticated access (API key required) + +To create or update data, you’ll need an API key. Authenticated actions include: + +- Creating datasets +- Creating resources +- Uploading or replacing data files +- Updating dataset and resource metadata + +#### Generating an API key + +To generate an API key: + +1. Log in to the [**PortalJS Cloud dashboard**](https://cloud.portaljs.com/auth/signin) +2. Navigate to [**your user profile**](https://cloud.portaljs.com/profile/api-keys) +3. Create a new API key + +Treat API keys like passwords and store them securely. + +![Interactive API docs](/static/img/blog/2026-01-22-keep-your-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api/api-token.png) + +### Using the API key in requests + +Include the API key in the `Authorization` header. + +#### Common Python setup + +We’ll use Python 3.10+ and the `requests` package. Set your portal slug and API key once and reuse them everywhere. + +```python +import requests + +PORTAL = "datopian" +API_KEY = "your-api-key" +API_BASE = f"https://api.cloud.portaljs.com/@{PORTAL}/api/3/action" + +headers = { + "Content-Type": "application/json", + "Authorization": API_KEY, +} +``` + +## Creating a Dataset via the API + +In PortalJS, a **dataset** is the top-level container for related data and resources. + +To create one programmatically, use the `package_create` endpoint. + +```python +response = requests.post( + f"{API_BASE}/package_create", + headers=headers, + json={ + "name": "automated-dataset", + "title": "Automated Dataset", + "notes": "This dataset is created and updated via the PortalJS Cloud API", + "owner_org": PORTAL, + }, +) + +result = response.json() +print(result) + +dataset_id = result["result"]["id"] +``` + +> The `owner_org` field should be set to the organization that owns the dataset. +> You can find the organization identifier in the PortalJS Cloud dashboard. + +--- + +## Creating a Resource for the Dataset + +A **resource** represents a specific data file (CSV, JSON, etc.) attached to a dataset. + +Create a resource using `resource_create`: + +```python +response = requests.post( + f"{API_BASE}/resource_create", + headers=headers, + json={ + "package_id": "automated-dataset", + "name": "latest-data", + "description": "Latest version of the dataset", + "format": "CSV", + }, +) + +result = response.json() +print(result) + +resource_id = result["result"]["id"] +``` + +Resources are typically created once and updated repeatedly. + +## Uploading Data Using Pre-Signed URLs + +PortalJS Cloud uses **pre-signed URLs** for uploads. This allows large files to be uploaded directly to storage without passing through the API server. + +The upload flow is: + +1. Request an upload URL +2. Upload the file using `PUT` +3. Finalize the upload so the resource metadata is updated + +### Step 1: Request an upload URL + +```python +upload_response = requests.post( + f"{API_BASE}/resource_upload", + headers=headers, + json={ + "id": resource_id, + "filename": "data.csv", + }, +) + +upload_result = upload_response.json() +upload_url = upload_result["result"]["presigned_url"] +print(upload_url) +``` + +### Step 2: Upload the file + +Create a minimal CSV file locally first, for example `data.csv`: + +```csv +id,name +1,Example row +``` + +Then upload the file: + +```python +with open("./data.csv", "rb") as file_handle: + requests.put(upload_url, data=file_handle) +``` + +### Step 3: Finalize the upload + +```python +requests.post( + f"{API_BASE}/resource_upload_finalize", + headers=headers, + json={ + "id": resource_id, + }, +) +``` + +At this point, the resource is updated and consumers will see the new data. + +## Updating Resource Data Automatically + +This same upload flow can be reused every time your data changes: +- Daily refreshes +- Weekly exports +- Data generated from upstream systems + +You do **not** need to create a new resource each time. Updating the existing resource ensures: +- Stable URLs +- Consistent metadata +- A clean dataset structure + +## Putting It All Together: End-to-End Automation + +A typical automation flow looks like this: + +**One-time** +- Create dataset +- Create resource + +**On every run** +- Generate or fetch new data +- Request upload URL +- Upload file +- Finalize the upload + +## Common Dataset and Resource Operations + +Here are a few additional calls you’ll use often once your pipeline is in place. + +### Search datasets + +```python +search_response = requests.get( + f"{API_BASE}/package_search", + params={"q": "climate", "rows": 5}, +) + +search_result = search_response.json() +print(search_result) +``` + +### Patch a dataset + +```python +dataset_patch_response = requests.post( + f"{API_BASE}/package_patch", + headers=headers, + json={ + "id": dataset_id, + "notes": "Updated description from automation.", + }, +) + +dataset_patch_result = dataset_patch_response.json() +print(dataset_patch_result) +``` + +### Delete a dataset + +```python +dataset_delete_response = requests.post( + f"{API_BASE}/package_delete", + headers=headers, + json={"id": dataset_id}, +) + +dataset_delete_result = dataset_delete_response.json() +print(dataset_delete_result) +``` + +### Patch a resource + +```python +resource_patch_response = requests.post( + f"{API_BASE}/resource_patch", + headers=headers, + json={ + "id": resource_id, + "description": "Updated resource description.", + }, +) + +resource_patch_result = resource_patch_response.json() +print(resource_patch_result) +``` + +### Delete a resource + +```python +resource_delete_response = requests.post( + f"{API_BASE}/resource_delete", + headers=headers, + json={"id": resource_id}, +) + +resource_delete_result = resource_delete_response.json() +print(resource_delete_result) +``` + +## Full End-to-End Script + +If you want a single copy-paste file with all the steps (create dataset, create resource, upload, finalize), use this: + +```python +import requests + +PORTAL = "datopian" +API_KEY = "your-api-key" +API_BASE = f"https://api.cloud.portaljs.com/@{PORTAL}/api/3/action" + +headers = { + "Content-Type": "application/json", + "Authorization": API_KEY, +} + +dataset_response = requests.post( + f"{API_BASE}/package_create", + headers=headers, + json={ + "name": "automated-dataset", + "title": "Automated Dataset", + "notes": "This dataset is created and updated via the PortalJS Cloud API", + "owner_org": PORTAL, + }, +) + +dataset_result = dataset_response.json() +dataset_id = dataset_result["result"]["id"] + +resource_response = requests.post( + f"{API_BASE}/resource_create", + headers=headers, + json={ + "package_id": dataset_id, + "name": "latest-data", + "description": "Latest version of the dataset", + "format": "CSV", + }, +) + +resource_result = resource_response.json() +resource_id = resource_result["result"]["id"] + +filename = "data.csv" +with open(filename, "w", encoding="utf-8") as file_handle: + file_handle.write("id,name\n1,Example row\n") + +upload_response = requests.post( + f"{API_BASE}/resource_upload", + headers=headers, + json={ + "id": resource_id, + "filename": filename, + }, +) + +upload_result = upload_response.json() +upload_url = upload_result["result"]["presigned_url"] + +with open(filename, "rb") as file_handle: + requests.put(upload_url, data=file_handle) + +requests.post( + f"{API_BASE}/resource_upload_finalize", + headers=headers, + json={ + "id": resource_id, + }, +) +``` + +## Conclusion and Next Steps + +Using the PortalJS Cloud API, you can move from manual uploads to a fully automated, reliable data publishing workflow. + +You’ve seen how to: + +- Discover your portal’s API +- Authenticate with API keys +- Create datasets and resources +- Upload and update data programmatically +- Search, update, and delete datasets and resources + +Explore your portal’s API documentation to go further and tailor automation to your data workflows. + + This guide walks through using the PortalJS Cloud API to programatically create datasets, add resources, upload and replace data files, and update metadata—showing how to build repeatable data update pipelines with code examples. + + + Turning OpenMetadata into a User-Friendly Data Portal with PortalJS + https://portaljs.com/blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs + + 2026-01-09T00:00:00.000Z + 2026-01-09T00:00:00.000Z + + João Demenech + + +OpenMetadata is a strong foundation for modern data governance. It excels at managing metadata, lineage, ownership, and data quality, and it is clearly designed for data engineers, platform teams, and governance practitioners. + +Its user interface reflects that focus. Concepts such as database services, schemas, and assets are exposed directly, assuming users understand how data infrastructure works. This is effective for power users, but it creates friction when OpenMetadata is used by a broader audience. + +Many organizations want researchers, analysts, partners, or other non-technical users to explore their data. For them, how data is stored matters far less than what the data represents and how it can be used. + +## Making OpenMetadata easier to explore with PortalJS + +PortalJS helps solve this by turning OpenMetadata into a data portal that is easier to browse and understand. It keeps all the existing metadata, but presents it in a simpler way, so people can focus on datasets and their contents instead of technical details. + +A ready-to-use, open-source template powered by Next.js and Tailwind CSS is available to get started quickly: + +👉 https://github.com/datopian/portaljs-frontend-starter-omd + +<img style={{"marginBottom": 0}} src="/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/from.png" /> +<div style={{textAlign: "center"}}> +*OpenMetadata explore page, where users navigate metadata through infrastructure concepts* +</div> + +<img style={{"marginBottom": 0}} src="/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/to.png" /> +<div style={{textAlign: "center"}}> +*PortalJS dataset search page, focused on helping users quickly find datasets* +</div> + +## Why discovery is hard for non-technical users + +In OpenMetadata, navigation mirrors how data is stored: + +- database services +- databases +- schemas +- tables and assets + +This structure makes sense from an engineering point of view, but it forces users to understand internal architecture before they can answer a simpler question: *what data exists that is relevant to me?* + +Most data consumers think in terms of datasets, domains, topics, and documentation. When finding data requires understanding storage layers, many users struggle to get value from the catalog. + +This is not a limitation of OpenMetadata’s metadata model. It is a mismatch between a governance-focused interface and a discovery-focused use case. + +## Access and sharing add another layer of friction + +OpenMetadata is designed as an authenticated system. Requiring users to sign in is often the right choice for governance workflows, but it limits how metadata can be shared. + +This makes it harder to: +- Share data with external collaborators +- Build lightweight data portals +- Expose selected metadata to broader audiences + +OpenMetadata is not intended to be a flexible, audience-facing data portal, which is why many teams look for an additional interface focused on exploration and reading. + +## PortalJS as a data portal for OpenMetadata + +PortalJS provides that interface. + +It is an open-source framework for building data portals on top of systems like OpenMetadata. OpenMetadata continues to manage metadata, ownership, and lineage, while PortalJS focuses on helping people find and understand data more easily. + +This separation allows teams to keep the full power of OpenMetadata, while offering a much simpler experience to data consumers. + +![PortalJS Search Page](/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-search-page.png) + +## A simpler mental model for data discovery + +The PortalJS OpenMetadata template reshapes how metadata is presented, using concepts that are easier for most users to understand: + +- **Data Product → Dataset** +- **Domain → Organization** +- **Asset → Resource** + +Nothing is removed or simplified in the metadata itself. The difference is how that information is organized and displayed, making it easier to browse, search, and explore. + +## What the template provides out of the box + +The open-source PortalJS OpenMetadata template includes: + +- A dataset search page +- Domain (organization) browsing +- A glossary page +- A dataset details page where users can understand the dataset metadata and browse available resources +- Resource detail pages + +All pages are designed for read-only, exploration-first use. Metadata is fetched directly from OpenMetadata, with no duplication or manual syncing. + +![PortalJS Dataset Details Page](/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-dataset-details-page.png) + +## Open source, flexible by design + +The template is built with **Next.js** and **Tailwind CSS**, making it easy to customize, extend, and brand. + +Because it is fully open source, teams retain control over: +- The codebase +- How and where it is deployed +- Who can access which data + +PortalJS can be adapted to different audiences and access requirements. + +## Not just for open data + +While PortalJS can power open data portals, the template is not limited to public use cases. + +It can be customized to: +- Add authentication +- Restrict access to specific datasets or domains +- Expose data conditionally based on users, roles, or custom properties + +This makes it suitable for internal catalogs, research portals, partner-facing experiences, and fully public portals alike. + +## From governance to exploration + +OpenMetadata is built for managing metadata. PortalJS is built for helping people explore and understand data. + +Together, they allow organizations to turn existing metadata into a user-friendly data portal that serves more people, without replacing governance tooling. + +**We’ve used this approach and the PortalJS OpenMetadata template with many different clients, across a range of data platforms and use cases. In practice, it has proven to be a flexible and reliable way to make OpenMetadata easier to explore, without changing how metadata is managed underneath.** + +For a concrete example of how this approach has worked in practice, check out our case study: + +👉 [Helping Researchers Find The Right Data Faster — With A Simple Frontend For OpenMetadata](https://www.datopian.com/showcase/case-studies/simple-frontend-for-openmetadata-with-portaljs). + +If you are already using OpenMetadata and want to improve data discovery, the open-source PortalJS OpenMetadata template is a practical place to start. + +👉 https://github.com/datopian/portaljs-frontend-starter-omd + + + OpenMetadata is excellent for governance and power users, but difficult for broader audiences. Learn how PortalJS turns OpenMetadata into a user-friendly data portal focused on discovery and navigation. + + + Supercharging Data Portals with the PortalJS MCP Server + https://portaljs.com/blog/supercharging-data-portals-with-the-portaljs-mcp-server + + 2025-11-25T00:00:00.000Z + 2025-11-25T00:00:00.000Z + + anuveyatsu + + +Back in September this year, we published [our first look at using MCP (Model Context Protocol) servers](/blog/mcp-server-ai-assistants-to-improve-data-portals) to give AI assistants structured access to data portals. + +Now the implementation is live and fully open source. + +PortalJS MCP runs in production on Cloudflare’s MCP SDK, which gives us a fast, global, edge-native runtime. It comes with low latency, high reliability, and no “AI integration infra tax” for you to pay. + +The PortalJS MCP server is publicly available at: + +``` +mcp.portaljs.com +``` + +If your data portal runs on PortalJS Cloud, connecting it is dead simple. Your MCP endpoint is: + +``` +mcp.portaljs.com/@org-name/sse +``` + +Paste that into ChatGPT, Claude, or any MCP-capable client, and your AI assistant immediately gains structured access to your datasets, metadata, and previews. + +And because we think this should be a standard building block for modern data portals, we’ve open sourced the whole implementation here: + +https://github.com/datopian/portaljs-mcp-server + +Use it, fork it, deploy your own version, or just read through it to understand how MCP can sit cleanly on top of a data portal. + +[![Architecture diagram](https://mermaid.ink/img/pako:eNpNjl9PgzAUxb9Kc580YYQxKLQxJhs8GU0WF19c91Dt3VgClJTWqITvbhm6eJ_un_M75w7wrhUCh5ORXUUen0VLfK33Lz2aA1ks7slmL6CopCXrruvJDZ4CUtTSKbwVcJjlm4uw2D8VW7JD8-HR-dC7t9l4q42V9cPOo9qp-ThV8a8ld5NL6eNKaeUvcs3AVkHg3zwr4NY4DKBB08hphGGSCLAVNiiA-1bhUbraChDt6LFOtq9aN3-k0e5UAT_KuveT65S0WJ6lf7W5bo0PRFNo11rgaXbxAD7AJ3DGQrqiGY3yPMnSnAXwBXxJozBKknQV53FMo4iNAXxfMqOQspwtaZzSJM4ymrDxBwREbd4?type=png)](https://mermaid.live/edit#pako:eNpNjl9PgzAUxb9Kc580YYQxKLQxJhs8GU0WF19c91Dt3VgClJTWqITvbhm6eJ_un_M75w7wrhUCh5ORXUUen0VLfK33Lz2aA1ks7slmL6CopCXrruvJDZ4CUtTSKbwVcJjlm4uw2D8VW7JD8-HR-dC7t9l4q42V9cPOo9qp-ThV8a8ld5NL6eNKaeUvcs3AVkHg3zwr4NY4DKBB08hphGGSCLAVNiiA-1bhUbraChDt6LFOtq9aN3-k0e5UAT_KuveT65S0WJ6lf7W5bo0PRFNo11rgaXbxAD7AJ3DGQrqiGY3yPMnSnAXwBXxJozBKknQV53FMo4iNAXxfMqOQspwtaZzSJM4ymrDxBwREbd4) +_Figure 1: Architecture diagram._ + +## Why MCP Is a Game-Changer for Data Portals + +AI chats are powerful, but without structured access they’re basically guessing. MCP fixes that by giving models secure, predictable tools to interact with real systems — including your data portal. + +In practice, this unlocks: + +* **Reliable dataset discovery** backed by actual portal data search +* **Accurate metadata exploration** without hallucination risk +* **On-demand previews** (rows, schema, field types) +* **One clean integration** that works across multiple AI clients + +This effectively turns your AI assistant into a precision data navigator — not just a polite autocomplete engine. + +## What’s Available in the MCP Today + +The initial toolset focuses on high-value workflows for discovery and exploration: + +### Search tool enables data discovery + +* List datasets +* Keyword search +* Metadata filtering +* Dataset summaries + +### Get tool for metadata exploration + +* Resource lists +* Field definitions +* Schema inspection +* Full metadata extraction + +### Table preview + +* First N rows +* Column summaries +* Type inference +* Lightweight profiling + +These tools are designed to be **fast, bounded, and safe**. The model doesn’t pull full datasets — it gets structured previews that are ideal for reasoning and analysis. + +## Works with ChatGPT, Claude, VS Code, and More + +Our MCP server is model-agnostic by default: + +* Claude — native MCP support +* ChatGPT Desktop — native MCP support +* VS Code MCP clients — plug-and-play +* Future MCP-enabled tools — automatically compatible + +Wherever your team uses AI, your portal can now show up *as a first-class, tool-based data source*. + +## Why Cloudflare’s MCP SDK? + +We chose Cloudflare’s SDK because MCP should feel like infrastructure you **never have to think about**. + +Using Cloudflare gives us: + +* **Edge deployment by default** → fast globally, no region bottlenecks +* **Battle-tested SSE support** → stable streaming tool calls +* **Simple scaling model** → no infra babysitting as usage grows + +This matters because AI tooling isn’t forgiving. If your MCP endpoint is slow or flaky, your user’s trust evaporates instantly. Cloudflare’s runtime lets us keep it sharp. + +## What’s Coming Next + +This is only the first layer. We’re already expanding the MCP toolbox, including: + +* Write-back tools (tags, notes, curation workflows) +* Automated metadata enrichment +* Data quality checks +* Permission-aware exploration +* Semantic search +* Lineage and observability integration + +The direction is clear: your data portal becomes an intelligent interface, not a static catalog. + +## Try It Today + +If your portal runs on PortalJS Cloud, your MCP endpoint is: + +``` +https://mcp.portaljs.com/@org-name/sse +``` + +Plug it into your AI assistant and start exploring your data conversationally — with real structure, real metadata, and real previews. + +Want help rolling this out to your team or customers? Reach out. We’re building this to make data portals genuinely useful in an AI-first world. + + Explore how the PortalJS MCP server unlocks AI-native discovery, metadata exploration, and data previews for modern portals — now open sourced and easy to integrate. + + + Introducing Visualizations in PortalJS Cloud: Publish and Share Insights Alongside Your Datasets + https://portaljs.com/blog/introducing-visualizations-in-portaljs-cloud + + 2025-10-13T00:00:00.000Z + 2025-10-13T00:00:00.000Z + + João Demenech + + +## Introduction + +PortalJS Cloud now treats visualizations as first-class citizens in your data portal — discoverable and searchable, just like your datasets. + +This feature allows users to publish external dashboards, reports, and data stories alongside their datasets, regardless of which tool they use — from Power BI to Tableau or custom-built data apps. + +## Why Visualizations Matter + +Data portals are great for publishing and discovering datasets, but raw data rarely tells the full story. + +Visualizations bridge that gap by helping users: + +- Quickly grasp insights and trends +- Lower the barrier for non-technical audiences +- Combine narrative and analysis into data-driven storytelling +- Share interactive dashboards directly with stakeholders + +![Data to Insight](/static/img/blog/introducing-visualizations-in-portaljs-cloud/spreadsheet-to-viz.png) + +## Tool-Agnostic by Design + +A core design goal for this feature was flexibility. + +PortalJS doesn’t restrict you to one visualization framework. Instead, you can publish and catalog visualizations created with any external tool, such as: + +- Power BI +- Observable +- Superset +- Tableau +- Custom-built dashboards or apps + +When you publish a visualization in PortalJS Cloud, it becomes: + +- A dedicated entry in your PortalJS instance (with metadata, tags, and ownership) +- Linked to the relevant groups and organizations +- Browsable and searchable, just like datasets + +This means your portal can now serve as both a catalog of datasets and a catalog of insights built on top of them. + +## Optional Add-On: Managed Data App Powered By Observable Framework + +For users who prefer a code-driven workflow, PortalJS offers an optional Observable Framework Data App Add-on integration. + +![Code to Insight](/static/img/blog/introducing-visualizations-in-portaljs-cloud/code-to-viz.png) + +[Observable Framework](https://observablehq.com/framework/) is an open-source JavaScript framework for building interactive data applications, dashboards, and reports. It was created by the team behind ObservableHQ, with the goal of making it easier for developers and analysts to turn data into live, shareable, and interactive visualizations using standard web technologies. + +Data apps powered by the Observable Framework are static sites that can be built, deployed, and hosted anywhere — including platforms like Vercel. This makes them fast, portable, and easy to integrate into modern web stacks such as PortalJS. + +The data app addon works similarly to the main data portal: once enabled on PortalJS Cloud, a dedicated GitHub repository and deployment will be created for your data app. + +<iframe src="https://drive.google.com/file/d/1Y6g89nMq3YjVGLXkaUP5VFQDxls6TZe-/preview" width="569" height="308" allow="autoplay; fullscreen"></iframe> + +The GitHub repository is created based on the [PortalJS Data App Starter template](https://github.com/datopian/portaljs-data-app-starter). You can then clone it locally for development and raise PRs to deploy changes to your data app, such as the creation of new dashboards or branding. + +## Publishing Visualizations + +Once your dashboards and reports are deployed to the data app (or any other tool), you can then publish them in PortalJS Cloud by creating corresponding visualizations. + +<iframe src="https://drive.google.com/file/d/170GaJd8WK6_wEna2gR-dbgR-Z0krTVSt/preview" width="569" height="308" allow="autoplay; fullscreen"></iframe> + +## Browsable and Searchable Like Datasets + +Finally, users will be able to explore the visualizations published to your portal and access the dashboards and reports created on the data app. + +Just like with datasets, users can search visualizations by organization, groups, and tags. + +<iframe src="https://drive.google.com/file/d/1zYJaz2HOCinVRFokrxooAWqQbvOpoPJ-/preview" width="569" height="308" allow="autoplay; fullscreen"></iframe> + +On the visualization details page, the full metadata for the visualization can be found, along with a link to access it. + +## What’s Next + +This release is just the beginning of a series of improvements focused on data visualizations. + +In the next iterations, we aim to make creating and publishing visualizations as intuitive as exploring them, introducing simple, guided tools that allow non-technical users to build and customize visualizations directly within PortalJS Cloud, without needing to write code or manage external apps. + +With these enhancements, we aim to make PortalJS Cloud not just a catalog of datasets and dashboards, but a platform where any user — technical or not — can explore, create, and share meaningful insights. + + + Empower your data portal with an insights catalog — a new way to explore, share, and communicate findings alongside your datasets. + + + MCP Server: A better way to connect AI assistants to data portals + https://portaljs.com/blog/mcp-server-ai-assistants-to-improve-data-portals + + 2025-09-17T00:00:00.000Z + 2025-09-17T00:00:00.000Z + + Theo Bertol + + +## Introduction + +The world of AI assistants is rapidly evolving, but there's been a persistent challenge: how do we connect these powerful tools to the vast repositories of data that organizations maintain? Enter the **Model Context Protocol (MCP)** - Anthropic's groundbreaking open standard that's revolutionizing how AI systems interact with data sources. + +## What is the Model Context Protocol? + +![MCP to LLM Connection](/static/img/blog/mcp-server-ai-assistants-to-improve-data-portals/mcp-llm.png) + +Before diving into our MCP Data Portal implementation, let's understand what makes MCP so revolutionary. Announced by Anthropic in November 2024, the Model Context Protocol is quickly becoming the universal standard for connecting AI assistants to data systems. + +### The Problem MCP Solves + +Traditional AI assistants are often overwhelmed by unnecessary, copy-pasted context (JSON, CSV, etc.). We end up pasting a lot of information before having a good conversation or solving the problem, burning a lot of tokens, and still not solving the problem because the signal is buried in noise. + +- How can I make this conversation more straight to the point? +- Why does my AI chat keep storing useless information? +- When did I ask for this? +- Where is this chat's context going? + +All of these questions point to the core issue: managing context. How do we fix it? + +### The MCP Solution + +MCP replaces these fragmented integrations with a single, open protocol. Think of it as the "USB standard" for AI-data connections - any MCP-compliant data source can serve context to any MCP-enabled AI client, and vice versa. + +Think of it as simple: instead of copy/pasting, contextualizing, and rephrasing, an MCP server provides direct, permissioned access to the right sources (APIs, databases, datasets, connectors). + +With an MCP server, the assistant knows which tools to call to answer your question. No more pasting 10,000-line CSVs. + +### Why Connect Data Portals to AI Assistants? + +Imagine being able to: + +- **Ask natural language questions** about datasets: "Show me environmental datasets from 2020" +- **Get instant summaries** of complex data without browsing through catalogs +- **Discover relationships** between datasets across different organizations +- **Access metadata** and resources through conversational interfaces +- **Integrate data discovery** into your existing AI workflows + +This is exactly what the MCP Server enables for data portals. + +## How It Works: + +The MCP Server acts as a bridge between MCP-compatible AI clients and data portal APIs. Here's the flow: + +1. **AI Assistant** sends a request through MCP protocol +2. **MCP Server** translates the request to data portal API calls +3. **Data Portal** returns data and metadata +4. **Server processes and formats** the response for the AI +5. **AI Assistant** receives structured data to provide intelligent responses + +### Government Open Data +Government agencies can enable citizens and researchers to interact with public datasets using natural language. Instead of navigating complex data portals, users can simply ask: "What environmental data is available for my city?" + +### Research Institutions +Researchers can quickly discover relevant datasets across multiple repositories, understand data provenance, and identify potential collaborations through AI-powered data exploration. + +### Enterprise Data Discovery +Organizations can connect their internal data portals to AI assistants, enabling employees to find and understand corporate data assets without specialized knowledge of data catalogs. + +### Data Journalism +Journalists can rapidly identify story-relevant datasets, understand their context, and explore connections between different data sources through conversational interfaces. + +## The Future of AI-Powered Data Discovery + +The MCP Server for data portals represents more than just a technical integration - it's a glimpse into the future of how we'll interact with data. As MCP becomes the standard protocol for AI-data connections, we're moving toward a world where: + +- **Data discovery is conversational**, not navigational +- **AI assistants understand context** from your organization's data +- **Complex data relationships** are explained in natural language +- **Data democratization** happens through familiar AI interfaces + +## Conclusion + +The Model Context Protocol is transforming how AI systems access and interact with data. The MCP Server for data portals makes this connection seamless, secure, and scalable. + +By bridging data portals with AI assistants, we're not just enabling new technical capabilities - we're fundamentally changing how people discover, understand, and work with data. The barriers between human curiosity and data insights are dissolving, replaced by natural, conversational interfaces that make data accessible to everyone. + How an MCP server bridges AI assistants and data portals, enabling seamless, efficient data discovery for ChatGPT, Claude, and other AI tools. + + + How We Rebuilt a Legacy CKAN Portal into a Static, Read-Only Site with PortalJS + https://portaljs.com/blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs + + 2025-07-29T00:00:00.000Z + 2025-07-29T00:00:00.000Z + + baglanadaskhan + + +## Background + +[DataHub v1](https://old.datahub.io/) was originally built as a CKAN 2.6-based data portal, hosting thousands of open datasets from organizations across the world. For many years, it served as a reliable place to discover, download, and share data. But like many long-running platforms, it started to show its age. + +Over time, the maintenance burden grew increasingly difficult to justify: + +* CKAN 2.6 was outdated and lacked long-term support +* The portal depended on numerous legacy plugins, some of which were custom and unmaintained +* Upgrades became risky and time-consuming +* Day-to-day stability relied on manual patching and workarounds + +At the same time, the **value of the data remained high** — historical records, research outputs, and public datasets that people still searched for and used. We didn’t want to lose that. But we also didn’t want to keep investing in heavy infrastructure just to preserve read-only access. + +So the idea emerged: **what if we turned the portal into a fully static site — no backend, no databases, just fast, reliable, and simple?** + +## The Goal + +We wanted to preserve: + +* Access to all datasets +* Dataset metadata (title, description, tags, license, resources) +* Basic search and navigation +* A clean and consistent UI + +And we wanted to remove: + +* The need for CKAN backend services (PostgreSQL, Solr, extensions) +* Admin/user accounts and dynamic features +* Any part of the system that required manual ops or upgrades + +Our target was a **read-only static portal**, built on modern tooling and served entirely over CDN. + +## From Legacy to Lightweight + +### Stabilizing the CKAN Instance + +Before migrating, we had to ensure the old CKAN site was stable enough to extract data from. We: + +* Disabled login and registration +* Made the instance read-only +* Removed unused and broken plugins like `disqus`, `datapub`, and `validation` + +This left us with a clean, static snapshot of the portal’s content that could be safely extracted. + +### Extracting Metadata + +We needed a format that was both machine-readable and flexible. We chose the [Frictionless Data Package](https://specs.frictionlessdata.io/data-package/) spec — a widely used standard in the open data world. + +Each dataset was exported as a datapackage.json file. For better structure and clarity, we organized them semantically by publisher: + +```bash +/datasets/ + └── organization-name/ + └── dataset-name/ + ├── datapackage.json + └── organization.json +``` + +This simple hierarchy helped mirror how CKAN groups datasets by organization, and allowed for clear URL routing and static page generation. + +All metadata files and downloadable resources were uploaded to Cloudflare R2 — an S3-compatible object storage with global CDN support. + +### Building the Frontend + +We chose [PortalJS](https://portaljs.com/) — an open-source, React/Next.js-based framework designed for data portals. It allowed us to build: + +* A homepage with basic intro and quick search +* A dataset listing page +* A dataset detail page rendered directly from datapackage.json + +Everything is statically rendered at build time, including SEO metadata, resource tables, and file links. + +We also customized layout components using TailwindCSS and React, giving the new portal a clean and responsive interface. + +### Implementing Search Without a Backend + +CKAN uses Solr for powerful search, but it’s a server-side dependency. We replaced it with [Lunr.js](https://lunrjs.com/), a client-side search engine that indexes documents in the browser. + +We wrote a script that scans all `datapackage.json` files and builds a Lunr index at deploy time. The result is a fast, compact index (\~1MB) bundled with the frontend and loaded entirely in-browser. + +For our use case — static data and a finite number of datasets — Lunr was the perfect fit. + +### CI/CD and Deployment + +We automated everything with GitHub Actions: + +* Build the PortalJS frontend +* Pull latest metadata and generate search index +* Deploy to Vercel + +There’s no server, no database, and nothing to monitor. The site is regenerated automatically when content changes. + +## What We Removed — By Design + +This wasn’t a downgrade — it was a conscious shift toward minimalism. We removed: + +* CKAN’s web UI and admin panel +* Solr search engine +* Login, registration, and permissions + +What remained was what mattered most: **the data itself**, presented clearly and accessibly. + +## Results + +* Over **1,000 datasets** preserved and discoverable +* Site loads in milliseconds — no waiting for backend queries +* Infrastructure costs nearly eliminated +* Maintenance reduced to a few GitHub workflows + +The new [old.datahub.io](https://old.datahub.io/) is not just faster — it's also cleaner, safer, and easier to evolve. + +--- + +Thanks for reading\! Want to explore more? Check out [PortalJS](https://portaljs.com/), or reach out if you’re thinking of giving your legacy data portal a second life — static, searchable, and serverless. + + Migrating from a heavy CKAN 2.6 portal to a fast, fully static frontend — and the technical journey behind it. + The Metadata Standards Landscape: Making Data Discoverable Across Organizations https://portaljs.com/blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations @@ -34,6 +1034,8 @@ This is where metadata standards come in—providing the consistent structure th The metadata standards landscape might seem overwhelming at first, but it's built around a few foundational standards that work together rather than compete. Let's explore the key players and how they complement each other. +![Metadata standards landscape illustration](/static/img/blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations/metadata-standards-landscape-illustration.png) + ### Dublin Core: The Universal Foundation Dublin Core is the veteran of metadata standards with its 15 basic elements that can describe virtually any resource. Published as ISO Standard 15836, it's domain-agnostic and internationally recognized. @@ -2798,8 +3800,8 @@ Check out the source on GitHub: https://github.com/datopian/markdowndb What We Shipped in Jul-Aug 2023 https://portaljs.com/blog/summer-updates-2023 - 2023-09-01T18:00:00.000Z - 2023-09-01T18:00:00.000Z + 2023-09-01T23:00:00.000Z + 2023-09-01T23:00:00.000Z ola-rubaj @@ -4499,7 +5501,7 @@ Check out a list of core datasets that are updated on a regular basis. From fina * [Population growth estimates and projections](/core/population-growth-estimates-and-projections) :clock1: updated annually -There will be more automated datasets on :datahub: so join our [community chat on :discord: Discord](https://discord.gg/krmj5HM6He) and our Newsletter (insert link) to receive the latest news! +There will be more automated datasets on :datahub: so join our [community chat on :discord: Discord](https://discord.gg/KrRzMKU) and our Newsletter (insert link) to receive the latest news! Read more... diff --git a/site/public/images/casestudies/lincolnshire1.png b/site/public/images/casestudies/lincolnshire1.png new file mode 100644 index 000000000..0daea49db Binary files /dev/null and b/site/public/images/casestudies/lincolnshire1.png differ diff --git a/site/public/images/casestudies/lincolnshire2.png b/site/public/images/casestudies/lincolnshire2.png new file mode 100644 index 000000000..92ea2b191 Binary files /dev/null and b/site/public/images/casestudies/lincolnshire2.png differ diff --git a/site/public/images/casestudies/lincolnshire3.png b/site/public/images/casestudies/lincolnshire3.png new file mode 100644 index 000000000..539c44fc8 Binary files /dev/null and b/site/public/images/casestudies/lincolnshire3.png differ diff --git a/site/public/images/casestudies/lincolnshire4.png b/site/public/images/casestudies/lincolnshire4.png new file mode 100644 index 000000000..db75925f7 Binary files /dev/null and b/site/public/images/casestudies/lincolnshire4.png differ diff --git a/site/public/images/casestudies/lincon.svg b/site/public/images/casestudies/lincon.svg new file mode 100644 index 000000000..6d33614e6 --- /dev/null +++ b/site/public/images/casestudies/lincon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/site/public/images/casestudies/linconshire0.jpg b/site/public/images/casestudies/linconshire0.jpg new file mode 100644 index 000000000..ce6b791bb Binary files /dev/null and b/site/public/images/casestudies/linconshire0.jpg differ diff --git a/site/public/rss.xml b/site/public/rss.xml index 815ce37d7..c42d68511 100644 --- a/site/public/rss.xml +++ b/site/public/rss.xml @@ -1,4 +1,932 @@ -<![CDATA[PortalJS Blog]]>https://portaljs.comRSS for NodeThu, 10 Jul 2025 09:00:46 GMTThu, 10 Jul 2025 09:00:46 GMT60<![CDATA[The Metadata Standards Landscape: Making Data Discoverable Across Organizations]]><![CDATA[PortalJS Blog]]>https://portaljs.comRSS for NodeTue, 03 Mar 2026 16:43:47 GMTTue, 03 Mar 2026 16:43:47 GMT60<![CDATA[Keep Your Portal Data Fresh: A Hands-On Guide to the PortalJS Cloud API]]> **Tip:** Bookmark this page—you’ll use it constantly when building and debugging integrations. + +## Authentication and API Keys + +### Public access (no API key) + +Without an API key, anyone can: + +- Read public datasets +- Access public resources and data files + +For example, a simple public read request: + +```python +import requests + +response = requests.get( + "https://api.cloud.portaljs.com/@datopian/api/3/action/package_search" +) + +result = response.json() +print(result) +``` + +### Authenticated access (API key required) + +To create or update data, you’ll need an API key. Authenticated actions include: + +- Creating datasets +- Creating resources +- Uploading or replacing data files +- Updating dataset and resource metadata + +#### Generating an API key + +To generate an API key: + +1. Log in to the [**PortalJS Cloud dashboard**](https://cloud.portaljs.com/auth/signin) +2. Navigate to [**your user profile**](https://cloud.portaljs.com/profile/api-keys) +3. Create a new API key + +Treat API keys like passwords and store them securely. + +![Interactive API docs](/static/img/blog/2026-01-22-keep-your-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api/api-token.png) + +### Using the API key in requests + +Include the API key in the `Authorization` header. + +#### Common Python setup + +We’ll use Python 3.10+ and the `requests` package. Set your portal slug and API key once and reuse them everywhere. + +```python +import requests + +PORTAL = "datopian" +API_KEY = "your-api-key" +API_BASE = f"https://api.cloud.portaljs.com/@{PORTAL}/api/3/action" + +headers = { + "Content-Type": "application/json", + "Authorization": API_KEY, +} +``` + +## Creating a Dataset via the API + +In PortalJS, a **dataset** is the top-level container for related data and resources. + +To create one programmatically, use the `package_create` endpoint. + +```python +response = requests.post( + f"{API_BASE}/package_create", + headers=headers, + json={ + "name": "automated-dataset", + "title": "Automated Dataset", + "notes": "This dataset is created and updated via the PortalJS Cloud API", + "owner_org": PORTAL, + }, +) + +result = response.json() +print(result) + +dataset_id = result["result"]["id"] +``` + +> The `owner_org` field should be set to the organization that owns the dataset. +> You can find the organization identifier in the PortalJS Cloud dashboard. + +--- + +## Creating a Resource for the Dataset + +A **resource** represents a specific data file (CSV, JSON, etc.) attached to a dataset. + +Create a resource using `resource_create`: + +```python +response = requests.post( + f"{API_BASE}/resource_create", + headers=headers, + json={ + "package_id": "automated-dataset", + "name": "latest-data", + "description": "Latest version of the dataset", + "format": "CSV", + }, +) + +result = response.json() +print(result) + +resource_id = result["result"]["id"] +``` + +Resources are typically created once and updated repeatedly. + +## Uploading Data Using Pre-Signed URLs + +PortalJS Cloud uses **pre-signed URLs** for uploads. This allows large files to be uploaded directly to storage without passing through the API server. + +The upload flow is: + +1. Request an upload URL +2. Upload the file using `PUT` +3. Finalize the upload so the resource metadata is updated + +### Step 1: Request an upload URL + +```python +upload_response = requests.post( + f"{API_BASE}/resource_upload", + headers=headers, + json={ + "id": resource_id, + "filename": "data.csv", + }, +) + +upload_result = upload_response.json() +upload_url = upload_result["result"]["presigned_url"] +print(upload_url) +``` + +### Step 2: Upload the file + +Create a minimal CSV file locally first, for example `data.csv`: + +```csv +id,name +1,Example row +``` + +Then upload the file: + +```python +with open("./data.csv", "rb") as file_handle: + requests.put(upload_url, data=file_handle) +``` + +### Step 3: Finalize the upload + +```python +requests.post( + f"{API_BASE}/resource_upload_finalize", + headers=headers, + json={ + "id": resource_id, + }, +) +``` + +At this point, the resource is updated and consumers will see the new data. + +## Updating Resource Data Automatically + +This same upload flow can be reused every time your data changes: +- Daily refreshes +- Weekly exports +- Data generated from upstream systems + +You do **not** need to create a new resource each time. Updating the existing resource ensures: +- Stable URLs +- Consistent metadata +- A clean dataset structure + +## Putting It All Together: End-to-End Automation + +A typical automation flow looks like this: + +**One-time** +- Create dataset +- Create resource + +**On every run** +- Generate or fetch new data +- Request upload URL +- Upload file +- Finalize the upload + +## Common Dataset and Resource Operations + +Here are a few additional calls you’ll use often once your pipeline is in place. + +### Search datasets + +```python +search_response = requests.get( + f"{API_BASE}/package_search", + params={"q": "climate", "rows": 5}, +) + +search_result = search_response.json() +print(search_result) +``` + +### Patch a dataset + +```python +dataset_patch_response = requests.post( + f"{API_BASE}/package_patch", + headers=headers, + json={ + "id": dataset_id, + "notes": "Updated description from automation.", + }, +) + +dataset_patch_result = dataset_patch_response.json() +print(dataset_patch_result) +``` + +### Delete a dataset + +```python +dataset_delete_response = requests.post( + f"{API_BASE}/package_delete", + headers=headers, + json={"id": dataset_id}, +) + +dataset_delete_result = dataset_delete_response.json() +print(dataset_delete_result) +``` + +### Patch a resource + +```python +resource_patch_response = requests.post( + f"{API_BASE}/resource_patch", + headers=headers, + json={ + "id": resource_id, + "description": "Updated resource description.", + }, +) + +resource_patch_result = resource_patch_response.json() +print(resource_patch_result) +``` + +### Delete a resource + +```python +resource_delete_response = requests.post( + f"{API_BASE}/resource_delete", + headers=headers, + json={"id": resource_id}, +) + +resource_delete_result = resource_delete_response.json() +print(resource_delete_result) +``` + +## Full End-to-End Script + +If you want a single copy-paste file with all the steps (create dataset, create resource, upload, finalize), use this: + +```python +import requests + +PORTAL = "datopian" +API_KEY = "your-api-key" +API_BASE = f"https://api.cloud.portaljs.com/@{PORTAL}/api/3/action" + +headers = { + "Content-Type": "application/json", + "Authorization": API_KEY, +} + +dataset_response = requests.post( + f"{API_BASE}/package_create", + headers=headers, + json={ + "name": "automated-dataset", + "title": "Automated Dataset", + "notes": "This dataset is created and updated via the PortalJS Cloud API", + "owner_org": PORTAL, + }, +) + +dataset_result = dataset_response.json() +dataset_id = dataset_result["result"]["id"] + +resource_response = requests.post( + f"{API_BASE}/resource_create", + headers=headers, + json={ + "package_id": dataset_id, + "name": "latest-data", + "description": "Latest version of the dataset", + "format": "CSV", + }, +) + +resource_result = resource_response.json() +resource_id = resource_result["result"]["id"] + +filename = "data.csv" +with open(filename, "w", encoding="utf-8") as file_handle: + file_handle.write("id,name\n1,Example row\n") + +upload_response = requests.post( + f"{API_BASE}/resource_upload", + headers=headers, + json={ + "id": resource_id, + "filename": filename, + }, +) + +upload_result = upload_response.json() +upload_url = upload_result["result"]["presigned_url"] + +with open(filename, "rb") as file_handle: + requests.put(upload_url, data=file_handle) + +requests.post( + f"{API_BASE}/resource_upload_finalize", + headers=headers, + json={ + "id": resource_id, + }, +) +``` + +## Conclusion and Next Steps + +Using the PortalJS Cloud API, you can move from manual uploads to a fully automated, reliable data publishing workflow. + +You’ve seen how to: + +- Discover your portal’s API +- Authenticate with API keys +- Create datasets and resources +- Upload and update data programmatically +- Search, update, and delete datasets and resources + +Explore your portal’s API documentation to go further and tailor automation to your data workflows. +]]>https://portaljs.com/blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-apihttps://portaljs.com/blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-apiThu, 22 Jan 2026 00:00:00 GMT<![CDATA[Turning OpenMetadata into a User-Friendly Data Portal with PortalJS]]> +
+*OpenMetadata explore page, where users navigate metadata through infrastructure concepts* +
+ + +
+*PortalJS dataset search page, focused on helping users quickly find datasets* +
+ +## Why discovery is hard for non-technical users + +In OpenMetadata, navigation mirrors how data is stored: + +- database services +- databases +- schemas +- tables and assets + +This structure makes sense from an engineering point of view, but it forces users to understand internal architecture before they can answer a simpler question: *what data exists that is relevant to me?* + +Most data consumers think in terms of datasets, domains, topics, and documentation. When finding data requires understanding storage layers, many users struggle to get value from the catalog. + +This is not a limitation of OpenMetadata’s metadata model. It is a mismatch between a governance-focused interface and a discovery-focused use case. + +## Access and sharing add another layer of friction + +OpenMetadata is designed as an authenticated system. Requiring users to sign in is often the right choice for governance workflows, but it limits how metadata can be shared. + +This makes it harder to: +- Share data with external collaborators +- Build lightweight data portals +- Expose selected metadata to broader audiences + +OpenMetadata is not intended to be a flexible, audience-facing data portal, which is why many teams look for an additional interface focused on exploration and reading. + +## PortalJS as a data portal for OpenMetadata + +PortalJS provides that interface. + +It is an open-source framework for building data portals on top of systems like OpenMetadata. OpenMetadata continues to manage metadata, ownership, and lineage, while PortalJS focuses on helping people find and understand data more easily. + +This separation allows teams to keep the full power of OpenMetadata, while offering a much simpler experience to data consumers. + +![PortalJS Search Page](/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-search-page.png) + +## A simpler mental model for data discovery + +The PortalJS OpenMetadata template reshapes how metadata is presented, using concepts that are easier for most users to understand: + +- **Data Product → Dataset** +- **Domain → Organization** +- **Asset → Resource** + +Nothing is removed or simplified in the metadata itself. The difference is how that information is organized and displayed, making it easier to browse, search, and explore. + +## What the template provides out of the box + +The open-source PortalJS OpenMetadata template includes: + +- A dataset search page +- Domain (organization) browsing +- A glossary page +- A dataset details page where users can understand the dataset metadata and browse available resources +- Resource detail pages + +All pages are designed for read-only, exploration-first use. Metadata is fetched directly from OpenMetadata, with no duplication or manual syncing. + +![PortalJS Dataset Details Page](/static/img/blog/2026-01-09-turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs/portaljs-dataset-details-page.png) + +## Open source, flexible by design + +The template is built with **Next.js** and **Tailwind CSS**, making it easy to customize, extend, and brand. + +Because it is fully open source, teams retain control over: +- The codebase +- How and where it is deployed +- Who can access which data + +PortalJS can be adapted to different audiences and access requirements. + +## Not just for open data + +While PortalJS can power open data portals, the template is not limited to public use cases. + +It can be customized to: +- Add authentication +- Restrict access to specific datasets or domains +- Expose data conditionally based on users, roles, or custom properties + +This makes it suitable for internal catalogs, research portals, partner-facing experiences, and fully public portals alike. + +## From governance to exploration + +OpenMetadata is built for managing metadata. PortalJS is built for helping people explore and understand data. + +Together, they allow organizations to turn existing metadata into a user-friendly data portal that serves more people, without replacing governance tooling. + +**We’ve used this approach and the PortalJS OpenMetadata template with many different clients, across a range of data platforms and use cases. In practice, it has proven to be a flexible and reliable way to make OpenMetadata easier to explore, without changing how metadata is managed underneath.** + +For a concrete example of how this approach has worked in practice, check out our case study: + +👉 [Helping Researchers Find The Right Data Faster — With A Simple Frontend For OpenMetadata](https://www.datopian.com/showcase/case-studies/simple-frontend-for-openmetadata-with-portaljs). + +If you are already using OpenMetadata and want to improve data discovery, the open-source PortalJS OpenMetadata template is a practical place to start. + +👉 https://github.com/datopian/portaljs-frontend-starter-omd + +]]>
https://portaljs.com/blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljshttps://portaljs.com/blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljsFri, 09 Jan 2026 00:00:00 GMT
<![CDATA[Supercharging Data Portals with the PortalJS MCP Server]]>https://portaljs.com/blog/supercharging-data-portals-with-the-portaljs-mcp-serverhttps://portaljs.com/blog/supercharging-data-portals-with-the-portaljs-mcp-serverTue, 25 Nov 2025 00:00:00 GMT<![CDATA[Introducing Visualizations in PortalJS Cloud: Publish and Share Insights Alongside Your Datasets]]> + +The GitHub repository is created based on the [PortalJS Data App Starter template](https://github.com/datopian/portaljs-data-app-starter). You can then clone it locally for development and raise PRs to deploy changes to your data app, such as the creation of new dashboards or branding. + +## Publishing Visualizations + +Once your dashboards and reports are deployed to the data app (or any other tool), you can then publish them in PortalJS Cloud by creating corresponding visualizations. + + + +## Browsable and Searchable Like Datasets + +Finally, users will be able to explore the visualizations published to your portal and access the dashboards and reports created on the data app. + +Just like with datasets, users can search visualizations by organization, groups, and tags. + + + +On the visualization details page, the full metadata for the visualization can be found, along with a link to access it. + +## What’s Next + +This release is just the beginning of a series of improvements focused on data visualizations. + +In the next iterations, we aim to make creating and publishing visualizations as intuitive as exploring them, introducing simple, guided tools that allow non-technical users to build and customize visualizations directly within PortalJS Cloud, without needing to write code or manage external apps. + +With these enhancements, we aim to make PortalJS Cloud not just a catalog of datasets and dashboards, but a platform where any user — technical or not — can explore, create, and share meaningful insights. + +]]>https://portaljs.com/blog/introducing-visualizations-in-portaljs-cloudhttps://portaljs.com/blog/introducing-visualizations-in-portaljs-cloudMon, 13 Oct 2025 00:00:00 GMT<![CDATA[MCP Server: A better way to connect AI assistants to data portals]]>https://portaljs.com/blog/mcp-server-ai-assistants-to-improve-data-portalshttps://portaljs.com/blog/mcp-server-ai-assistants-to-improve-data-portalsWed, 17 Sep 2025 00:00:00 GMT<![CDATA[How We Rebuilt a Legacy CKAN Portal into a Static, Read-Only Site with PortalJS]]>https://portaljs.com/blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljshttps://portaljs.com/blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljsTue, 29 Jul 2025 00:00:00 GMT<![CDATA[The Metadata Standards Landscape: Making Data Discoverable Across Organizations]]>https://portaljs.com/blog/summer-updates-2023https://portaljs.com/blog/summer-updates-2023Fri, 01 Sep 2023 18:00:00 GMT<![CDATA[Adding Maps to PortalJS: Enhancing Geospatial Data Visualization with PortalJS]]>https://portaljs.com/blog/summer-updates-2023https://portaljs.com/blog/summer-updates-2023Fri, 01 Sep 2023 23:00:00 GMT<![CDATA[Adding Maps to PortalJS: Enhancing Geospatial Data Visualization with PortalJS]]>https://portaljs.com/blog/automatically-updated-core-datasets-on-datahubhttps://portaljs.com/blog/automatically-updated-core-datasets-on-datahubWed, 05 Sep 2018 00:00:00 GMT<![CDATA[Sports data on DataHub]]> -https://portaljs.com2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/case-studies2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/ckan2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/compare2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/compare/arcgis-hub2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/compare/ckan2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/compare/custom-solution2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/compare/dataverse2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/compare/dkan2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/compare/opendatasoft2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/compare/socrata2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/data-portals2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/faq2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/features2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/git2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/learn2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/learn/metadata2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/openmetadata2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/partners2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/pricing2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/welcome2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/effortless-user-management-portaljs2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/example-ckan-20212025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/javascript-sdk-for-data-deployment2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/vega-upgrade-spec-v32025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/enhancing-geospatial-data-visualization-with-portaljs2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/docs/showing-metadata2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/howtos/seo2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/automated-kpis-collection-and-visualization-of-the-funnels2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/why-portaljs-is-the-future-of-decoupled-frontend-for-data-portals2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/create-a-simple-catalog-of-anything-using-markdown2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/docs/setup2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/sports-data-on-datahub2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/improved-reporting-and-debugging-of-data-publishing2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/how-to-use-data-packages-from-r2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/howtos/markdown2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/the-open-spending-revamp-behind-the-scenes2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/case-studies/a-global-transport-hub-building-a-shared-open-data-infrastructure-for-30-plus-transport-organizations2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/case-studies/eiti-fully-customizable-data-portal-in-minutes2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/open-data-day-covid-192025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/world-bank-indicators-on-datahub2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/howtos/analytics2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/docs2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/comparotron-a-simple-way-to-visualize-and-share-comparisons2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/why-we-decoupled-CKAN-frontend2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/see-events-and-activity-related-to-datasets-or-publishers2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/developers/automating-ckan-resource-cloudflare-r2-workers2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/howtos/sitemap2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/howtos/comments2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/developers/comprehensive-guide-building-robust-data-portal-ckan2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/docs/searching-datasets2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/automatically-updated-core-datasets-on-datahub2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/summer-updates-20232025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/pharmaceutical-drug-spending2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/datasets-in-zip-format2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/case-studies/simplifying-healthcare-metadata2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/create-a-website-from-scratch2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/developers/create-data-catalog-portaljs-ckan2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/basics-of-metadata-how-it-helps-to-understand-your-data2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/making-portalJS-cloud-admin-panel-accessible2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/how-to-initialize-a-data-package-using-data-tool2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/developers/enabling-direct-file-uploads-api-ckan-cloudflare2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/introducing-private-datasets-on-the-datahub2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/markdowndb-basics-tutorial-20232025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/machine-learning-datasets2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/new-machine-learning-datasets2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/how-to-use-multiple-datahub-accounts2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/attribute-relation-file-format-arff2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/previews-for-large-datasets2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/edit-a-website-locally2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/q1-2018-review2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/the-new-look-of-portaljs-cloud2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/ckan-resource-uploads-via-api2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/new-features-and-improvements2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/covid19-and-compartmental-models-in-epidemiology2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/docs/deploying-your-portaljs-app2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/data-desktop-app-alpha-release2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/guide2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/developers/create-github-backed-data-catalog-portaljs2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/excel-files-on-the-datahub-automated-previews-and-data-extraction2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/frictionless-specs-european-commission2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/case-studies/london-borough-of-hounslow2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/auto-publish-your-datasets-using-travis-ci2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/howtos/blog2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/generate-an-interactive-webpage-from-csv-data-and-markdown2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/markdowndb-launch2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/howtos/data-rich-documents2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/case-studies/uae-moei-scalable-platform-government-data-publishing2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/opensource/docs/creating-new-datasets2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/data-validation-in-the-datahub2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/online-validation-tool2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/import-online-data-files-directly-with-scheduling2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/how-to-reduce-data-portal-costs-by-90-percent2025-07-10T07:07:22.562Zdaily0.7 -https://portaljs.com/blog/upgrade-to-data-package-specs-v12025-07-10T07:07:22.562Zdaily0.7 +https://portaljs.com2026-03-03T16:43:47.337Zdaily0.7 +https://portaljs.com/blog2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/case-studies2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/ckan2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/compare2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/compare/arcgis-hub2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/compare/ckan2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/compare/custom-solution2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/compare/dataverse2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/compare/dkan2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/compare/opendatasoft2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/compare/socrata2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/data-portals2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/datahub2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/faq2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/features2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/git2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/learn2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/learn/metadata2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/openmetadata2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/partners2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/pricing2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/purview2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/solutions/open-data2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/welcome2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/effortless-user-management-portaljs2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/example-ckan-20212026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/javascript-sdk-for-data-deployment2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/vega-upgrade-spec-v32026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/enhancing-geospatial-data-visualization-with-portaljs2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/docs/showing-metadata2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/howtos/seo2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/why-NASA-and-anyone-using-CKAN-should-consider-a-decoupled-front-end-with-PortalJS2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/automated-kpis-collection-and-visualization-of-the-funnels2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/keep-your-portal-data-fresh-a-hands-on-guide-to-the-portaljs-cloud-api2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/why-portaljs-is-the-future-of-decoupled-frontend-for-data-portals2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/case-studies/modernizing-lincolnshire-county-council39s-open-data-portal2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/supercharging-data-portals-with-the-portaljs-mcp-server2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/mcp-server-ai-assistants-to-improve-data-portals2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/the-metadata-standards-landscape-making-data-discoverable-across-organizations2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/create-a-simple-catalog-of-anything-using-markdown2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/docs/setup2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/turning-openmetadata-into-a-user-friendly-data-portal-with-portaljs2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/sports-data-on-datahub2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/improved-reporting-and-debugging-of-data-publishing2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/how-to-use-data-packages-from-r2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/howtos/markdown2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/the-open-spending-revamp-behind-the-scenes2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/case-studies/a-global-transport-hub-building-a-shared-open-data-infrastructure-for-30-plus-transport-organizations2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/case-studies/eiti-fully-customizable-data-portal-in-minutes2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/open-data-day-covid-192026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/world-bank-indicators-on-datahub2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/howtos/analytics2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/docs2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/comparotron-a-simple-way-to-visualize-and-share-comparisons2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/why-we-decoupled-CKAN-frontend2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/see-events-and-activity-related-to-datasets-or-publishers2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/developers/automating-ckan-resource-cloudflare-r2-workers2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/howtos/sitemap2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/howtos/comments2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/revamped-awesome-collections-data-sets-that-are-grouped-by-subject2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/developers/comprehensive-guide-building-robust-data-portal-ckan2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/how-we-rebuilt-a-legacy-ckan-portal-into-a-static-read-only-site-with-portaljs2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/docs/searching-datasets2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/automatically-updated-core-datasets-on-datahub2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/summer-updates-20232026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/pharmaceutical-drug-spending2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/datasets-in-zip-format2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/case-studies/simplifying-healthcare-metadata2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/create-a-website-from-scratch2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/developers/create-data-catalog-portaljs-ckan2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/basics-of-metadata-how-it-helps-to-understand-your-data2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/making-portalJS-cloud-admin-panel-accessible2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/how-to-initialize-a-data-package-using-data-tool2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/developers/enabling-direct-file-uploads-api-ckan-cloudflare2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/introducing-private-datasets-on-the-datahub2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/markdowndb-basics-tutorial-20232026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/machine-learning-datasets2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/new-machine-learning-datasets2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/how-to-use-multiple-datahub-accounts2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/attribute-relation-file-format-arff2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/previews-for-large-datasets2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/edit-a-website-locally2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/q1-2018-review2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/the-new-look-of-portaljs-cloud2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/ckan-resource-uploads-via-api2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/new-features-and-improvements2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/covid19-and-compartmental-models-in-epidemiology2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/docs/deploying-your-portaljs-app2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/data-desktop-app-alpha-release2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/guide2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/developers/create-github-backed-data-catalog-portaljs2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/excel-files-on-the-datahub-automated-previews-and-data-extraction2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/frictionless-specs-european-commission2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/case-studies/london-borough-of-hounslow2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/auto-publish-your-datasets-using-travis-ci2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/howtos/blog2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/introducing-visualizations-in-portaljs-cloud2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/generate-an-interactive-webpage-from-csv-data-and-markdown2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/how-rich-metadata-powers-data-discovery-in-modern-data-catalogs2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/markdowndb-launch2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/howtos/data-rich-documents2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/core-data-essential-datasets-for-data-wranglers-and-data-scientists2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/case-studies/uae-moei-scalable-platform-government-data-publishing2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/opensource/docs/creating-new-datasets2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/data-validation-in-the-datahub2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/online-validation-tool2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/import-online-data-files-directly-with-scheduling2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/how-to-reduce-data-portal-costs-by-90-percent2026-03-03T16:43:47.338Zdaily0.7 +https://portaljs.com/blog/upgrade-to-data-package-specs-v12026-03-03T16:43:47.338Zdaily0.7 \ No newline at end of file